Compare commits

..

13 Commits

Author SHA1 Message Date
28198e9b9e Next stable release 2017-03-12 14:23:42 +02:00
dev
3953df845c impoved the request linking options, fixed few bugs in compiler (#52) 2017-03-08 06:49:54 +02:00
30e37dcfde Improved category integration, adapted the fields generator to allow one field to be used multiple times in the same view 2017-03-06 14:08:12 +02:00
bc9e5495d7 fixed #43 to insure fields are sorted in the correct order. Added the noticeboard to the compiler page, to insure all our notices gets viewed by all those who use the JCB 2017-03-03 23:53:18 +02:00
4d47f8292f added another fields to admin view to target list controller and model. Also improve compiler to add these new custom script to correct areas 2017-03-02 02:55:04 +02:00
a1ff74f157 Resolves #43 to insure that fields are sorted by tab once save, thanks to @Peeripapo 2017-02-24 16:57:40 +02:00
dc1217e6d1 Resolved #42 to insure the strpos always returns the correct data type. Improvements to some of the UI surrounding the custom code area. Added an edit button for the component being compiled on the complier page. 2017-02-23 02:29:37 +02:00
f2e4df6ecb Improved the custom code by adding the feature that shows where the manual custom code is used, including better placeholder information. Added component information to the compiler view. 2017-02-17 20:35:18 +02:00
a197f503a9 changed component table name to joomla-component to add history/version tracking back to components 2017-02-16 16:02:23 +02:00
79ab3164a6 few changes in comments, descriptions and fields. Included JS files to custom code engine 2017-02-14 02:33:24 +02:00
290a51dd5a Further improved #37 to ensure language strings are set and reversed, also add extra buttons to the compiler page. Major restructure of custom code implementation to make it more stable. Resolved #40 by updating the default field sql values. 2017-02-14 01:24:38 +02:00
de008d5907 Stable release of the automatic import of custom code, and the JCB manual placeholder implementation resolves #37 please view https://youtu.be/KiAtJawZ3oo 2017-02-11 04:24:26 +02:00
5b5599575b Fixes #39 to ensure components are build even if created and modified dates are not set. Improved #37 #issuecomment-278372267 to avoid one line error in windows. 2017-02-09 18:11:10 +02:00
414 changed files with 29350 additions and 22464 deletions

View File

@ -1,4 +1,4 @@
# Component Builder (2.3.0)
# Component Builder (2.3.7)
This is a [Joomla 3.x](http://www.joomla.org/) component.
@ -8,7 +8,7 @@ The Component Builder for [Joomla](http://www.joomla.org/) that is highly advanc
Whether you're a seasoned [Joomla](http://www.joomla.org/) developer, or have just started, Component Builder will safe you lots of time and money. A real must have!
You can install it quite easily and with no limitations. On [github](https://github.com/vdm-io/Joomla-Component-Builder/releases) is the latest release (2.3.0) with **ALL** its features and **ALL** concepts totally open-source and free!
You can install it quite easily and with no limitations. On [github](https://github.com/vdm-io/Joomla-Component-Builder/releases) is the latest release (2.3.7) with **ALL** its features and **ALL** concepts totally open-source and free!
Once installed upgrades are quick and easy via the default Joomla upgrade area.
@ -104,12 +104,12 @@ Component Builder is mapped as a component in itself on my local development env
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Component Builder](http://vdm.bz/component-builder)
+ *First Build*: 30th April, 2015
+ *Last Build*: 4th February, 2017
+ *Version*: 2.3.0
+ *Last Build*: 12th March, 2017
+ *Version*: 2.3.7
+ *Copyright*: Copyright (C) 2015. All Rights Reserved
+ *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
+ *Line count*: **91058**
+ *File count*: **589**
+ *Line count*: **92889**
+ *File count*: **602**
+ *Folder count*: **105**
> This **component** was build with a Joomla [Automated Component Builder](http://vdm.bz/component-builder).

View File

@ -1,4 +1,4 @@
# Component Builder (2.3.0)
# Component Builder (2.3.7)
This is a [Joomla 3.x](http://www.joomla.org/) component.
@ -8,7 +8,7 @@ The Component Builder for [Joomla](http://www.joomla.org/) that is highly advanc
Whether you're a seasoned [Joomla](http://www.joomla.org/) developer, or have just started, Component Builder will safe you lots of time and money. A real must have!
You can install it quite easily and with no limitations. On [github](https://github.com/vdm-io/Joomla-Component-Builder/releases) is the latest release (2.3.0) with **ALL** its features and **ALL** concepts totally open-source and free!
You can install it quite easily and with no limitations. On [github](https://github.com/vdm-io/Joomla-Component-Builder/releases) is the latest release (2.3.7) with **ALL** its features and **ALL** concepts totally open-source and free!
Once installed upgrades are quick and easy via the default Joomla upgrade area.
@ -104,12 +104,12 @@ Component Builder is mapped as a component in itself on my local development env
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Component Builder](http://vdm.bz/component-builder)
+ *First Build*: 30th April, 2015
+ *Last Build*: 4th February, 2017
+ *Version*: 2.3.0
+ *Last Build*: 12th March, 2017
+ *Version*: 2.3.7
+ *Copyright*: Copyright (C) 2015. All Rights Reserved
+ *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
+ *Line count*: **91058**
+ *File count*: **589**
+ *Line count*: **92889**
+ *File count*: **602**
+ *Folder count*: **105**
> This **component** was build with a Joomla [Automated Component Builder](http://vdm.bz/component-builder).

View File

@ -101,6 +101,16 @@
<action name="help_document.export" title="COM_COMPONENTBUILDER_HELP_DOCUMENTS_EXPORT" description="COM_COMPONENTBUILDER_HELP_DOCUMENTS_EXPORT_DESC" />
<action name="help_document.import" title="COM_COMPONENTBUILDER_HELP_DOCUMENTS_IMPORT" description="COM_COMPONENTBUILDER_HELP_DOCUMENTS_IMPORT_DESC" />
<action name="help_document.submenu" title="COM_COMPONENTBUILDER_HELP_DOCUMENTS_SUBMENU" description="COM_COMPONENTBUILDER_HELP_DOCUMENTS_SUBMENU_DESC" />
<action name="joomla_component.access" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_ACCESS" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_ACCESS_DESC" />
<action name="joomla_component.batch" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_USE" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_USE_DESC" />
<action name="joomla_component.dashboard_add" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_DASHBOARD_ADD" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_DASHBOARD_ADD_DESC" />
<action name="joomla_component.dashboard_list" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_DASHBOARD_LIST" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_DASHBOARD_LIST_DESC" />
<action name="joomla_component.edit.add_license" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_ADD_LICENSE" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_ADD_LICENSE_DESC" />
<action name="joomla_component.edit.license_type" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_LICENSE_TYPE" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_LICENSE_TYPE_DESC" />
<action name="joomla_component.version" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION_DESC" />
<action name="joomla_component.export" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EXPORT" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EXPORT_DESC" />
<action name="joomla_component.import" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_IMPORT" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_IMPORT_DESC" />
<action name="joomla_component.submenu" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_SUBMENU" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_SUBMENU_DESC" />
<action name="layout.access" title="COM_COMPONENTBUILDER_LAYOUTS_ACCESS" description="COM_COMPONENTBUILDER_LAYOUTS_ACCESS_DESC" />
<action name="layout.batch" title="COM_COMPONENTBUILDER_LAYOUTS_BATCH_USE" description="COM_COMPONENTBUILDER_LAYOUTS_BATCH_USE_DESC" />
<action name="layout.dashboard_add" title="COM_COMPONENTBUILDER_LAYOUTS_DASHBOARD_ADD" description="COM_COMPONENTBUILDER_LAYOUTS_DASHBOARD_ADD_DESC" />
@ -134,6 +144,11 @@
<action name="template.import" title="COM_COMPONENTBUILDER_TEMPLATES_IMPORT" description="COM_COMPONENTBUILDER_TEMPLATES_IMPORT_DESC" />
<action name="template.submenu" title="COM_COMPONENTBUILDER_TEMPLATES_SUBMENU" description="COM_COMPONENTBUILDER_TEMPLATES_SUBMENU_DESC" />
</section>
<section name="joomla_component">
<action name="joomla_component.edit.add_license" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_ADD_LICENSE" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_ADD_LICENSE_DESC" />
<action name="joomla_component.edit.license_type" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_LICENSE_TYPE" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_LICENSE_TYPE_DESC" />
<action name="joomla_component.version" title="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION_DESC" />
</section>
<section name="admin_view">
<action name="core.edit" title="COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT" description="COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_DESC" />
<action name="core.edit.state" title="COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_STATE" description="COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_STATE_DESC" />

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage admin.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 95 of this MVC
@build 3rd February, 2017
@version @update number 104 of this MVC
@build 6th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage admin_view.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 95 of this MVC
@build 3rd February, 2017
@version @update number 104 of this MVC
@build 6th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage admin_views.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 11 of this MVC
@build 2nd February, 2017
@version @update number 46 of this MVC
@build 3rd March, 2017
@created 1st February, 2017
@package Component Builder
@subpackage compiler.css

View File

@ -10,7 +10,7 @@
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 22 of this MVC
@build 3rd February, 2017
@build 1st March, 2017
@created 13th August, 2015
@package Component Builder
@subpackage custom_admin_view.css

View File

@ -10,7 +10,7 @@
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 22 of this MVC
@build 3rd February, 2017
@build 1st March, 2017
@created 13th August, 2015
@package Component Builder
@subpackage custom_admin_views.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 14 of this MVC
@build 31st January, 2017
@version @update number 81 of this MVC
@build 1st March, 2017
@created 11th October, 2016
@package Component Builder
@subpackage custom_code.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 14 of this MVC
@build 31st January, 2017
@version @update number 81 of this MVC
@build 1st March, 2017
@created 11th October, 2016
@package Component Builder
@subpackage custom_codes.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage dashboard.css

View File

@ -9,11 +9,11 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 81 of this MVC
@build 3rd February, 2017
@version @update number 97 of this MVC
@build 3rd March, 2017
@created 6th May, 2015
@package Component Builder
@subpackage component.css
@subpackage joomla_component.css
@author Llewellyn van der Merwe <http://vdm.bz/component-builder>
@copyright Copyright (C) 2015. All Rights Reserved
@license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html

View File

@ -9,11 +9,11 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 81 of this MVC
@build 3rd February, 2017
@version @update number 97 of this MVC
@build 3rd March, 2017
@created 6th May, 2015
@package Component Builder
@subpackage components.css
@subpackage joomla_components.css
@author Llewellyn van der Merwe <http://vdm.bz/component-builder>
@copyright Copyright (C) 2015. All Rights Reserved
@license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 66 of this MVC
@build 3rd February, 2017
@version @update number 67 of this MVC
@build 22nd February, 2017
@created 18th May, 2015
@package Component Builder
@subpackage layout.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 66 of this MVC
@build 3rd February, 2017
@version @update number 67 of this MVC
@build 22nd February, 2017
@created 18th May, 2015
@package Component Builder
@subpackage layouts.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 48 of this MVC
@build 3rd February, 2017
@version @update number 51 of this MVC
@build 6th March, 2017
@created 29th May, 2015
@package Component Builder
@subpackage site_view.css

View File

@ -9,8 +9,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 48 of this MVC
@build 3rd February, 2017
@version @update number 51 of this MVC
@build 6th March, 2017
@created 29th May, 2015
@package Component Builder
@subpackage site_views.css

View File

@ -10,7 +10,7 @@
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 40 of this MVC
@build 3rd February, 2017
@build 22nd February, 2017
@created 26th May, 2015
@package Component Builder
@subpackage template.css

View File

@ -10,7 +10,7 @@
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 40 of this MVC
@build 3rd February, 2017
@build 22nd February, 2017
@created 26th May, 2015
@package Component Builder
@subpackage templates.css

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -146,13 +146,18 @@ abstract class ###Component###Helper
if (self::checkArray($where))
{
// prep main <-- why? well if $main='' is empty then $table can be categories or users
if (self::checkString($main))
{
$main = '_'.ltrim($main, '_');
}
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
$query->select($db->quoteName(array($what)));
$query->from($db->quoteName('#__'.$main.'_'.$table));
$query->from($db->quoteName('#_'.$main.'_'.$table));
$query->where($db->quoteName($whereString) . ' '.$operator.' (' . implode(',',$where) . ')');
$db->setQuery($query);
$db->execute();
@ -681,57 +686,86 @@ abstract class ###Component###Helper
return $string;
}
public static function safeString($string, $type = 'L', $spacer = '_')
public static function safeString($string, $type = 'L', $spacer = '_', $replaceNumbers = true)
{
// remove all numbers and replace with english text version (works well only up to a thousand)
$string = self::replaceNumbers($string);
if ($replaceNumbers === true)
{
// remove all numbers and replace with english text version (works well only up to millions)
$string = self::replaceNumbers($string);
}
// 0nly continue if we have a string
if (self::checkString($string))
{
// remove all other characters
$string = trim($string);
$string = preg_replace('/'.$spacer.'+/', ' ', $string);
$string = preg_replace('/\s+/', ' ', $string);
$string = preg_replace("/[^A-Za-z ]/", '', $string);
// return a string with all first letter of each word uppercase(no undersocre)
if ($type == 'W')
{
return ucwords(strtolower($string));
}
elseif ($type == 'w')
{
return strtolower($string);
}
elseif ($type == 'Ww')
{
return ucfirst(strtolower($string));
}
elseif ($type == 'WW')
{
return strtoupper($string);
}
elseif ($type == 'U')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return all upper
return strtoupper($string);
}
elseif ($type == 'F')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return with first caracter to upper
return ucfirst(strtolower($string));
}
elseif ($type == 'L')
// create file name without the extention that is safe
if ($type === 'filename')
{
// make sure VDM is not in the string
$string = str_replace('VDM', 'vDm', $string);
// Remove anything which isn't a word, whitespace, number
// or any of the following caracters -_()
// If you don't need to handle multi-byte characters
// you can use preg_replace rather than mb_ereg_replace
// Thanks @Łukasz Rysiak!
$string = mb_ereg_replace("([^\w\s\d\-_\(\)])", '', $string);
// http://stackoverflow.com/a/2021729/1429677
return preg_replace('/\s+/', ' ', $string);
}
// remove all other characters
$string = trim($string);
$string = preg_replace('/'.$spacer.'+/', ' ', $string);
$string = preg_replace('/\s+/', ' ', $string);
$string = preg_replace("/[^A-Za-z ]/", '', $string);
// select final adaptations
if ($type === 'L' || $type === 'strtolower')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// default is to return lower
return strtolower($string);
}
elseif ($type === 'W')
{
// return a string with all first letter of each word uppercase(no undersocre)
return ucwords(strtolower($string));
}
elseif ($type === 'w' || $type === 'word')
{
// return a string with all lowercase(no undersocre)
return strtolower($string);
}
elseif ($type === 'Ww' || $type === 'Word')
{
// return a string with first letter of the first word uppercase and all the rest lowercase(no undersocre)
return ucfirst(strtolower($string));
}
elseif ($type === 'WW' || $type === 'WORD')
{
// return a string with all the uppercase(no undersocre)
return strtoupper($string);
}
elseif ($type === 'U' || $type === 'strtoupper')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return all upper
return strtoupper($string);
}
elseif ($type === 'F' || $type === 'ucfirst')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return with first caracter to upper
return ucfirst(strtolower($string));
}
elseif ($type === 'cA' || $type === 'cAmel' || $type === 'camelcase')
{
// convert all words to first letter uppercase
$string = ucwords(strtolower($string));
// remove white space
$string = preg_replace('/\s+/', '', $string);
// now return first letter lowercase
return lcfirst($string);
}
// return string
return $string;
}

View File

@ -0,0 +1,35 @@
<?php
/*--------------------------------------------------------------------------------------------------------| www.vdm.io |------/
__ __ _ _____ _ _ __ __ _ _ _
\ \ / / | | | __ \ | | | | | \/ | | | | | | |
\ \ / /_ _ ___| |_ | | | | _____ _____| | ___ _ __ _ __ ___ ___ _ __ | |_ | \ / | ___| |_| |__ ___ __| |
\ \/ / _` / __| __| | | | |/ _ \ \ / / _ \ |/ _ \| '_ \| '_ ` _ \ / _ \ '_ \| __| | |\/| |/ _ \ __| '_ \ / _ \ / _` |
\ / (_| \__ \ |_ | |__| | __/\ V / __/ | (_) | |_) | | | | | | __/ | | | |_ | | | | __/ |_| | | | (_) | (_| |
\/ \__,_|___/\__| |_____/ \___| \_/ \___|_|\___/| .__/|_| |_| |_|\___|_| |_|\__| |_| |_|\___|\__|_| |_|\___/ \__,_|
| |
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@package Component Builder
@subpackage componentbuilder.php
@author Llewellyn van der Merwe <https://www.vdm.io/joomla-component-builder>
@my wife Roline van der Merwe <http://www.vdm.io/>
@copyright Copyright (C) 2015. All Rights Reserved
@license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
Builds Complex Joomla Components
/-----------------------------------------------------------------------------------------------------------------------------*/
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
?>
###BOM###
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/**
* ###Component### Component Category Tree
*/
###CATEGORY_CLASS_TREES###

View File

@ -0,0 +1,50 @@
<?php
/*--------------------------------------------------------------------------------------------------------| www.vdm.io |------/
__ __ _ _____ _ _ __ __ _ _ _
\ \ / / | | | __ \ | | | | | \/ | | | | | | |
\ \ / /_ _ ___| |_ | | | | _____ _____| | ___ _ __ _ __ ___ ___ _ __ | |_ | \ / | ___| |_| |__ ___ __| |
\ \/ / _` / __| __| | | | |/ _ \ \ / / _ \ |/ _ \| '_ \| '_ ` _ \ / _ \ '_ \| __| | |\/| |/ _ \ __| '_ \ / _ \ / _` |
\ / (_| \__ \ |_ | |__| | __/\ V / __/ | (_) | |_) | | | | | | __/ | | | |_ | | | | __/ |_| | | | (_) | (_| |
\/ \__,_|___/\__| |_____/ \___| \_/ \___|_|\___/| .__/|_| |_| |_|\___|_| |_|\__| |_| |_|\___|\__|_| |_|\___/ \__,_|
| |
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@package Component Builder
@subpackage componentbuilder.php
@author Llewellyn van der Merwe <https://www.vdm.io/joomla-component-builder>
@my wife Roline van der Merwe <http://www.vdm.io/>
@copyright Copyright (C) 2015. All Rights Reserved
@license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
Builds Complex Joomla Components
/-----------------------------------------------------------------------------------------------------------------------------*/
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
?>
###BOM###
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/**
* ###Component### ###View### Component Category Tree
*/
class ###Component######Views###Categories extends JCategories
{
/**
* Class constructor
*
* @param array $options Array of options
*
*/
public function __construct($options = array())
{
$options['table'] = '#__###component###_###view###';
$options['extension'] = 'com_###component###.###views###';
parent::__construct($options);
}
}

View File

@ -320,13 +320,18 @@ abstract class ###Component###Helper
if (self::checkArray($where))
{
// prep main <-- why? well if $main='' is empty then $table can be categories or users
if (self::checkString($main))
{
$main = '_'.ltrim($main, '_');
}
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
$query->select($db->quoteName(array($what)));
$query->from($db->quoteName('#__'.$main.'_'.$table));
$query->from($db->quoteName('#_'.$main.'_'.$table));
$query->where($db->quoteName($whereString) . ' '.$operator.' (' . implode(',',$where) . ')');
$db->setQuery($query);
$db->execute();
@ -673,62 +678,91 @@ abstract class ###Component###Helper
return $string;
}
public static function safeString($string, $type = 'L', $spacer = '_')
public static function safeString($string, $type = 'L', $spacer = '_', $replaceNumbers = true)
{
// remove all numbers and replace with english text version (works well only up to a thousand)
$string = self::replaceNumbers($string);
if (self::checkString($string))
if ($replaceNumbers === true)
{
// remove all numbers and replace with english text version (works well only up to millions)
$string = self::replaceNumbers($string);
}
// 0nly continue if we have a string
if (self::checkString($string))
{
// create file name without the extention that is safe
if ($type === 'filename')
{
// make sure VDM is not in the string
$string = str_replace('VDM', 'vDm', $string);
// Remove anything which isn't a word, whitespace, number
// or any of the following caracters -_()
// If you don't need to handle multi-byte characters
// you can use preg_replace rather than mb_ereg_replace
// Thanks @Łukasz Rysiak!
$string = mb_ereg_replace("([^\w\s\d\-_\(\)])", '', $string);
// http://stackoverflow.com/a/2021729/1429677
return preg_replace('/\s+/', ' ', $string);
}
// remove all other characters
$string = trim($string);
$string = preg_replace('/'.$spacer.'+/', ' ', $string);
$string = preg_replace('/\s+/', ' ', $string);
$string = preg_replace("/[^A-Za-z ]/", '', $string);
// return a string with all first letter of each word uppercase(no undersocre)
if ($type == 'W')
{
return ucwords(strtolower($string));
}
elseif ($type == 'w')
{
return strtolower($string);
}
elseif ($type == 'Ww')
{
return ucfirst(strtolower($string));
}
elseif ($type == 'WW')
{
return strtoupper($string);
}
elseif ($type == 'U')
// select final adaptations
if ($type === 'L' || $type === 'strtolower')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// default is to return lower
return strtolower($string);
}
elseif ($type === 'W')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return all upper
return strtoupper($string);
// return a string with all first letter of each word uppercase(no undersocre)
return ucwords(strtolower($string));
}
elseif ($type == 'F')
elseif ($type === 'w' || $type === 'word')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return with first caracter to upper
// return a string with all lowercase(no undersocre)
return strtolower($string);
}
elseif ($type === 'Ww' || $type === 'Word')
{
// return a string with first letter of the first word uppercase and all the rest lowercase(no undersocre)
return ucfirst(strtolower($string));
}
elseif ($type == 'L')
elseif ($type === 'WW' || $type === 'WORD')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// default is to return lower
return strtolower($string);
// return a string with all the uppercase(no undersocre)
return strtoupper($string);
}
// return string
return $string;
}
// not a string
return '';
elseif ($type === 'U' || $type === 'strtoupper')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return all upper
return strtoupper($string);
}
elseif ($type === 'F' || $type === 'ucfirst')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return with first caracter to upper
return ucfirst(strtolower($string));
}
elseif ($type === 'cA' || $type === 'cAmel' || $type === 'camelcase')
{
// convert all words to first letter uppercase
$string = ucwords(strtolower($string));
// remove white space
$string = preg_replace('/\s+/', '', $string);
// now return first letter lowercase
return lcfirst($string);
}
// return string
return $string;
}
// not a string
return '';
}
public static function htmlEscape($var, $charset = 'UTF-8', $sorten = false, $length = 40)

View File

@ -47,5 +47,5 @@ class ###Component###Controller###Views### extends JControllerAdmin
$model = parent::getModel($name, $prefix, array('ignore_request' => true));
return $model;
}###CONTROLLEREXIMPORTMETHOD### ###CUSTOM_ADMIN_DYNAMIC_BUTTONS_CONTROLLER###
}###CONTROLLEREXIMPORTMETHOD### ###CUSTOM_ADMIN_DYNAMIC_BUTTONS_CONTROLLER### ###ADMIN_CUSTOM_BUTTONS_CONTROLLER_LIST###
}

View File

@ -67,7 +67,7 @@ class ###Component###Model###View### extends JModelAdmin
public function getTable($type = '###view###', $prefix = '###Component###Table', $config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
}###ADMIN_CUSTOM_BUTTONS_METHOD###
/**
* Method to get a single record.
@ -248,6 +248,45 @@ class ###Component###Model###View### extends JModelAdmin
return $data;
}###VALIDATIONFIX### ###UNIQUEFIELDS###
/**
* Method to delete one or more records.
*
* @param array &$pks An array of record primary keys.
*
* @return boolean True if successful, false if an error occurs.
*
* @since 12.2
*/
public function delete(&$pks)
{###JMODELADMIN_BEFORE_DELETE###
if (!parent::delete($pks))
{
return false;
}###JMODELADMIN_AFTER_DELETE###
return true;
}
/**
* Method to change the published state of one or more records.
*
* @param array &$pks A list of the primary keys to change.
* @param integer $value The value of the published state.
*
* @return boolean True on success.
*
* @since 12.2
*/
public function publish(&$pks, $value = 1)
{###JMODELADMIN_BEFORE_PUBLISH###
if (!parent::publish($pks, $value))
{
return false;
}###JMODELADMIN_AFTER_PUBLISH###
return true;
}
/**
* Method to perform batch operations on an item or a set of items.

View File

@ -47,7 +47,7 @@ class ###Component###Model###Views### extends JModelList
}
parent::__construct($config);
}
}###ADMIN_CUSTOM_BUTTONS_METHOD_LIST###
/**
* Method to auto-populate the model state.

View File

@ -52,7 +52,8 @@ class ###Component###ViewImport extends JViewLegacy
}
// Check for errors.
if (count($errors = $this->get('Errors'))){
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}

View File

@ -132,7 +132,7 @@ class ###Component###View###Views### extends JViewLegacy
// add the button to the page
$dhtml = $layout->render(array('title' => $title));
$bar->appendButton('Custom', $dhtml, 'batch');
}###CUSTOM_ADMIN_DYNAMIC_BUTTONS###
}###CUSTOM_ADMIN_DYNAMIC_BUTTONS### ###ADMIN_CUSTOM_BUTTONS_LIST###
if ($this->state->get('filter.published') == -2 && ($this->canState && $this->canDelete))
{

View File

@ -1,6 +1,11 @@
###INSTALL###
--
-- Always insure this column is large enough for all the access control values.
-- Always insure this column rules is large enough for all the access control values.
--
ALTER TABLE `#__assets` CHANGE `rules` `rules` MEDIUMTEXT NOT NULL COMMENT 'JSON encoded access control.';
--
-- Always insure this column name is large enough for long component and view names.
--
ALTER TABLE `#__assets` CHANGE `name` `name` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'The unique name for the asset.';

View File

@ -139,11 +139,11 @@ class ###Component###Router extends JComponentRouterBase
return $vars;
}
protected function getVar($table, $where = null, $whereString = 'user', $what = 'id', $category = false, $operator = '=', $main = '###component###')
protected function getVar($table, $where = null, $whereString = null, $what = null, $category = false, $operator = '=', $main = '###component###')
{
if(!$where)
if(!$where || !$what || !$whereString)
{
$where = JFactory::getUser()->id;
return false;
}
// Get a db connection.
$db = JFactory::getDbo();
@ -153,19 +153,42 @@ class ###Component###Router extends JComponentRouterBase
$query->select($db->quoteName(array($what)));
if ('categories' == $table || 'category' == $table || $category)
{
$query->from($db->quoteName('#__categories'));
$getTable = '#__categories';
$query->from($db->quoteName($getTable));
}
else
{
$query->from($db->quoteName('#__'.$main.'_'.$table));
// we must check if the table exist (TODO not ideal)
$tables = $db->getTableList();
$app = JFactory::getApplication();
$prefix = $app->get('dbprefix');
$check = $prefix.$main.'_'.$table;
if (in_array($check, $tables))
{
$getTable = '#__'.$main.'_'.$table;
$query->from($db->quoteName($getTable));
}
else
{
return false;
}
}
if (is_numeric($where))
{
$query->where($db->quoteName($whereString) . ' '.$operator.' '.(int) $where);
return false;
}
elseif (is_string($where))
elseif ($this->checkString($where))
{
$query->where($db->quoteName($whereString) . ' '.$operator.' '. $db->quote((string)$where));
// we must first check if this table has the column
$columns = $db->getTableColumns($getTable);
if (isset($columns[$whereString]))
{
$query->where($db->quoteName($whereString) . ' '.$operator.' '. $db->quote((string)$where));
}
else
{
return false;
}
}
else
{
@ -179,6 +202,15 @@ class ###Component###Router extends JComponentRouterBase
}
return false;
}
protected function checkString($string)
{
if (isset($string) && is_string($string) && strlen($string) > 0)
{
return true;
}
return false;
}
}
function ###Component###BuildRoute(&$query)

View File

@ -157,6 +157,13 @@
"rename": "Helper_site",
"type": "file"
},
"Helper_category.php": {
"naam":"Helper_category.php",
"path": "c0mp0n3nt/site/helpers",
"rename": "new",
"newName": "category.php",
"type": "file"
},
"script.php": {
"naam":"script.php",
"path": "c0mp0n3nt/",
@ -677,6 +684,11 @@
"rename": "new",
"newName": "submitbutton.js",
"type": "custom_form"
},
"Helper_category_view.php": {
"path": "c0mp0n3nt/site/helpers",
"rename": "Helper_category_view",
"type": "category"
}
},
"custom_admin": {

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage componentbuilder.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage controller.php
@ -88,7 +88,7 @@ class ComponentbuilderController extends JControllerLegacy
if (ComponentbuilderHelper::checkString($view))
{
$views = array(
'component' => 'components',
'joomla_component' => 'joomla_components',
'admin_view' => 'admin_views',
'custom_admin_view' => 'custom_admin_views',
'site_view' => 'site_views',

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 95 of this MVC
@build 3rd February, 2017
@version @update number 104 of this MVC
@build 6th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage admin_view.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 95 of this MVC
@build 3rd February, 2017
@version @update number 104 of this MVC
@build 6th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage admin_views.php
@ -107,5 +107,5 @@ class ComponentbuilderControllerAdmin_views extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=admin_views', false), $message, 'error');
return;
}
}
}

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage ajax.json.php
@ -44,6 +44,7 @@ class ComponentbuilderControllerAjax extends JControllerLegacy
// load the tasks
$this->registerTask('isNew', 'ajax');
$this->registerTask('isRead', 'ajax');
$this->registerTask('getComponentDetails', 'ajax');
$this->registerTask('tableColumns', 'ajax');
$this->registerTask('fieldSelectOptions', 'ajax');
$this->registerTask('getImportScripts', 'ajax');
@ -54,6 +55,8 @@ class ComponentbuilderControllerAjax extends JControllerLegacy
$this->registerTask('dynamicFormDetails', 'ajax');
$this->registerTask('dbTableColumns', 'ajax');
$this->registerTask('viewTableColumns', 'ajax');
$this->registerTask('checkFunctionName', 'ajax');
$this->registerTask('usedin', 'ajax');
$this->registerTask('fieldOptions', 'ajax');
}
@ -145,6 +148,44 @@ class ComponentbuilderControllerAjax extends JControllerLegacy
}
}
break;
case 'getComponentDetails':
try
{
$returnRaw = $jinput->get('raw', false, 'BOOLEAN');
$idValue = $jinput->get('id', NULL, 'INT');
if($idValue && $user->id != 0)
{
$result = $this->getModel('ajax')->getComponentDetails($idValue);
}
else
{
$result = false;
}
if($callback = $jinput->get('callback', null, 'CMD'))
{
echo $callback . "(".json_encode($result).");";
}
elseif($returnRaw)
{
echo json_encode($result);
}
else
{
echo "(".json_encode($result).");";
}
}
catch(Exception $e)
{
if($callback = $jinput->get('callback', null, 'CMD'))
{
echo $callback."(".json_encode($e).");";
}
else
{
echo "(".json_encode($e).");";
}
}
break;
case 'tableColumns':
try
{
@ -530,6 +571,85 @@ class ComponentbuilderControllerAjax extends JControllerLegacy
}
}
break;
case 'checkFunctionName':
try
{
$returnRaw = $jinput->get('raw', false, 'BOOLEAN');
$functioNameValue = $jinput->get('functioName', NULL, 'STRING');
$idValue = $jinput->get('id', NULL, 'INT');
if($functioNameValue && $idValue && $user->id != 0)
{
$result = $this->getModel('ajax')->checkFunctionName($functioNameValue, $idValue);
}
else
{
$result = false;
}
if($callback = $jinput->get('callback', null, 'CMD'))
{
echo $callback . "(".json_encode($result).");";
}
elseif($returnRaw)
{
echo json_encode($result);
}
else
{
echo "(".json_encode($result).");";
}
}
catch(Exception $e)
{
if($callback = $jinput->get('callback', null, 'CMD'))
{
echo $callback."(".json_encode($e).");";
}
else
{
echo "(".json_encode($e).");";
}
}
break;
case 'usedin':
try
{
$returnRaw = $jinput->get('raw', false, 'BOOLEAN');
$functioNameValue = $jinput->get('functioName', NULL, 'WORD');
$idValue = $jinput->get('id', NULL, 'INT');
$targetValue = $jinput->get('target', NULL, 'WORD');
if($functioNameValue && $idValue && $targetValue && $user->id != 0)
{
$result = $this->getModel('ajax')->usedin($functioNameValue, $idValue, $targetValue);
}
else
{
$result = false;
}
if($callback = $jinput->get('callback', null, 'CMD'))
{
echo $callback . "(".json_encode($result).");";
}
elseif($returnRaw)
{
echo json_encode($result);
}
else
{
echo "(".json_encode($result).");";
}
}
catch(Exception $e)
{
if($callback = $jinput->get('callback', null, 'CMD'))
{
echo $callback."(".json_encode($e).");";
}
else
{
echo "(".json_encode($e).");";
}
}
break;
case 'fieldOptions':
try
{

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 11 of this MVC
@build 2nd February, 2017
@version @update number 46 of this MVC
@build 3rd March, 2017
@created 1st February, 2017
@package Component Builder
@subpackage compiler.php
@ -66,15 +66,17 @@ class ComponentbuilderControllerCompiler extends JControllerAdmin
if($user->authorise('core.admin', 'com_componentbuilder'))
{
// get the post values
$jinput = JFactory::getApplication()->input;
$componentId = $jinput->post->get('component', 0, 'INT');
$version = $jinput->post->get('version', 0, 'INT');
$addBackup = $jinput->post->get('backup', 0, 'INT');
$addGit = $jinput->post->get('git', 0, 'INT');
$jinput = JFactory::getApplication()->input;
$componentId = $jinput->post->get('component', 0, 'INT');
$version = $jinput->post->get('version', 0, 'INT');
$addBackup = $jinput->post->get('backup', 0, 'INT');
$addGit = $jinput->post->get('git', 0, 'INT');
$addPlaceholders = $jinput->post->get('placeholders', 2, 'INT');
$debugLinenr = $jinput->post->get('debuglinenr', 2, 'INT');
// include component compiler
require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/compiler.php';
$model = $this->getModel('compiler');
if ($model->builder($version,$componentId,$addBackup,$addGit))
if ($model->builder($version,$componentId,$addBackup,$addGit,$addPlaceholders,$debugLinenr))
{
$cache = JFactory::getCache('mod_menu');
$cache->clean();
@ -91,61 +93,37 @@ class ComponentbuilderControllerCompiler extends JControllerAdmin
if (empty($redirect_url) && $componentId > 0)
{
$redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=compiler', false);
// setup the unrealistic numbers
$counter = $model->getCount();
$folders = $counter['folders'] * 5;
$files = $counter['files'] * 5;
$lines = $counter['lines'] * 10;
$seconds = $folders + $files + $lines;
$totalHours = round($seconds / 3600);
$totalDays = round($totalHours / 8);
// setup the more realistic numbers
$debugging = $seconds / 4;
$planning = $seconds / 7;
$mapping = $seconds / 10;
$office = $seconds / 6;
$seconds = $folders + $files + $lines + $debugging + $planning + $mapping + $office;
$actualTotalHours = round($seconds / 3600);
$actualTotalDays = round($actualTotalHours / 8);
$debuggingHours = round($debugging / 3600);
$planningHours = round($planning / 3600);
$mappingHours = round($mapping / 3600);
$officeHours = round($office / 3600);
// the actual time spent
$actualHoursSpent = $actualTotalHours - $totalHours;
$actualDaysSpent = $actualTotalDays - $totalDays;
// calculate the projects actual time frame of completion
$projectWeekTime = round($actualTotalDays / 5,1);
$projectMonthTime = round($actualTotalDays / 24,1);
if (($pos = strpos($counter['filePath'], "/tmp/")) !== FALSE)
if (($pos = strpos($model->compiler->filepath, "/tmp/")) !== FALSE)
{
$url = JURI::root() . substr($counter['filePath'], $pos + 1);
$url = JURI::root() . substr($model->compiler->filepath, $pos + 1);
}
// Message of successful build
$message = '<h1>The ('.$counter['filename'].') Was Successfully Compiled!</h1>';
$message = '<h1>The ('.$model->compiler->componentFolderName.') Was Successfully Compiled!</h1>';
$message .= '<p><button class="btn btn-small btn-success" onclick="Joomla.submitbutton(\'compiler.installExtention\')">';
$message .= 'Install '.$counter['filename'].' on this <span class="icon-joomla icon-white"></span>Joomla website.</button></p>';
$message .= 'Install '.$model->compiler->componentFolderName.' on this <span class="icon-joomla icon-white"></span>Joomla website.</button></p>';
$message .= '<h2>Total time saved</h2>';
$message .= '<ul>';
$message .= '<li>Total folders created: <b>'.$counter['folders'].'</b></li>';
$message .= '<li>Total files created: <b>'.$counter['files'].'</b></li>';
$message .= '<li>Total lines written: <b>'.$counter['lines'].'</b></li>';
$message .= '<li>Total folders created: <b>'.$model->compiler->folderCount.'</b></li>';
$message .= '<li>Total files created: <b>'.$model->compiler->fileCount.'</b></li>';
$message .= '<li>Total lines written: <b>'.$model->compiler->lineCount.'</b></li>';
$message .= '<li>A4 Book of: <b>'.$model->compiler->pageCount.' pages</b></li>';
$message .= '</ul>';
$message .= '<p><b>'.$totalHours.' Hours</b> or <b>'.$totalDays.' Eight Hour Days</b> <em>(actual time you saved)</em><br />';
$message .= '<p><b>'.$model->compiler->totalHours.' Hours</b> or <b>'.$model->compiler->totalDays.' Eight Hour Days</b> <em>(actual time you saved)</em><br />';
$message .= '<small>(if creating a folder and file took <b>5 seconds</b> and writing one line of code took <b>10 seconds</b>, never making one mistake or taking any coffee break.)</small><br />';
$message .= '<b>'.$actualHoursSpent.' Hours</b> or <b>'.$actualDaysSpent.' Eight Hour Days</b> <em>(the actual time you spent)</em><br />';
$message .= '<small>(with the following break down: <b>debugging @'.$debuggingHours.'hours</b> = codingtime / 4; <b>planning @'.$planningHours.'hours</b> = codingtime / 7; <b>mapping @'.$mappingHours.'hours</b> = codingtime / 10; <b>office @'.$officeHours.'hours</b> = codingtime / 6;)</small></p>';
$message .= '<p><b>'.$actualTotalHours.' Hours</b> or <b>'.$actualTotalDays.' Eight Hour Days</b> <em>(a total of the realistic time frame for this project)</em><br />';
$message .= '<b>'.$model->compiler->actualHoursSpent.' Hours</b> or <b>'.$model->compiler->actualDaysSpent.' Eight Hour Days</b> <em>(the actual time you spent)</em><br />';
$message .= '<small>(with the following break down: <b>debugging @'.$model->compiler->debuggingHours.'hours</b> = codingtime / 4; <b>planning @'.$model->compiler->planningHours.'hours</b> = codingtime / 7; <b>mapping @'.$model->compiler->mappingHours.'hours</b> = codingtime / 10; <b>office @'.$model->compiler->officeHours.'hours</b> = codingtime / 6;)</small></p>';
$message .= '<p><b>'.$model->compiler->actualTotalHours.' Hours</b> or <b>'.$model->compiler->actualTotalDays.' Eight Hour Days</b> <em>(a total of the realistic time frame for this project)</em><br />';
$message .= '<small>(if creating a folder and file took <b>5 seconds</b> and writing one line of code took <b>10 seconds</b>, with the normal everyday realities at the office, that includes the component planning, mapping & debugging.)</small></p>';
$message .= '<p>Project duration: <b>'.$projectWeekTime. ' weeks</b> or <b>'.$projectMonthTime.' months</b></p>';
$message .= '<p>Project duration: <b>'.$model->compiler->projectWeekTime. ' weeks</b> or <b>'.$model->compiler->projectMonthTime.' months</b></p>';
$message .= '<h2>Path to Zip File</h2>';
$message .= '<p><b>Path:</b> <code>'.$counter['filePath'].'</code><br />';
$message .= '<p><b>Path:</b> <code>'.$model->compiler->filepath.'</code><br />';
$message .= '<b>URL:</b> <code>'.$url.'</code><br /><br />';
$message .= '<small>Hey! you can also download the file right now!</small><br /><a class="btn btn-success" href="'.$url.'" ><span class="icon-download icon-white"></span>Download</a></p>';
$message .= '<p><small><b>Remember!</b> This file is in your tmp folder and therefore publicly accessible untill you click [Clear tmp]!</small> </p>';
$message .= '<p><small>Compilation took <b>'.$model->compiler->secondsCompiled.'</b> seconds to complete.</small> </p>';
// set redirect
$this->setRedirect($redirect_url,$message,'message');
$app->setUserState('com_componentbuilder.extension_name', $counter['filename']);
$app->setUserState('com_componentbuilder.extension_name', $model->compiler->componentFolderName);
}
else
{

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage componentbuilder.php

View File

@ -11,7 +11,7 @@
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 22 of this MVC
@build 3rd February, 2017
@build 1st March, 2017
@created 13th August, 2015
@package Component Builder
@subpackage custom_admin_view.php

View File

@ -11,7 +11,7 @@
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 22 of this MVC
@build 3rd February, 2017
@build 1st March, 2017
@created 13th August, 2015
@package Component Builder
@subpackage custom_admin_views.php
@ -107,5 +107,5 @@ class ComponentbuilderControllerCustom_admin_views extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=custom_admin_views', false), $message, 'error');
return;
}
}
}

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 14 of this MVC
@build 31st January, 2017
@version @update number 81 of this MVC
@build 1st March, 2017
@created 11th October, 2016
@package Component Builder
@subpackage custom_code.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 14 of this MVC
@build 31st January, 2017
@version @update number 81 of this MVC
@build 1st March, 2017
@created 11th October, 2016
@package Component Builder
@subpackage custom_codes.php
@ -107,5 +107,5 @@ class ComponentbuilderControllerCustom_codes extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=custom_codes', false), $message, 'error');
return;
}
}
}

View File

@ -107,5 +107,5 @@ class ComponentbuilderControllerDynamic_gets extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=dynamic_gets', false), $message, 'error');
return;
}
}
}

View File

@ -60,33 +60,14 @@ class ComponentbuilderControllerField extends JControllerForm
*/
protected function allowAdd($data = array())
{
// get the user object
$user = JFactory::getUser();
// Access check.
$access = $user->authorise('field.access', 'com_componentbuilder');
$access = JFactory::getUser()->authorise('field.access', 'com_componentbuilder');
if (!$access)
{
return false;
}
$categoryId = JArrayHelper::getValue($data, 'catid', $this->input->getInt('filter_category_id'), 'int');
$allow = null;
if ($categoryId)
{
// If the category has been passed in the URL check it.
$allow = $user->authorise('core.create', $this->option . '.fields.category.' . $categoryId);
}
if ($allow === null)
{
// In the absense of better information, revert to the component permissions.
return $user->authorise('field.create', $this->option);
}
else
{
return $allow;
}
// In the absense of better information, revert to the component permissions.
return JFactory::getUser()->authorise('field.create', $this->option);
}
/**
@ -146,18 +127,6 @@ class ComponentbuilderControllerField extends JControllerForm
}
return false;
}
$categoryId = (int) isset($data['catid']) ? $data['catid']: $this->getModel()->getItem($recordId)->catid;
if ($categoryId)
{
// The category has been set. Check the category permissions.
$catpermission = $user->authorise('core.edit', $this->option . '.fields.category.' . $categoryId);
if (!$catpermission && !is_null($catpermission))
{
return false;
}
}
}
// Since there is no permission, revert to the component permissions.
return $user->authorise('field.edit', $this->option);

View File

@ -107,5 +107,5 @@ class ComponentbuilderControllerFields extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=fields', false), $message, 'error');
return;
}
}
}

View File

@ -60,33 +60,14 @@ class ComponentbuilderControllerFieldtype extends JControllerForm
*/
protected function allowAdd($data = array())
{
// get the user object
$user = JFactory::getUser();
// Access check.
$access = $user->authorise('fieldtype.access', 'com_componentbuilder');
$access = JFactory::getUser()->authorise('fieldtype.access', 'com_componentbuilder');
if (!$access)
{
return false;
}
$categoryId = JArrayHelper::getValue($data, 'catid', $this->input->getInt('filter_category_id'), 'int');
$allow = null;
if ($categoryId)
{
// If the category has been passed in the URL check it.
$allow = $user->authorise('core.create', $this->option . '.fieldtypes.category.' . $categoryId);
}
if ($allow === null)
{
// In the absense of better information, revert to the component permissions.
return $user->authorise('fieldtype.create', $this->option);
}
else
{
return $allow;
}
// In the absense of better information, revert to the component permissions.
return JFactory::getUser()->authorise('fieldtype.create', $this->option);
}
/**
@ -146,18 +127,6 @@ class ComponentbuilderControllerFieldtype extends JControllerForm
}
return false;
}
$categoryId = (int) isset($data['catid']) ? $data['catid']: $this->getModel()->getItem($recordId)->catid;
if ($categoryId)
{
// The category has been set. Check the category permissions.
$catpermission = $user->authorise('core.edit', $this->option . '.fieldtypes.category.' . $categoryId);
if (!$catpermission && !is_null($catpermission))
{
return false;
}
}
}
// Since there is no permission, revert to the component permissions.
return $user->authorise('fieldtype.edit', $this->option);

View File

@ -107,5 +107,5 @@ class ComponentbuilderControllerFieldtypes extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=fieldtypes', false), $message, 'error');
return;
}
}
}

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage help.php

View File

@ -107,5 +107,5 @@ class ComponentbuilderControllerHelp_documents extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=help_documents', false), $message, 'error');
return;
}
}
}

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage import.php

View File

@ -10,11 +10,11 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 81 of this MVC
@build 3rd February, 2017
@version @update number 97 of this MVC
@build 3rd March, 2017
@created 6th May, 2015
@package Component Builder
@subpackage component.php
@subpackage joomla_component.php
@author Llewellyn van der Merwe <http://vdm.bz/component-builder>
@copyright Copyright (C) 2015. All Rights Reserved
@license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
@ -30,9 +30,9 @@ defined('_JEXEC') or die('Restricted access');
jimport('joomla.application.component.controllerform');
/**
* Component Controller
* Joomla_component Controller
*/
class ComponentbuilderControllerComponent extends JControllerForm
class ComponentbuilderControllerJoomla_component extends JControllerForm
{
/**
* Current or most recently performed task.
@ -45,7 +45,7 @@ class ComponentbuilderControllerComponent extends JControllerForm
public function __construct($config = array())
{
$this->view_list = 'Components'; // safeguard for setting the return view listing to the main view.
$this->view_list = 'Joomla_components'; // safeguard for setting the return view listing to the main view.
parent::__construct($config);
}
@ -59,7 +59,14 @@ class ComponentbuilderControllerComponent extends JControllerForm
* @since 1.6
*/
protected function allowAdd($data = array())
{ // In the absense of better information, revert to the component permissions.
{
// Access check.
$access = JFactory::getUser()->authorise('joomla_component.access', 'com_componentbuilder');
if (!$access)
{
return false;
}
// In the absense of better information, revert to the component permissions.
return parent::allowAdd($data);
}
@ -84,10 +91,10 @@ class ComponentbuilderControllerComponent extends JControllerForm
if ($recordId)
{
// The record has been set. Check the record permissions.
$permission = $user->authorise('core.edit', 'com_componentbuilder.component.' . (int) $recordId);
$permission = $user->authorise('core.edit', 'com_componentbuilder.joomla_component.' . (int) $recordId);
if (!$permission)
{
if ($user->authorise('core.edit.own', 'com_componentbuilder.component.' . $recordId))
if ($user->authorise('core.edit.own', 'com_componentbuilder.joomla_component.' . $recordId))
{
// Now test the owner is the user.
$ownerId = (int) isset($data['created_by']) ? $data['created_by'] : 0;
@ -182,10 +189,10 @@ class ComponentbuilderControllerComponent extends JControllerForm
JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
// Set the model
$model = $this->getModel('Component', '', array());
$model = $this->getModel('Joomla_component', '', array());
// Preset the redirect
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=components' . $this->getRedirectToListAppend(), false));
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=joomla_components' . $this->getRedirectToListAppend(), false));
return parent::batch($model);
}

View File

@ -10,11 +10,11 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 81 of this MVC
@build 3rd February, 2017
@version @update number 97 of this MVC
@build 3rd March, 2017
@created 6th May, 2015
@package Component Builder
@subpackage components.php
@subpackage joomla_components.php
@author Llewellyn van der Merwe <http://vdm.bz/component-builder>
@copyright Copyright (C) 2015. All Rights Reserved
@license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
@ -30,16 +30,16 @@ defined('_JEXEC') or die('Restricted access');
jimport('joomla.application.component.controlleradmin');
/**
* Components Controller
* Joomla_components Controller
*/
class ComponentbuilderControllerComponents extends JControllerAdmin
class ComponentbuilderControllerJoomla_components extends JControllerAdmin
{
protected $text_prefix = 'COM_COMPONENTBUILDER_COMPONENTS';
protected $text_prefix = 'COM_COMPONENTBUILDER_JOOMLA_COMPONENTS';
/**
* Proxy for getModel.
* @since 2.5
*/
public function getModel($name = 'Component', $prefix = 'ComponentbuilderModel', $config = array())
public function getModel($name = 'Joomla_component', $prefix = 'ComponentbuilderModel', $config = array())
{
$model = parent::getModel($name, $prefix, array('ignore_request' => true));
@ -52,7 +52,7 @@ class ComponentbuilderControllerComponents extends JControllerAdmin
JSession::checkToken() or die(JText::_('JINVALID_TOKEN'));
// check if export is allowed for this user.
$user = JFactory::getUser();
if ($user->authorise('component.export', 'com_componentbuilder') && $user->authorise('core.export', 'com_componentbuilder'))
if ($user->authorise('joomla_component.export', 'com_componentbuilder') && $user->authorise('core.export', 'com_componentbuilder'))
{
// Get the input
$input = JFactory::getApplication()->input;
@ -60,19 +60,19 @@ class ComponentbuilderControllerComponents extends JControllerAdmin
// Sanitize the input
JArrayHelper::toInteger($pks);
// Get the model
$model = $this->getModel('Components');
$model = $this->getModel('Joomla_components');
// get the data to export
$data = $model->getExportData($pks);
if (ComponentbuilderHelper::checkArray($data))
{
// now set the data to the spreadsheet
$date = JFactory::getDate();
ComponentbuilderHelper::xls($data,'Components_'.$date->format('jS_F_Y'),'Components exported ('.$date->format('jS F, Y').')','components');
ComponentbuilderHelper::xls($data,'Joomla_components_'.$date->format('jS_F_Y'),'Joomla components exported ('.$date->format('jS F, Y').')','joomla components');
}
}
// Redirect to the list screen with error.
$message = JText::_('COM_COMPONENTBUILDER_EXPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=components', false), $message, 'error');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=joomla_components', false), $message, 'error');
return;
}
@ -83,10 +83,10 @@ class ComponentbuilderControllerComponents extends JControllerAdmin
JSession::checkToken() or die(JText::_('JINVALID_TOKEN'));
// check if import is allowed for this user.
$user = JFactory::getUser();
if ($user->authorise('component.import', 'com_componentbuilder') && $user->authorise('core.import', 'com_componentbuilder'))
if ($user->authorise('joomla_component.import', 'com_componentbuilder') && $user->authorise('core.import', 'com_componentbuilder'))
{
// Get the import model
$model = $this->getModel('Components');
$model = $this->getModel('Joomla_components');
// get the headers to import
$headers = $model->getExImPortHeaders();
if (ComponentbuilderHelper::checkObject($headers))
@ -94,18 +94,18 @@ class ComponentbuilderControllerComponents extends JControllerAdmin
// Load headers to session.
$session = JFactory::getSession();
$headers = json_encode($headers);
$session->set('component_VDM_IMPORTHEADERS', $headers);
$session->set('backto_VDM_IMPORT', 'components');
$session->set('dataType_VDM_IMPORTINTO', 'component');
$session->set('joomla_component_VDM_IMPORTHEADERS', $headers);
$session->set('backto_VDM_IMPORT', 'joomla_components');
$session->set('dataType_VDM_IMPORTINTO', 'joomla_component');
// Redirect to import view.
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_COMPONENTS');
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_JOOMLA_COMPONENTS');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=import', false), $message);
return;
}
}
// Redirect to the list screen with error.
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=components', false), $message, 'error');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=joomla_components', false), $message, 'error');
return;
}
}
}

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 66 of this MVC
@build 3rd February, 2017
@version @update number 67 of this MVC
@build 22nd February, 2017
@created 18th May, 2015
@package Component Builder
@subpackage layout.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 66 of this MVC
@build 3rd February, 2017
@version @update number 67 of this MVC
@build 22nd February, 2017
@created 18th May, 2015
@package Component Builder
@subpackage layouts.php
@ -107,5 +107,5 @@ class ComponentbuilderControllerLayouts extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=layouts', false), $message, 'error');
return;
}
}
}

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 48 of this MVC
@build 3rd February, 2017
@version @update number 51 of this MVC
@build 6th March, 2017
@created 29th May, 2015
@package Component Builder
@subpackage site_view.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 48 of this MVC
@build 3rd February, 2017
@version @update number 51 of this MVC
@build 6th March, 2017
@created 29th May, 2015
@package Component Builder
@subpackage site_views.php
@ -107,5 +107,5 @@ class ComponentbuilderControllerSite_views extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=site_views', false), $message, 'error');
return;
}
}
}

View File

@ -107,5 +107,5 @@ class ComponentbuilderControllerSnippets extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=snippets', false), $message, 'error');
return;
}
}
}

View File

@ -11,7 +11,7 @@
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 40 of this MVC
@build 3rd February, 2017
@build 22nd February, 2017
@created 26th May, 2015
@package Component Builder
@subpackage template.php

View File

@ -11,7 +11,7 @@
/-------------------------------------------------------------------------------------------------------------------------------/
@version @update number 40 of this MVC
@build 3rd February, 2017
@build 22nd February, 2017
@created 26th May, 2015
@package Component Builder
@subpackage templates.php
@ -107,5 +107,5 @@ class ComponentbuilderControllerTemplates extends JControllerAdmin
$message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED');
$this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=templates', false), $message, 'error');
return;
}
}
}

View File

@ -1,169 +1,175 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.0.6
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
table.footable,
table.footable-details {
position: relative;
width: 100%;
border-spacing: 0;
border-collapse: collapse;
}
table.footable-details {
margin-bottom: 0;
}
table > tbody > tr > td > span.footable-toggle {
margin-right: 8px;
opacity: 0.3;
}
table > tbody > tr > td > span.footable-toggle.last-column {
margin-left: 8px;
float: right;
}
table.table-condensed > tbody > tr > td > span.footable-toggle {
margin-right: 5px;
}
table.footable-details > tbody > tr > th:nth-child(1) {
min-width: 40px;
width: 120px;
}
table.footable-details > tbody > tr > td:nth-child(2) {
word-break: break-all;
}
table.footable-details > thead > tr:first-child > th,
table.footable-details > thead > tr:first-child > td,
table.footable-details > tbody > tr:first-child > th,
table.footable-details > tbody > tr:first-child > td,
table.footable-details > tfoot > tr:first-child > th,
table.footable-details > tfoot > tr:first-child > td {
border-top-width: 0;
}
table.footable-details.table-bordered > thead > tr:first-child > th,
table.footable-details.table-bordered > thead > tr:first-child > td,
table.footable-details.table-bordered > tbody > tr:first-child > th,
table.footable-details.table-bordered > tbody > tr:first-child > td,
table.footable-details.table-bordered > tfoot > tr:first-child > th,
table.footable-details.table-bordered > tfoot > tr:first-child > td {
border-top-width: 1px;
}
div.footable-loader {
vertical-align: middle;
text-align: center;
height: 300px;
position: relative;
}
div.footable-loader > span.fooicon {
display: inline-block;
opacity: 0.3;
font-size: 30px;
line-height: 32px;
width: 32px;
height: 32px;
margin-top: -16px;
margin-left: -16px;
position: absolute;
top: 50%;
left: 50%;
-webkit-animation: fooicon-spin-r 2s infinite linear;
animation: fooicon-spin-r 2s infinite linear;
}
table.footable > tbody > tr.footable-empty > td {
vertical-align: middle;
text-align: center;
font-size: 30px;
}
table.footable > tbody > tr > td,
table.footable > tbody > tr > th {
display: none;
}
table.footable > tbody > tr.footable-empty > td,
table.footable > tbody > tr.footable-empty > th,
table.footable > tbody > tr.footable-detail-row > td,
table.footable > tbody > tr.footable-detail-row > th {
display: table-cell;
}
@-webkit-keyframes fooicon-spin-r {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes fooicon-spin-r {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.fooicon {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings' !important;
font-style: normal;
font-weight: 400;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fooicon:before,
.fooicon:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.fooicon-loader:before {
content: "\e030";
}
.fooicon-plus:before {
content: "\2b";
}
.fooicon-minus:before {
content: "\2212";
}
.fooicon-search:before {
content: "\e003";
}
.fooicon-remove:before {
content: "\e014";
}
.fooicon-sort:before {
content: "\e150";
}
.fooicon-sort-asc:before {
content: "\e155";
}
.fooicon-sort-desc:before {
content: "\e156";
}
.fooicon-pencil:before {
content: "\270f";
}
.fooicon-trash:before {
content: "\e020";
}
.fooicon-eye-close:before {
content: "\e106";
}
.fooicon-flash:before {
content: "\e162";
}
.fooicon-cog:before {
content: "\e019";
}
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
table.footable,
table.footable-details {
position: relative;
width: 100%;
border-spacing: 0;
border-collapse: collapse;
}
table.footable-details {
margin-bottom: 0;
}
table.footable-hide-fouc {
display: none;
}
table > tbody > tr > td > span.footable-toggle {
margin-right: 8px;
opacity: 0.3;
}
table > tbody > tr > td > span.footable-toggle.last-column {
margin-left: 8px;
float: right;
}
table.table-condensed > tbody > tr > td > span.footable-toggle {
margin-right: 5px;
}
table.footable-details > tbody > tr > th:nth-child(1) {
min-width: 40px;
width: 120px;
}
table.footable-details > tbody > tr > td:nth-child(2) {
word-break: break-all;
}
table.footable-details > thead > tr:first-child > th,
table.footable-details > thead > tr:first-child > td,
table.footable-details > tbody > tr:first-child > th,
table.footable-details > tbody > tr:first-child > td,
table.footable-details > tfoot > tr:first-child > th,
table.footable-details > tfoot > tr:first-child > td {
border-top-width: 0;
}
table.footable-details.table-bordered > thead > tr:first-child > th,
table.footable-details.table-bordered > thead > tr:first-child > td,
table.footable-details.table-bordered > tbody > tr:first-child > th,
table.footable-details.table-bordered > tbody > tr:first-child > td,
table.footable-details.table-bordered > tfoot > tr:first-child > th,
table.footable-details.table-bordered > tfoot > tr:first-child > td {
border-top-width: 1px;
}
div.footable-loader {
vertical-align: middle;
text-align: center;
height: 300px;
position: relative;
}
div.footable-loader > span.fooicon {
display: inline-block;
opacity: 0.3;
font-size: 30px;
line-height: 32px;
width: 32px;
height: 32px;
margin-top: -16px;
margin-left: -16px;
position: absolute;
top: 50%;
left: 50%;
-webkit-animation: fooicon-spin-r 2s infinite linear;
animation: fooicon-spin-r 2s infinite linear;
}
table.footable > tbody > tr.footable-empty > td {
vertical-align: middle;
text-align: center;
font-size: 30px;
}
table.footable > tbody > tr > td,
table.footable > tbody > tr > th {
display: none;
}
table.footable > tbody > tr.footable-empty > td,
table.footable > tbody > tr.footable-empty > th,
table.footable > tbody > tr.footable-detail-row > td,
table.footable > tbody > tr.footable-detail-row > th {
display: table-cell;
}
@-webkit-keyframes fooicon-spin-r {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes fooicon-spin-r {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.fooicon {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings' !important;
font-style: normal;
font-weight: 400;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fooicon:before,
.fooicon:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.fooicon-loader:before {
content: "\e030";
}
.fooicon-plus:before {
content: "\2b";
}
.fooicon-minus:before {
content: "\2212";
}
.fooicon-search:before {
content: "\e003";
}
.fooicon-remove:before {
content: "\e014";
}
.fooicon-sort:before {
content: "\e150";
}
.fooicon-sort-asc:before {
content: "\e155";
}
.fooicon-sort-desc:before {
content: "\e156";
}
.fooicon-pencil:before {
content: "\270f";
}
.fooicon-trash:before {
content: "\e020";
}
.fooicon-eye-close:before {
content: "\e106";
}
.fooicon-flash:before {
content: "\e162";
}
.fooicon-cog:before {
content: "\e019";
}
.fooicon-stats:before {
content: "\e185";
}

View File

@ -0,0 +1 @@
table.footable,table.footable-details{position:relative;width:100%;border-spacing:0;border-collapse:collapse}table.footable-details{margin-bottom:0}table.footable-hide-fouc{display:none}table>tbody>tr>td>span.footable-toggle{margin-right:8px;opacity:.3}table>tbody>tr>td>span.footable-toggle.last-column{margin-left:8px;float:right}table.table-condensed>tbody>tr>td>span.footable-toggle{margin-right:5px}table.footable-details>tbody>tr>th:nth-child(1){min-width:40px;width:120px}table.footable-details>tbody>tr>td:nth-child(2){word-break:break-all}table.footable-details>tbody>tr:first-child>td,table.footable-details>tbody>tr:first-child>th,table.footable-details>tfoot>tr:first-child>td,table.footable-details>tfoot>tr:first-child>th,table.footable-details>thead>tr:first-child>td,table.footable-details>thead>tr:first-child>th{border-top-width:0}table.footable-details.table-bordered>tbody>tr:first-child>td,table.footable-details.table-bordered>tbody>tr:first-child>th,table.footable-details.table-bordered>tfoot>tr:first-child>td,table.footable-details.table-bordered>tfoot>tr:first-child>th,table.footable-details.table-bordered>thead>tr:first-child>td,table.footable-details.table-bordered>thead>tr:first-child>th{border-top-width:1px}div.footable-loader{vertical-align:middle;text-align:center;height:300px;position:relative}div.footable-loader>span.fooicon{display:inline-block;opacity:.3;font-size:30px;line-height:32px;width:32px;height:32px;margin-top:-16px;margin-left:-16px;position:absolute;top:50%;left:50%;-webkit-animation:fooicon-spin-r 2s infinite linear;animation:fooicon-spin-r 2s infinite linear}table.footable>tbody>tr.footable-empty>td{vertical-align:middle;text-align:center;font-size:30px}table.footable>tbody>tr>td,table.footable>tbody>tr>th{display:none}table.footable>tbody>tr.footable-detail-row>td,table.footable>tbody>tr.footable-detail-row>th,table.footable>tbody>tr.footable-empty>td,table.footable>tbody>tr.footable-empty>th{display:table-cell}@-webkit-keyframes fooicon-spin-r{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fooicon-spin-r{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fooicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings'!important;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fooicon:after,.fooicon:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fooicon-loader:before{content:"\e030"}.fooicon-plus:before{content:"\2b"}.fooicon-minus:before{content:"\2212"}.fooicon-search:before{content:"\e003"}.fooicon-remove:before{content:"\e014"}.fooicon-sort:before{content:"\e150"}.fooicon-sort-asc:before{content:"\e155"}.fooicon-sort-desc:before{content:"\e156"}.fooicon-pencil:before{content:"\270f"}.fooicon-trash:before{content:"\e020"}.fooicon-eye-close:before{content:"\e106"}.fooicon-flash:before{content:"\e162"}.fooicon-cog:before{content:"\e019"}.fooicon-stats:before{content:"\e185"}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,50 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
td.footable-editing {
width: 90px;
max-width: 90px;
}
table.footable-editing-no-edit td.footable-editing,
table.footable-editing-no-delete td.footable-editing,
table.footable-editing-no-view td.footable-editing {
width: 70px;
max-width: 70px;
}
table.footable-editing-no-edit.footable-editing-no-delete td.footable-editing,
table.footable-editing-no-edit.footable-editing-no-view td.footable-editing,
table.footable-editing-no-delete.footable-editing-no-view td.footable-editing {
width: 50px;
max-width: 50px;
}
table.footable-editing-no-edit.footable-editing-no-delete.footable-editing-no-view td.footable-editing,
table.footable-editing-no-edit.footable-editing-no-delete.footable-editing-no-view th.footable-editing {
width: 0;
max-width: 0;
display: none !important;
}
table.footable-editing-right td.footable-editing,
table.footable-editing-right tr.footable-editing {
text-align: right;
}
table.footable-editing-left td.footable-editing,
table.footable-editing-left tr.footable-editing {
text-align: left;
}
table.footable-editing button.footable-add,
table.footable-editing button.footable-hide,
table.footable-editing-show button.footable-show,
table.footable-editing.footable-editing-always-show button.footable-show,
table.footable-editing.footable-editing-always-show button.footable-hide,
table.footable-editing.footable-editing-always-show.footable-editing-no-add tr.footable-editing {
display: none;
}
table.footable-editing.footable-editing-show button.footable-add,
table.footable-editing.footable-editing-show button.footable-hide,
table.footable-editing.footable-editing-always-show button.footable-add {
display: inline-block;
}

View File

@ -0,0 +1 @@
td.footable-editing{width:90px;max-width:90px}table.footable-editing-no-delete td.footable-editing,table.footable-editing-no-edit td.footable-editing,table.footable-editing-no-view td.footable-editing{width:70px;max-width:70px}table.footable-editing-no-delete.footable-editing-no-view td.footable-editing,table.footable-editing-no-edit.footable-editing-no-delete td.footable-editing,table.footable-editing-no-edit.footable-editing-no-view td.footable-editing{width:50px;max-width:50px}table.footable-editing-no-edit.footable-editing-no-delete.footable-editing-no-view td.footable-editing,table.footable-editing-no-edit.footable-editing-no-delete.footable-editing-no-view th.footable-editing{width:0;max-width:0;display:none!important}table.footable-editing-right td.footable-editing,table.footable-editing-right tr.footable-editing{text-align:right}table.footable-editing-left td.footable-editing,table.footable-editing-left tr.footable-editing{text-align:left}table.footable-editing button.footable-add,table.footable-editing button.footable-hide,table.footable-editing-show button.footable-show,table.footable-editing.footable-editing-always-show button.footable-hide,table.footable-editing.footable-editing-always-show button.footable-show,table.footable-editing.footable-editing-always-show.footable-editing-no-add tr.footable-editing{display:none}table.footable-editing.footable-editing-always-show button.footable-add,table.footable-editing.footable-editing-show button.footable-add,table.footable-editing.footable-editing-show button.footable-hide{display:inline-block}

View File

@ -1,55 +1,55 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.0.6
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
table.footable > thead > tr.footable-filtering > th {
border-bottom-width: 1px;
font-weight: normal;
}
table.footable > thead > tr.footable-filtering > th,
table.footable.footable-filtering-right > thead > tr.footable-filtering > th {
text-align: right;
}
table.footable.footable-filtering-left > thead > tr.footable-filtering > th {
text-align: left;
}
table.footable.footable-filtering-center > thead > tr.footable-filtering > th {
text-align: center;
}
table.footable > thead > tr.footable-filtering > th div.form-group {
margin-bottom: 0;
}
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
margin-top: 5px;
}
table.footable > thead > tr.footable-filtering > th div.input-group {
width: 100%;
}
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox {
margin: 0;
display: block;
position: relative;
}
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox > label {
display: block;
padding-left: 20px;
}
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox input[type="checkbox"] {
position: absolute;
margin-left: -20px;
}
@media (min-width: 768px) {
table.footable > thead > tr.footable-filtering > th div.input-group {
width: auto;
}
table.footable > thead > tr.footable-filtering > th div.form-group {
margin-left: 2px;
margin-right: 2px;
}
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
margin-top: 0;
}
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
table.footable > thead > tr.footable-filtering > th {
border-bottom-width: 1px;
font-weight: normal;
}
table.footable > thead > tr.footable-filtering > th,
table.footable.footable-filtering-right > thead > tr.footable-filtering > th {
text-align: right;
}
table.footable.footable-filtering-left > thead > tr.footable-filtering > th {
text-align: left;
}
table.footable.footable-filtering-center > thead > tr.footable-filtering > th {
text-align: center;
}
table.footable > thead > tr.footable-filtering > th div.form-group {
margin-bottom: 0;
}
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
margin-top: 5px;
}
table.footable > thead > tr.footable-filtering > th div.input-group {
width: 100%;
}
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox {
margin: 0;
display: block;
position: relative;
}
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox > label {
display: block;
padding-left: 20px;
}
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox input[type="checkbox"] {
position: absolute;
margin-left: -20px;
}
@media (min-width: 768px) {
table.footable > thead > tr.footable-filtering > th div.input-group {
width: auto;
}
table.footable > thead > tr.footable-filtering > th div.form-group {
margin-left: 2px;
margin-right: 2px;
}
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
margin-top: 0;
}
}

View File

@ -1,31 +1,31 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.0.6
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
table.footable > tfoot > tr.footable-paging > td > ul.pagination {
margin: 10px 0 0 0;
}
table.footable > tfoot > tr.footable-paging > td > span.label {
display: inline-block;
margin: 0 0 10px 0;
padding: 4px 10px;
}
table.footable > tfoot > tr.footable-paging > td,
table.footable-paging-center > tfoot > tr.footable-paging > td {
text-align: center;
}
table.footable-paging-left > tfoot > tr.footable-paging > td {
text-align: left;
}
table.footable-paging-right > tfoot > tr.footable-paging > td {
text-align: right;
}
ul.pagination > li.footable-page {
display: none;
}
ul.pagination > li.footable-page.visible {
display: inline;
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
table.footable > tfoot > tr.footable-paging > td > ul.pagination {
margin: 10px 0 0 0;
}
table.footable > tfoot > tr.footable-paging > td > span.label {
display: inline-block;
margin: 0 0 10px 0;
padding: 4px 10px;
}
table.footable > tfoot > tr.footable-paging > td,
table.footable-paging-center > tfoot > tr.footable-paging > td {
text-align: center;
}
table.footable-paging-left > tfoot > tr.footable-paging > td {
text-align: left;
}
table.footable-paging-right > tfoot > tr.footable-paging > td {
text-align: right;
}
ul.pagination > li.footable-page {
display: none;
}
ul.pagination > li.footable-page.visible {
display: inline;
}

View File

@ -1,32 +1,46 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.0.6
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
td.footable-sortable,
th.footable-sortable {
position: relative;
padding-right: 30px;
cursor: pointer;
}
td.footable-sortable > span.fooicon,
th.footable-sortable > span.fooicon {
position: absolute;
right: 6px;
top: 50%;
margin-top: -7px;
opacity: 0;
transition: opacity 0.3s ease-in;
}
td.footable-sortable:hover > span.fooicon,
th.footable-sortable:hover > span.fooicon {
opacity: 1;
}
td.footable-sortable.footable-asc > span.fooicon,
th.footable-sortable.footable-asc > span.fooicon,
td.footable-sortable.footable-desc > span.fooicon,
th.footable-sortable.footable-desc > span.fooicon {
opacity: 1;
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
table.footable > thead > tr > td.footable-sortable,
table.footable > thead > tr > th.footable-sortable,
table.footable > tbody > tr > td.footable-sortable,
table.footable > tbody > tr > th.footable-sortable,
table.footable > tfoot > tr > td.footable-sortable,
table.footable > tfoot > tr > th.footable-sortable {
position: relative;
padding-right: 30px;
cursor: pointer;
}
td.footable-sortable > span.fooicon,
th.footable-sortable > span.fooicon {
position: absolute;
right: 6px;
top: 50%;
margin-top: -7px;
opacity: 0;
transition: opacity 0.3s ease-in;
}
td.footable-sortable:hover > span.fooicon,
th.footable-sortable:hover > span.fooicon {
opacity: 1;
}
td.footable-sortable.footable-asc > span.fooicon,
th.footable-sortable.footable-asc > span.fooicon,
td.footable-sortable.footable-desc > span.fooicon,
th.footable-sortable.footable-desc > span.fooicon {
opacity: 1;
}
/* hides the sort icons when sorting is not allowed */
table.footable-sorting-disabled td.footable-sortable.footable-asc > span.fooicon,
table.footable-sorting-disabled td.footable-sortable.footable-desc > span.fooicon,
table.footable-sorting-disabled td.footable-sortable:hover > span.fooicon,
table.footable-sorting-disabled th.footable-sortable.footable-asc > span.fooicon,
table.footable-sorting-disabled th.footable-sortable.footable-desc > span.fooicon,
table.footable-sorting-disabled th.footable-sortable:hover > span.fooicon {
opacity: 0;
visibility: hidden;
}

View File

@ -1 +1 @@
td.footable-sortable,th.footable-sortable{position:relative;padding-right:30px;cursor:pointer}td.footable-sortable>span.fooicon,th.footable-sortable>span.fooicon{position:absolute;right:6px;top:50%;margin-top:-7px;opacity:0;transition:opacity .3s ease-in}td.footable-sortable.footable-asc>span.fooicon,td.footable-sortable.footable-desc>span.fooicon,td.footable-sortable:hover>span.fooicon,th.footable-sortable.footable-asc>span.fooicon,th.footable-sortable.footable-desc>span.fooicon,th.footable-sortable:hover>span.fooicon{opacity:1}
table.footable>tbody>tr>td.footable-sortable,table.footable>tbody>tr>th.footable-sortable,table.footable>tfoot>tr>td.footable-sortable,table.footable>tfoot>tr>th.footable-sortable,table.footable>thead>tr>td.footable-sortable,table.footable>thead>tr>th.footable-sortable{position:relative;padding-right:30px;cursor:pointer}td.footable-sortable>span.fooicon,th.footable-sortable>span.fooicon{position:absolute;right:6px;top:50%;margin-top:-7px;opacity:0;transition:opacity .3s ease-in}td.footable-sortable.footable-asc>span.fooicon,td.footable-sortable.footable-desc>span.fooicon,td.footable-sortable:hover>span.fooicon,th.footable-sortable.footable-asc>span.fooicon,th.footable-sortable.footable-desc>span.fooicon,th.footable-sortable:hover>span.fooicon{opacity:1}table.footable-sorting-disabled td.footable-sortable.footable-asc>span.fooicon,table.footable-sorting-disabled td.footable-sortable.footable-desc>span.fooicon,table.footable-sorting-disabled td.footable-sortable:hover>span.fooicon,table.footable-sorting-disabled th.footable-sortable.footable-asc>span.fooicon,table.footable-sorting-disabled th.footable-sortable.footable-desc>span.fooicon,table.footable-sorting-disabled th.footable-sortable:hover>span.fooicon{opacity:0;visibility:hidden}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,802 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
(function($, F){
F.Editing = F.Component.extend(/** @lends FooTable.Editing */{
/**
* The editing component adds a column with edit and delete buttons to each row as well as a single add row button in the footer.
* @constructs
* @extends FooTable.Component
* @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
* @returns {FooTable.Editing}
*/
construct: function(table){
// call the base constructor
this._super(table, table.o.editing.enabled);
/**
* Whether or not to automatically page to a new row when it is added to the table.
* @type {boolean}
*/
this.pageToNew = table.o.editing.pageToNew;
/**
* Whether or not the editing column and add row button are always visible.
* @type {boolean}
*/
this.alwaysShow = table.o.editing.alwaysShow;
/**
* The options for the editing column. @see {@link FooTable.EditingColumn} for more info.
* @type {object}
* @prop {string} classes="footable-editing" - A space separated string of class names to apply to all cells in the column.
* @prop {string} name="editing" - The name of the column.
* @prop {string} title="" - The title displayed in the header row of the table for the column.
* @prop {boolean} filterable=false - Whether or not the column should be filterable when using the filtering component.
* @prop {boolean} sortable=false - Whether or not the column should be sortable when using the sorting component.
*/
this.column = $.extend(true, {}, table.o.editing.column, {visible: this.alwaysShow});
/**
* The position of the editing column in the table as well as the alignment of the buttons.
* @type {string}
*/
this.position = table.o.editing.position;
/**
* The text that appears in the show button. This can contain HTML.
* @type {string}
*/
this.showText = table.o.editing.showText;
/**
* The text that appears in the hide button. This can contain HTML.
* @type {string}
*/
this.hideText = table.o.editing.hideText;
/**
* The text that appears in the add button. This can contain HTML.
* @type {string}
*/
this.addText = table.o.editing.addText;
/**
* The text that appears in the edit button. This can contain HTML.
* @type {string}
*/
this.editText = table.o.editing.editText;
/**
* The text that appears in the delete button. This can contain HTML.
* @type {string}
*/
this.deleteText = table.o.editing.deleteText;
/**
* The text that appears in the view button. This can contain HTML.
* @type {string}
*/
this.viewText = table.o.editing.viewText;
/**
* Whether or not to show the Add Row button.
* @type {boolean}
*/
this.allowAdd = table.o.editing.allowAdd;
/**
* Whether or not to show the Edit Row button.
* @type {boolean}
*/
this.allowEdit = table.o.editing.allowEdit;
/**
* Whether or not to show the Delete Row button.
* @type {boolean}
*/
this.allowDelete = table.o.editing.allowDelete;
/**
* Whether or not to show the View Row button.
* @type {boolean}
*/
this.allowView = table.o.editing.allowView;
/**
* Caches the row button elements to help with performance.
* @type {(null|jQuery)}
* @private
*/
this._$buttons = null;
/**
* This object is used to contain the callbacks for the add, edit and delete row buttons.
* @type {object}
* @prop {function} addRow
* @prop {function} editRow
* @prop {function} deleteRow
* @prop {function} viewRow
*/
this.callbacks = {
addRow: F.checkFnValue(this, table.o.editing.addRow),
editRow: F.checkFnValue(this, table.o.editing.editRow),
deleteRow: F.checkFnValue(this, table.o.editing.deleteRow),
viewRow: F.checkFnValue(this, table.o.editing.viewRow)
};
},
/* PROTECTED */
/**
* Checks the supplied data and options for the editing component.
* @instance
* @protected
* @param {object} data - The jQuery data object from the parent table.
* @fires FooTable.Editing#"preinit.ft.editing"
*/
preinit: function(data){
var self = this;
/**
* The preinit.ft.editing event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
* Calling preventDefault on this event will disable the component.
* @event FooTable.Editing#"preinit.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {object} data - The jQuery data object of the table raising the event.
*/
this.ft.raise('preinit.ft.editing', [data]).then(function(){
if (self.ft.$el.hasClass('footable-editing'))
self.enabled = true;
self.enabled = F.is.boolean(data.editing)
? data.editing
: self.enabled;
if (!self.enabled) return;
self.pageToNew = F.is.boolean(data.editingPageToNew) ? data.editingPageToNew : self.pageToNew;
self.alwaysShow = F.is.boolean(data.editingAlwaysShow) ? data.editingAlwaysShow : self.alwaysShow;
self.position = F.is.string(data.editingPosition) ? data.editingPosition : self.position;
self.showText = F.is.string(data.editingShowText) ? data.editingShowText : self.showText;
self.hideText = F.is.string(data.editingHideText) ? data.editingHideText : self.hideText;
self.addText = F.is.string(data.editingAddText) ? data.editingAddText : self.addText;
self.editText = F.is.string(data.editingEditText) ? data.editingEditText : self.editText;
self.deleteText = F.is.string(data.editingDeleteText) ? data.editingDeleteText : self.deleteText;
self.viewText = F.is.string(data.editingViewText) ? data.editingViewText : self.viewText;
self.allowAdd = F.is.boolean(data.editingAllowAdd) ? data.editingAllowAdd : self.allowAdd;
self.allowEdit = F.is.boolean(data.editingAllowEdit) ? data.editingAllowEdit : self.allowEdit;
self.allowDelete = F.is.boolean(data.editingAllowDelete) ? data.editingAllowDelete : self.allowDelete;
self.allowView = F.is.boolean(data.editingAllowView) ? data.editingAllowView : self.allowView;
self.column = new F.EditingColumn(self.ft, self, $.extend(true, {}, self.column, data.editingColumn, {visible: self.alwaysShow}));
if (self.ft.$el.hasClass('footable-editing-left'))
self.position = 'left';
if (self.ft.$el.hasClass('footable-editing-right'))
self.position = 'right';
if (self.position === 'right'){
self.column.index = self.ft.columns.array.length;
} else {
self.column.index = 0;
for (var i = 0, len = self.ft.columns.array.length; i < len; i++){
self.ft.columns.array[i].index += 1;
}
}
self.ft.columns.array.push(self.column);
self.ft.columns.array.sort(function(a, b){ return a.index - b.index; });
self.callbacks.addRow = F.checkFnValue(self, data.editingAddRow, self.callbacks.addRow);
self.callbacks.editRow = F.checkFnValue(self, data.editingEditRow, self.callbacks.editRow);
self.callbacks.deleteRow = F.checkFnValue(self, data.editingDeleteRow, self.callbacks.deleteRow);
self.callbacks.viewRow = F.checkFnValue(self, data.editingViewRow, self.callbacks.viewRow);
}, function(){
self.enabled = false;
});
},
/**
* Initializes the editing component for the plugin using the supplied table and options.
* @instance
* @protected
* @fires FooTable.Editing#"init.ft.editing"
*/
init: function(){
/**
* The init.ft.editing event is raised before its UI is generated.
* Calling preventDefault on this event will disable the component.
* @event FooTable.Editing#"init.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
var self = this;
this.ft.raise('init.ft.editing').then(function(){
self.$create();
}, function(){
self.enabled = false;
});
},
/**
* Destroys the editing component removing any UI generated from the table.
* @instance
* @protected
* @fires FooTable.Editing#"destroy.ft.editing"
*/
destroy: function () {
/**
* The destroy.ft.editing event is raised before its UI is removed.
* Calling preventDefault on this event will prevent the component from being destroyed.
* @event FooTable.Editing#"destroy.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
var self = this;
this.ft.raise('destroy.ft.editing').then(function(){
self.ft.$el.removeClass('footable-editing footable-editing-always-show footable-editing-no-add footable-editing-no-edit footable-editing-no-delete footable-editing-no-view')
.off('click.ft.editing').find('tfoot > tr.footable-editing').remove();
});
},
/**
* Creates the editing UI from the current options setting the various jQuery properties of this component.
* @instance
* @protected
*/
$create: function(){
var self = this, position = self.position === 'right' ? 'footable-editing-right' : 'footable-editing-left';
self.ft.$el.addClass('footable-editing').addClass(position)
.on('click.ft.editing', '.footable-show', {self: self}, self._onShowClick)
.on('click.ft.editing', '.footable-hide', {self: self}, self._onHideClick)
.on('click.ft.editing', '.footable-edit', {self: self}, self._onEditClick)
.on('click.ft.editing', '.footable-delete', {self: self}, self._onDeleteClick)
.on('click.ft.editing', '.footable-view', {self: self}, self._onViewClick)
.on('click.ft.editing', '.footable-add', {self: self}, self._onAddClick);
self.$cell = $('<td/>').attr('colspan', self.ft.columns.visibleColspan).append(self.$buttonShow());
if (self.allowAdd){
self.$cell.append(self.$buttonAdd());
}
self.$cell.append(self.$buttonHide());
if (self.alwaysShow){
self.ft.$el.addClass('footable-editing-always-show');
}
if (!self.allowAdd) self.ft.$el.addClass('footable-editing-no-add');
if (!self.allowEdit) self.ft.$el.addClass('footable-editing-no-edit');
if (!self.allowDelete) self.ft.$el.addClass('footable-editing-no-delete');
if (!self.allowView) self.ft.$el.addClass('footable-editing-no-view');
var $tfoot = self.ft.$el.children('tfoot');
if ($tfoot.length == 0){
$tfoot = $('<tfoot/>');
self.ft.$el.append($tfoot);
}
self.$row = $('<tr/>', { 'class': 'footable-editing' }).append(self.$cell).appendTo($tfoot);
},
/**
* Creates the show button for the editing component.
* @instance
* @protected
* @returns {(string|HTMLElement|jQuery)}
*/
$buttonShow: function(){
return '<button type="button" class="btn btn-primary footable-show">' + this.showText + '</button>';
},
/**
* Creates the hide button for the editing component.
* @instance
* @protected
* @returns {(string|HTMLElement|jQuery)}
*/
$buttonHide: function(){
return '<button type="button" class="btn btn-default footable-hide">' + this.hideText + '</button>';
},
/**
* Creates the add button for the editing component.
* @instance
* @protected
* @returns {(string|HTMLElement|jQuery)}
*/
$buttonAdd: function(){
return '<button type="button" class="btn btn-primary footable-add">' + this.addText + '</button> ';
},
/**
* Creates the edit button for the editing component.
* @instance
* @protected
* @returns {(string|HTMLElement|jQuery)}
*/
$buttonEdit: function(){
return '<button type="button" class="btn btn-default footable-edit">' + this.editText + '</button> ';
},
/**
* Creates the delete button for the editing component.
* @instance
* @protected
* @returns {(string|HTMLElement|jQuery)}
*/
$buttonDelete: function(){
return '<button type="button" class="btn btn-default footable-delete">' + this.deleteText + '</button>';
},
/**
* Creates the view button for the editing component.
* @instance
* @protected
* @returns {(string|HTMLElement|jQuery)}
*/
$buttonView: function(){
return '<button type="button" class="btn btn-default footable-view">' + this.viewText + '</button> ';
},
/**
* Creates the button group for the row buttons.
* @instance
* @protected
* @returns {(string|HTMLElement|jQuery)}
*/
$rowButtons: function(){
if (F.is.jq(this._$buttons)) return this._$buttons.clone();
this._$buttons = $('<div class="btn-group btn-group-xs" role="group"></div>');
if (this.allowView) this._$buttons.append(this.$buttonView());
if (this.allowEdit) this._$buttons.append(this.$buttonEdit());
if (this.allowDelete) this._$buttons.append(this.$buttonDelete());
return this._$buttons;
},
/**
* Performs the drawing of the component.
*/
draw: function(){
this.$cell.attr('colspan', this.ft.columns.visibleColspan);
},
/**
* Handles the edit button click event.
* @instance
* @private
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @fires FooTable.Editing#"edit.ft.editing"
*/
_onEditClick: function(e){
e.preventDefault();
var self = e.data.self, row = $(this).closest('tr').data('__FooTableRow__');
if (row instanceof F.Row){
/**
* The edit.ft.editing event is raised before its callback is executed.
* Calling preventDefault on this event will prevent the callback from being executed.
* @event FooTable.Editing#"edit.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {FooTable.Row} row - The row to be edited.
*/
self.ft.raise('edit.ft.editing', [row]).then(function(){
self.callbacks.editRow.call(self.ft, row);
});
}
},
/**
* Handles the delete button click event.
* @instance
* @private
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @fires FooTable.Editing#"delete.ft.editing"
*/
_onDeleteClick: function(e){
e.preventDefault();
var self = e.data.self, row = $(this).closest('tr').data('__FooTableRow__');
if (row instanceof F.Row){
/**
* The delete.ft.editing event is raised before its callback is executed.
* Calling preventDefault on this event will prevent the callback from being executed.
* @event FooTable.Editing#"delete.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {FooTable.Row} row - The row to be deleted.
*/
self.ft.raise('delete.ft.editing', [row]).then(function(){
self.callbacks.deleteRow.call(self.ft, row);
});
}
},
/**
* Handles the view button click event.
* @instance
* @private
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @fires FooTable.Editing#"view.ft.editing"
*/
_onViewClick: function(e){
e.preventDefault();
var self = e.data.self, row = $(this).closest('tr').data('__FooTableRow__');
if (row instanceof F.Row){
/**
* The view.ft.editing event is raised before its callback is executed.
* Calling preventDefault on this event will prevent the callback from being executed.
* @event FooTable.Editing#"view.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {FooTable.Row} row - The row to be viewed.
*/
self.ft.raise('view.ft.editing', [row]).then(function(){
self.callbacks.viewRow.call(self.ft, row);
});
}
},
/**
* Handles the add button click event.
* @instance
* @private
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @fires FooTable.Editing#"add.ft.editing"
*/
_onAddClick: function(e){
e.preventDefault();
var self = e.data.self;
/**
* The add.ft.editing event is raised before its callback is executed.
* Calling preventDefault on this event will prevent the callback from being executed.
* @event FooTable.Editing#"add.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
self.ft.raise('add.ft.editing').then(function(){
self.callbacks.addRow.call(self.ft);
});
},
/**
* Handles the show button click event.
* @instance
* @private
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @fires FooTable.Editing#"show.ft.editing"
*/
_onShowClick: function(e){
e.preventDefault();
var self = e.data.self;
/**
* The show.ft.editing event is raised before its callback is executed.
* Calling preventDefault on this event will prevent the callback from being executed.
* @event FooTable.Editing#"show.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
self.ft.raise('show.ft.editing').then(function(){
self.ft.$el.addClass('footable-editing-show');
self.column.visible = true;
self.ft.draw();
});
},
/**
* Handles the hide button click event.
* @instance
* @private
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @fires FooTable.Editing#"show.ft.editing"
*/
_onHideClick: function(e){
e.preventDefault();
var self = e.data.self;
/**
* The hide.ft.editing event is raised before its callback is executed.
* Calling preventDefault on this event will prevent the callback from being executed.
* @event FooTable.Editing#"hide.ft.editing"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
self.ft.raise('hide.ft.editing').then(function(){
self.ft.$el.removeClass('footable-editing-show');
self.column.visible = false;
self.ft.draw();
});
}
});
F.components.register('editing', F.Editing, 850);
})(jQuery, FooTable);
(function($, F){
F.EditingColumn = F.Column.extend(/** @lends FooTable.EditingColumn */{
/**
* The Editing column class is used to create the column containing the editing buttons.
* @constructs
* @extends FooTable.Column
* @param {FooTable.Table} instance - The parent {@link FooTable.Table} this column belongs to.
* @param {FooTable.Editing} editing - The parent {@link FooTable.Editing} component this column is used with.
* @param {object} definition - An object containing all the properties to set for the column.
* @returns {FooTable.EditingColumn}
*/
construct: function(instance, editing, definition){
this._super(instance, definition, 'editing');
this.editing = editing;
},
/**
* After the column has been defined this ensures that the $el property is a jQuery object by either creating or updating the current value.
* @instance
* @protected
* @this FooTable.Column
*/
$create: function(){
(this.$el = !this.virtual && F.is.jq(this.$el) ? this.$el : $('<th/>', {'class': 'footable-editing'})).html(this.title);
},
/**
* This is supplied either the cell value or jQuery object to parse. Any value can be returned from this method and
* will be provided to the {@link FooTable.EditingColumn#format} function
* to generate the cell contents.
* @instance
* @protected
* @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
* @returns {(jQuery)}
*/
parser: function(valueOrElement){
if (F.is.string(valueOrElement)) valueOrElement = $($.trim(valueOrElement));
if (F.is.element(valueOrElement)) valueOrElement = $(valueOrElement);
if (F.is.jq(valueOrElement)){
var tagName = valueOrElement.prop('tagName').toLowerCase();
if (tagName == 'td' || tagName == 'th') return valueOrElement.data('value') || valueOrElement.contents();
return valueOrElement;
}
return null;
},
/**
* Creates a cell to be used in the supplied row for this column.
* @param {FooTable.Row} row - The row to create the cell for.
* @returns {FooTable.Cell}
*/
createCell: function(row){
var $buttons = this.editing.$rowButtons(), $cell = $('<td/>').append($buttons);
if (F.is.jq(row.$el)){
if (this.index === 0){
$cell.prependTo(row.$el);
} else {
$cell.insertAfter(row.$el.children().eq(this.index-1));
}
}
return new F.Cell(this.ft, row, this, $cell || $cell.html());
}
});
F.columns.register('editing', F.EditingColumn);
})(jQuery, FooTable);
(function($, F) {
/**
* An object containing the editing options for the plugin. Added by the {@link FooTable.Editing} component.
* @type {object}
* @prop {boolean} enabled=false - Whether or not to allow editing on the table.
* @prop {boolean} pageToNew=true - Whether or not to automatically page to a new row when it is added to the table.
* @prop {string} position="right" - The position of the editing column in the table as well as the alignment of the buttons.
* @prop {boolean} alwaysShow=false - Whether or not the editing column and add row button are always visible.
* @prop {function} addRow - The callback function to execute when the add row button is clicked.
* @prop {function} editRow - The callback function to execute when the edit row button is clicked.
* @prop {function} deleteRow - The callback function to execute when the delete row button is clicked.
* @prop {function} viewRow - The callback function to execute when the view row button is clicked.
* @prop {string} showText - The text that appears in the show button. This can contain HTML.
* @prop {string} hideText - The text that appears in the hide button. This can contain HTML.
* @prop {string} addText - The text that appears in the add button. This can contain HTML.
* @prop {string} editText - The text that appears in the edit button. This can contain HTML.
* @prop {string} deleteText - The text that appears in the delete button. This can contain HTML.
* @prop {string} viewText - The text that appears in the view button. This can contain HTML.
* @prop {boolean} allowAdd - Whether or not to show the Add Row button.
* @prop {boolean} allowEdit - Whether or not to show the Edit Row button.
* @prop {boolean} allowDelete - Whether or not to show the Delete Row button.
* @prop {boolean} allowView - Whether or not to show the View Row button.
* @prop {object} column - The options for the editing column. @see {@link FooTable.EditingColumn} for more info.
* @prop {string} column.classes="footable-editing" - A space separated string of class names to apply to all cells in the column.
* @prop {string} column.name="editing" - The name of the column.
* @prop {string} column.title="" - The title displayed in the header row of the table for the column.
* @prop {boolean} column.filterable=false - Whether or not the column should be filterable when using the filtering component.
* @prop {boolean} column.sortable=false - Whether or not the column should be sortable when using the sorting component.
*/
F.Defaults.prototype.editing = {
enabled: false,
pageToNew: true,
position: 'right',
alwaysShow: false,
addRow: function(){},
editRow: function(row){},
deleteRow: function(row){},
viewRow: function(row){},
showText: '<span class="fooicon fooicon-pencil" aria-hidden="true"></span> Edit rows',
hideText: 'Cancel',
addText: 'New row',
editText: '<span class="fooicon fooicon-pencil" aria-hidden="true"></span>',
deleteText: '<span class="fooicon fooicon-trash" aria-hidden="true"></span>',
viewText: '<span class="fooicon fooicon-stats" aria-hidden="true"></span>',
allowAdd: true,
allowEdit: true,
allowDelete: true,
allowView: false,
column: {
classes: 'footable-editing',
name: 'editing',
title: '',
filterable: false,
sortable: false
}
};
})(jQuery, FooTable);
(function($, F){
if (F.is.defined(F.Paging)){
/**
* Holds a shallow clone of the un-paged {@link FooTable.Rows#array} value before paging occurs and superfluous rows are removed. Added by the {@link FooTable.Editing} component.
* @instance
* @public
* @type {Array<FooTable.Row>}
*/
F.Paging.prototype.unpaged = [];
// override the default predraw method with one that sets the unpaged property.
F.Paging.extend('predraw', function(){
this.unpaged = this.ft.rows.array.slice(0); // create a shallow clone for later use
this._super(); // call the original method
});
}
})(jQuery, FooTable);
(function($, F){
/**
* Adds the row to the table.
* @param {boolean} [redraw=true] - Whether or not to redraw the table, defaults to true but for bulk operations this
* can be set to false and then followed by a call to the {@link FooTable.Table#draw} method.
* @returns {jQuery.Deferred}
*/
F.Row.prototype.add = function(redraw){
redraw = F.is.boolean(redraw) ? redraw : true;
var self = this;
return $.Deferred(function(d){
var index = self.ft.rows.all.push(self) - 1;
if (redraw){
return self.ft.draw().then(function(){
d.resolve(index);
});
} else {
d.resolve(index);
}
});
};
/**
* Removes the row from the table.
* @param {boolean} [redraw=true] - Whether or not to redraw the table, defaults to true but for bulk operations this
* can be set to false and then followed by a call to the {@link FooTable.Table#draw} method.
* @returns {jQuery.Deferred}
*/
F.Row.prototype.delete = function(redraw){
redraw = F.is.boolean(redraw) ? redraw : true;
var self = this;
return $.Deferred(function(d){
var index = self.ft.rows.all.indexOf(self);
if (F.is.number(index) && index >= 0 && index < self.ft.rows.all.length){
self.ft.rows.all.splice(index, 1);
if (redraw){
return self.ft.draw().then(function(){
d.resolve(self);
});
}
}
d.resolve(self);
});
};
if (F.is.defined(F.Paging)){
// override the default add method with one that supports paging
F.Row.extend('add', function(redraw){
redraw = F.is.boolean(redraw) ? redraw : true;
var self = this,
added = this._super(redraw),
editing = self.ft.use(F.Editing),
paging;
if (editing && editing.pageToNew && (paging = self.ft.use(F.Paging)) && redraw){
return added.then(function(){
var index = paging.unpaged.indexOf(self); // find this row in the unpaged array (this array will be sorted and filtered)
var page = Math.ceil((index + 1) / paging.size); // calculate the page the new row is on
if (paging.current !== page){ // goto the page if we need to
return paging.goto(page);
}
});
}
return added;
});
}
if (F.is.defined(F.Sorting)){
// override the default val method with one that supports sorting and paging
F.Row.extend('val', function(data, redraw){
redraw = F.is.boolean(redraw) ? redraw : true;
var result = this._super(data);
if (!F.is.hash(data)){
return result;
}
var self = this;
if (redraw){
self.ft.draw().then(function(){
var editing = self.ft.use(F.Editing), paging;
if (F.is.defined(F.Paging) && editing && editing.pageToNew && (paging = self.ft.use(F.Paging))){
var index = paging.unpaged.indexOf(self); // find this row in the unpaged array (this array will be sorted and filtered)
var page = Math.ceil((index + 1) / paging.size); // calculate the page the new row is on
if (paging.current !== page){ // goto the page if we need to
return paging.goto(page);
}
}
});
}
return result;
});
}
})(jQuery, FooTable);
(function(F){
/**
* Adds a row to the underlying {@link FooTable.Rows#all} array.
* @param {(object|FooTable.Row)} dataOrRow - A hash containing the row values or an actual {@link FooTable.Row} object.
* @param {boolean} [redraw=true] - Whether or not to redraw the table, defaults to true but for bulk operations this
* can be set to false and then followed by a call to the {@link FooTable.Table#draw} method.
*/
F.Rows.prototype.add = function(dataOrRow, redraw){
var row = dataOrRow;
if (F.is.hash(dataOrRow)){
row = new FooTable.Row(this.ft, this.ft.columns.array, dataOrRow);
}
if (row instanceof FooTable.Row){
row.add(redraw);
}
};
/**
* Updates a row in the underlying {@link FooTable.Rows#all} array.
* @param {(number|FooTable.Row)} indexOrRow - The index to update or the actual {@link FooTable.Row} object.
* @param {object} data - A hash containing the new row values.
* @param {boolean} [redraw=true] - Whether or not to redraw the table, defaults to true but for bulk operations this
* can be set to false and then followed by a call to the {@link FooTable.Table#draw} method.
*/
F.Rows.prototype.update = function(indexOrRow, data, redraw){
var len = this.ft.rows.all.length,
row = indexOrRow;
if (F.is.number(indexOrRow) && indexOrRow >= 0 && indexOrRow < len){
row = this.ft.rows.all[indexOrRow];
}
if (row instanceof FooTable.Row && F.is.hash(data)){
row.val(data, redraw);
}
};
/**
* Deletes a row from the underlying {@link FooTable.Rows#all} array.
* @param {(number|FooTable.Row)} indexOrRow - The index to delete or the actual {@link FooTable.Row} object.
* @param {boolean} [redraw=true] - Whether or not to redraw the table, defaults to true but for bulk operations this
* can be set to false and then followed by a call to the {@link FooTable.Table#draw} method.
*/
F.Rows.prototype.delete = function(indexOrRow, redraw){
var len = this.ft.rows.all.length,
row = indexOrRow;
if (F.is.number(indexOrRow) && indexOrRow >= 0 && indexOrRow < len){
row = this.ft.rows.all[indexOrRow];
}
if (row instanceof FooTable.Row){
row.delete(redraw);
}
};
})(FooTable);

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,435 +1,490 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.0.6
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
(function($, F){
F.Sorter = F.Class.extend(/** @lends FooTable.Sorter */{
/**
* The sorter object contains the column and direction to sort by.
* @constructs
* @extends FooTable.Class
* @param {FooTable.Column} column - The column to sort.
* @param {string} direction - The direction to sort by.
* @returns {FooTable.Sorter}
*/
construct: function(column, direction){
/**
* The column to sort.
* @type {FooTable.Column}
*/
this.column = column;
/**
* The direction to sort by.
* @type {string}
*/
this.direction = direction;
}
});
})(jQuery, FooTable);
(function ($, F) {
F.Sorting = F.Component.extend(/** @lends FooTable.Sorting */{
/**
* The sorting component adds a small sort button to specified column headers allowing users to sort those columns in the table.
* @constructs
* @extends FooTable.Component
* @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
* @returns {FooTable.Sorting}
*/
construct: function (table) {
// call the constructor of the base class
this._super(table, table.o.sorting.enabled);
/* PROTECTED */
/**
* This provides a shortcut to the {@link FooTable.Table#options}.[sorting]{@link FooTable.Defaults#sorting} object.
* @instance
* @protected
* @type {object}
*/
this.o = table.o.sorting;
/**
* The current sorted column.
* @instance
* @type {FooTable.Column}
*/
this.column = null;
/* PRIVATE */
/**
* Sets a flag indicating whether or not the sorting has changed. When set to true the {@link FooTable.Sorting#sorting_changing} and {@link FooTable.Sorting#sorting_changed} events
* will be raised during the drawing operation.
* @private
* @type {boolean}
*/
this._changed = false;
},
/* PROTECTED */
/**
* Checks the supplied data and options for the sorting component.
* @instance
* @protected
* @param {object} data - The jQuery data object from the parent table.
* @fires FooTable.Sorting#"preinit.ft.sorting"
* @this FooTable.Sorting
*/
preinit: function(data){
var self = this;
/**
* The preinit.ft.sorting event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
* Calling preventDefault on this event will disable the component.
* @event FooTable.Sorting#"preinit.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {object} data - The jQuery data object of the table raising the event.
*/
this.ft.raise('preinit.ft.sorting', [data]).then(function(){
if (self.ft.$el.hasClass('footable-sorting'))
self.enabled = true;
self.enabled = F.is.boolean(data.sorting)
? data.sorting
: self.enabled;
if (!self.enabled) return;
self.column = F.arr.first(self.ft.columns.array, function(col){ return col.sorted; });
}, function(){
self.enabled = false;
});
},
/**
* Initializes the sorting component for the plugin using the supplied table and options.
* @instance
* @protected
* @fires FooTable.Sorting#"init.ft.sorting"
* @this FooTable.Sorting
*/
init: function () {
/**
* The init.ft.sorting event is raised before its UI is generated.
* Calling preventDefault on this event will disable the component.
* @event FooTable.Sorting#"init.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
var self = this;
this.ft.raise('init.ft.sorting').then(function(){
F.arr.each(self.ft.columns.array, function(col){
if (col.sortable){
col.$el.addClass('footable-sortable').append($('<span/>', {'class': 'fooicon fooicon-sort'}));
}
});
self.ft.$el.on('click.footable', '.footable-sortable', { self: self }, self._onSortClicked);
}, function(){
self.enabled = false;
});
},
/**
* Destroys the sorting component removing any UI generated from the table.
* @instance
* @protected
* @fires FooTable.Sorting#"destroy.ft.sorting"
*/
destroy: function () {
/**
* The destroy.ft.sorting event is raised before its UI is removed.
* Calling preventDefault on this event will prevent the component from being destroyed.
* @event FooTable.Sorting#"destroy.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
var self = this;
this.ft.raise('destroy.ft.paging').then(function(){
self.ft.$el.off('click.footable', '.footable-sortable', self._onSortClicked);
self.ft.$el.children('thead').children('tr.footable-header')
.children('.footable-sortable').removeClass('footable-sortable')
.find('span.fooicon').remove();
});
},
/**
* Performs the actual sorting against the {@link FooTable.Rows#current} array.
* @instance
* @protected
*/
predraw: function () {
if (!this.column) return;
var self = this, col = self.column;
//self.ft.rows.array.sort(function (a, b) {
// return col.direction == 'ASC'
// ? col.sorter(a.cells[col.index].value, b.cells[col.index].value)
// : col.sorter(b.cells[col.index].value, a.cells[col.index].value);
//});
self.ft.rows.array.sort(function (a, b) {
return col.direction == 'ASC'
? col.sorter(a.cells[col.index].sortValue, b.cells[col.index].sortValue)
: col.sorter(b.cells[col.index].sortValue, a.cells[col.index].sortValue);
});
},
/**
* Updates the sorting UI setting the state of the sort buttons.
* @instance
* @protected
*/
draw: function () {
if (!this.column) return;
var self = this,
$sortable = self.ft.$el.find('thead > tr > .footable-sortable'),
$active = self.column.$el;
$sortable.removeClass('footable-asc footable-desc').children('.fooicon').removeClass('fooicon-sort fooicon-sort-asc fooicon-sort-desc');
$sortable.not($active).children('.fooicon').addClass('fooicon-sort');
$active.addClass(self.column.direction == 'ASC' ? 'footable-asc' : 'footable-desc')
.children('.fooicon').addClass(self.column.direction == 'ASC' ? 'fooicon-sort-asc' : 'fooicon-sort-desc');
},
/* PUBLIC */
/**
* Sets the sorting options and calls the {@link FooTable.Table#draw} method to perform the actual sorting.
* @instance
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
* @returns {jQuery.Promise}
* @fires FooTable.Sorting#"before.ft.sorting"
* @fires FooTable.Sorting#"after.ft.sorting"
*/
sort: function(column, direction){
return this._sort(column, direction);
},
/* PRIVATE */
/**
* Performs the required steps to handle sorting including the raising of the {@link FooTable.Sorting#"before.ft.sorting"} and {@link FooTable.Sorting#"after.ft.sorting"} events.
* @instance
* @private
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
* @returns {jQuery.Promise}
* @fires FooTable.Sorting#"before.ft.sorting"
* @fires FooTable.Sorting#"after.ft.sorting"
*/
_sort: function(column, direction){
var self = this;
var sorter = new F.Sorter(self.ft.columns.get(column), F.Sorting.dir(direction));
/**
* The before.ft.sorting event is raised before a sort is applied and allows listeners to modify the sorter or cancel it completely by calling preventDefault on the jQuery.Event object.
* @event FooTable.Sorting#"before.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {FooTable.Sorter} sorter - The sorter that is about to be applied.
*/
return self.ft.raise('before.ft.sorting', [sorter]).then(function(){
F.arr.each(self.ft.columns.array, function(col){
if (col != self.column) col.direction = null;
});
self.column = self.ft.columns.get(sorter.column);
if (self.column) self.column.direction = F.Sorting.dir(sorter.direction);
return self.ft.draw().then(function(){
/**
* The after.ft.sorting event is raised after a sorter has been applied.
* @event FooTable.Sorting#"after.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {FooTable.Sorter} sorter - The sorter that has been applied.
*/
self.ft.raise('after.ft.sorting', [sorter]);
});
});
},
/**
* Handles the sort button clicked event.
* @instance
* @private
* @param {jQuery.Event} e - The event object for the event.
*/
_onSortClicked: function (e) {
e.preventDefault();
var self = e.data.self, $header = $(this).closest('th,td'),
direction = $header.is('.footable-asc, .footable-desc')
? ($header.hasClass('footable-desc') ? 'ASC' : 'DESC')
: 'ASC';
self._sort($header.index(), direction);
}
});
/**
* Checks the supplied string is a valid direction and if not returns ASC as default.
* @static
* @protected
* @param {string} str - The string to check.
*/
F.Sorting.dir = function(str){
return F.is.string(str) && (str == 'ASC' || str == 'DESC') ? str : 'ASC';
};
F.components.core.register('sorting', F.Sorting, 5);
})(jQuery, FooTable);
(function(F){
/**
* The value used by the sorting component during sort operations. Can be set using the data-sort-value attribute on the cell itself.
* If this is not supplied it is set to the result of the toString method called on the value for the cell. Added by the {@link FooTable.Sorting} component.
* @type {string}
* @default null
*/
F.Cell.prototype.sortValue = null;
// this is used to define the sorting specific properties on cell creation
F.Cell.prototype.__sorting_define__ = function(valueOrElement){
this.sortValue = this.column.sortValue.call(this.column, valueOrElement);
};
// this is used to update the sortValue property whenever the cell value is changed
F.Cell.prototype.__sorting_val__ = function(value){
if (F.is.defined(value)){
// set only
this.sortValue = this.column.sortValue.call(this.column, value);
}
};
// overrides the public define method and replaces it with our own
F.Cell.extend('define', function(valueOrElement){
this._super(valueOrElement);
this.__sorting_define__(valueOrElement);
});
// overrides the public val method and replaces it with our own
F.Cell.extend('val', function(value){
var val = this._super(value);
this.__sorting_val__(value);
return val;
});
})(FooTable);
(function($, F){
/**
* The direction to sort if the {@link FooTable.Column#sorted} property is set to true. Can be "ASC", "DESC" or NULL. Added by the {@link FooTable.Sorting} component.
* @type {string}
* @default null
*/
F.Column.prototype.direction = null;
/**
* Whether or not the column can be sorted. Added by the {@link FooTable.Sorting} component.
* @type {boolean}
* @default true
*/
F.Column.prototype.sortable = true;
/**
* Whether or not the column is sorted. Added by the {@link FooTable.Sorting} component.
* @type {boolean}
* @default false
*/
F.Column.prototype.sorted = false;
/**
* This is supplied two values from the column for a comparison to be made and the result returned. Added by the {@link FooTable.Sorting} component.
* @param {*} a - The first value to be compared.
* @param {*} b - The second value to compare to the first.
* @returns {number}
* @example <caption>This example shows using pseudo code what a sort function would look like.</caption>
* "sorter": function(a, b){
* if (a is less than b by some ordering criterion) {
* return -1;
* }
* if (a is greater than b by the ordering criterion) {
* return 1;
* }
* // a must be equal to b
* return 0;
* }
*/
F.Column.prototype.sorter = function(a, b){
if (typeof a === 'string') a = a.toLowerCase();
if (typeof b === 'string') b = b.toLowerCase();
if (a === b) return 0;
if (a < b) return -1;
return 1;
};
/**
* This is supplied either the cell value or jQuery object to parse. A value must be returned from this method and will be used during sorting operations.
* @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
* @returns {*}
* @this FooTable.Column
*/
F.Column.prototype.sortValue = function(valueOrElement){
// if we have an element or a jQuery object use jQuery to get the value
if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)) return $(valueOrElement).data('sortValue') || this.parser(valueOrElement);
// if options are supplied with the value
if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
if (F.is.string(valueOrElement.options.sortValue)) return valueOrElement.options.sortValue;
if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
}
if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement;
return null;
};
// this is used to define the sorting specific properties on column creation
F.Column.prototype.__sorting_define__ = function(definition){
this.sorter = F.checkFnValue(this, definition.sorter, this.sorter);
this.direction = F.is.type(definition.direction, 'string') ? F.Sorting.dir(definition.direction) : null;
this.sortable = F.is.boolean(definition.sortable) ? definition.sortable : true;
this.sorted = F.is.boolean(definition.sorted) ? definition.sorted : false;
};
// overrides the public define method and replaces it with our own
F.Column.extend('define', function(definition){
this._super(definition);
this.__sorting_define__(definition);
});
})(jQuery, FooTable);
(function(F){
/**
* An object containing the sorting options for the plugin. Added by the {@link FooTable.Sorting} component.
* @type {object}
* @prop {boolean} enabled=false - Whether or not to allow sorting on the table.
*/
F.Defaults.prototype.sorting = {
enabled: false
};
})(FooTable);
(function($, F){
F.HTMLColumn.extend('__sorting_define__', function(definition){
this._super(definition);
this.sortUse = F.is.string(definition.sortUse) && $.inArray(definition.sortUse, ['html','text']) !== -1 ? definition.sortUse : 'html';
});
/**
* This is supplied either the cell value or jQuery object to parse. A value must be returned from this method and will be used during sorting operations.
* @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
* @returns {*}
* @this FooTable.HTMLColumn
*/
F.HTMLColumn.prototype.sortValue = function(valueOrElement){
// if we have an element or a jQuery object use jQuery to get the data value or pass it off to the parser
if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)){
return $(valueOrElement).data('sortValue') || $.trim($(valueOrElement)[this.sortUse]());
}
// if options are supplied with the value
if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
if (F.is.string(valueOrElement.options.sortValue)) return valueOrElement.options.sortValue;
if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
}
if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement;
return null;
};
})(jQuery, FooTable);
(function(F){
/**
* Sort the table using the specified column and direction. Added by the {@link FooTable.Sorting} component.
* @instance
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
* @returns {jQuery.Promise}
* @fires FooTable.Sorting#"change.ft.sorting"
* @fires FooTable.Sorting#"changed.ft.sorting"
* @see FooTable.Sorting#sort
*/
F.Table.prototype.sort = function(column, direction){
return this.use(F.Sorting).sort(column, direction);
};
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
(function($, F){
F.Sorter = F.Class.extend(/** @lends FooTable.Sorter */{
/**
* The sorter object contains the column and direction to sort by.
* @constructs
* @extends FooTable.Class
* @param {FooTable.Column} column - The column to sort.
* @param {string} direction - The direction to sort by.
* @returns {FooTable.Sorter}
*/
construct: function(column, direction){
/**
* The column to sort.
* @type {FooTable.Column}
*/
this.column = column;
/**
* The direction to sort by.
* @type {string}
*/
this.direction = direction;
}
});
})(jQuery, FooTable);
(function ($, F) {
F.Sorting = F.Component.extend(/** @lends FooTable.Sorting */{
/**
* The sorting component adds a small sort button to specified column headers allowing users to sort those columns in the table.
* @constructs
* @extends FooTable.Component
* @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
* @returns {FooTable.Sorting}
*/
construct: function (table) {
// call the constructor of the base class
this._super(table, table.o.sorting.enabled);
/* PROTECTED */
/**
* This provides a shortcut to the {@link FooTable.Table#options}.[sorting]{@link FooTable.Defaults#sorting} object.
* @instance
* @protected
* @type {object}
*/
this.o = table.o.sorting;
/**
* The current sorted column.
* @instance
* @type {FooTable.Column}
*/
this.column = null;
/**
* Whether or not to allow sorting to occur, should be set using the {@link FooTable.Sorting#toggleAllowed} method.
* @instance
* @type {boolean}
*/
this.allowed = true;
/**
* The initial sort state of the table, this value is used for determining if the sorting has occurred or to reset the state to default.
* @instance
* @type {{isset: boolean, rows: Array.<FooTable.Row>, column: string, direction: ?string}}
*/
this.initial = null;
},
/* PROTECTED */
/**
* Checks the supplied data and options for the sorting component.
* @instance
* @protected
* @param {object} data - The jQuery data object from the parent table.
* @fires FooTable.Sorting#"preinit.ft.sorting"
* @this FooTable.Sorting
*/
preinit: function(data){
var self = this;
/**
* The preinit.ft.sorting event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
* Calling preventDefault on this event will disable the component.
* @event FooTable.Sorting#"preinit.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {object} data - The jQuery data object of the table raising the event.
*/
this.ft.raise('preinit.ft.sorting', [data]).then(function(){
if (self.ft.$el.hasClass('footable-sorting'))
self.enabled = true;
self.enabled = F.is.boolean(data.sorting)
? data.sorting
: self.enabled;
if (!self.enabled) return;
self.column = F.arr.first(self.ft.columns.array, function(col){ return col.sorted; });
}, function(){
self.enabled = false;
});
},
/**
* Initializes the sorting component for the plugin using the supplied table and options.
* @instance
* @protected
* @fires FooTable.Sorting#"init.ft.sorting"
* @this FooTable.Sorting
*/
init: function () {
/**
* The init.ft.sorting event is raised before its UI is generated.
* Calling preventDefault on this event will disable the component.
* @event FooTable.Sorting#"init.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
var self = this;
this.ft.raise('init.ft.sorting').then(function(){
if (!self.initial){
var isset = !!self.column;
self.initial = {
isset: isset,
// grab a shallow copy of the rows array prior to sorting - allows us to reset without an initial sort
rows: self.ft.rows.all.slice(0),
// if there is a sorted column store its name and direction
column: isset ? self.column.name : null,
direction: isset ? self.column.direction : null
}
}
F.arr.each(self.ft.columns.array, function(col){
if (col.sortable){
col.$el.addClass('footable-sortable').append($('<span/>', {'class': 'fooicon fooicon-sort'}));
}
});
self.ft.$el.on('click.footable', '.footable-sortable', { self: self }, self._onSortClicked);
}, function(){
self.enabled = false;
});
},
/**
* Destroys the sorting component removing any UI generated from the table.
* @instance
* @protected
* @fires FooTable.Sorting#"destroy.ft.sorting"
*/
destroy: function () {
/**
* The destroy.ft.sorting event is raised before its UI is removed.
* Calling preventDefault on this event will prevent the component from being destroyed.
* @event FooTable.Sorting#"destroy.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
*/
var self = this;
this.ft.raise('destroy.ft.paging').then(function(){
self.ft.$el.off('click.footable', '.footable-sortable', self._onSortClicked);
self.ft.$el.children('thead').children('tr.footable-header')
.children('.footable-sortable').removeClass('footable-sortable footable-asc footable-desc')
.find('span.fooicon').remove();
});
},
/**
* Performs the actual sorting against the {@link FooTable.Rows#current} array.
* @instance
* @protected
*/
predraw: function () {
if (!this.column) return;
var self = this, col = self.column;
self.ft.rows.array.sort(function (a, b) {
return col.direction == 'DESC'
? col.sorter(b.cells[col.index].sortValue, a.cells[col.index].sortValue)
: col.sorter(a.cells[col.index].sortValue, b.cells[col.index].sortValue);
});
},
/**
* Updates the sorting UI setting the state of the sort buttons.
* @instance
* @protected
*/
draw: function () {
if (!this.column) return;
var self = this,
$sortable = self.ft.$el.find('thead > tr > .footable-sortable'),
$active = self.column.$el;
$sortable.removeClass('footable-asc footable-desc').children('.fooicon').removeClass('fooicon-sort fooicon-sort-asc fooicon-sort-desc');
$sortable.not($active).children('.fooicon').addClass('fooicon-sort');
$active.addClass(self.column.direction == 'DESC' ? 'footable-desc' : 'footable-asc')
.children('.fooicon').addClass(self.column.direction == 'DESC' ? 'fooicon-sort-desc' : 'fooicon-sort-asc');
},
/* PUBLIC */
/**
* Sets the sorting options and calls the {@link FooTable.Table#draw} method to perform the actual sorting.
* @instance
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
* @returns {jQuery.Promise}
* @fires FooTable.Sorting#"before.ft.sorting"
* @fires FooTable.Sorting#"after.ft.sorting"
*/
sort: function(column, direction){
return this._sort(column, direction);
},
/**
* Toggles whether or not sorting is currently allowed.
* @param {boolean} [state] - You can optionally specify the state you want it to be, if not supplied the current value is flipped.
*/
toggleAllowed: function(state){
state = F.is.boolean(state) ? state : !this.allowed;
this.allowed = state;
this.ft.$el.toggleClass('footable-sorting-disabled', !this.allowed);
},
/**
* Checks whether any sorting has occurred for the table.
* @returns {boolean}
*/
hasChanged: function(){
return !(!this.initial || !this.column ||
(this.column.name === this.initial.column &&
(this.column.direction === this.initial.direction || (this.initial.direction === null && this.column.direction === 'ASC')))
);
},
/**
* Resets the table sorting to the initial state recorded in the components init method.
*/
reset: function(){
if (!!this.initial){
if (this.initial.isset){
// if the initial value specified a column, sort by it
this.sort(this.initial.column, this.initial.direction);
} else {
// if there was no initial column then we need to reset the rows to there original order
if (!!this.column){
// if there is a currently sorted column remove the asc/desc classes and set it to null.
this.column.$el.removeClass('footable-asc footable-desc');
this.column = null;
}
// replace the current all rows array with the one stored in the initial value
this.ft.rows.all = this.initial.rows;
// force the table to redraw itself using the updated rows array
this.ft.draw();
}
}
},
/* PRIVATE */
/**
* Performs the required steps to handle sorting including the raising of the {@link FooTable.Sorting#"before.ft.sorting"} and {@link FooTable.Sorting#"after.ft.sorting"} events.
* @instance
* @private
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
* @returns {jQuery.Promise}
* @fires FooTable.Sorting#"before.ft.sorting"
* @fires FooTable.Sorting#"after.ft.sorting"
*/
_sort: function(column, direction){
if (!this.allowed) return $.Deferred().reject('sorting disabled');
var self = this;
var sorter = new F.Sorter(self.ft.columns.get(column), F.Sorting.dir(direction));
/**
* The before.ft.sorting event is raised before a sort is applied and allows listeners to modify the sorter or cancel it completely by calling preventDefault on the jQuery.Event object.
* @event FooTable.Sorting#"before.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {FooTable.Sorter} sorter - The sorter that is about to be applied.
*/
return self.ft.raise('before.ft.sorting', [sorter]).then(function(){
F.arr.each(self.ft.columns.array, function(col){
if (col != self.column) col.direction = null;
});
self.column = self.ft.columns.get(sorter.column);
if (self.column) self.column.direction = F.Sorting.dir(sorter.direction);
return self.ft.draw().then(function(){
/**
* The after.ft.sorting event is raised after a sorter has been applied.
* @event FooTable.Sorting#"after.ft.sorting"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {FooTable.Sorter} sorter - The sorter that has been applied.
*/
self.ft.raise('after.ft.sorting', [sorter]);
});
});
},
/**
* Handles the sort button clicked event.
* @instance
* @private
* @param {jQuery.Event} e - The event object for the event.
*/
_onSortClicked: function (e) {
var self = e.data.self, $header = $(this).closest('th,td'),
direction = $header.is('.footable-asc, .footable-desc')
? ($header.hasClass('footable-desc') ? 'ASC' : 'DESC')
: 'ASC';
self._sort($header.index(), direction);
}
});
/**
* Checks the supplied string is a valid direction and if not returns ASC as default.
* @static
* @protected
* @param {string} str - The string to check.
*/
F.Sorting.dir = function(str){
return F.is.string(str) && (str == 'ASC' || str == 'DESC') ? str : 'ASC';
};
F.components.register('sorting', F.Sorting, 600);
})(jQuery, FooTable);
(function(F){
/**
* The value used by the sorting component during sort operations. Can be set using the data-sort-value attribute on the cell itself.
* If this is not supplied it is set to the result of the toString method called on the value for the cell. Added by the {@link FooTable.Sorting} component.
* @type {string}
* @default null
*/
F.Cell.prototype.sortValue = null;
// this is used to define the sorting specific properties on cell creation
F.Cell.prototype.__sorting_define__ = function(valueOrElement){
this.sortValue = this.column.sortValue.call(this.column, valueOrElement);
};
// this is used to update the sortValue property whenever the cell value is changed
F.Cell.prototype.__sorting_val__ = function(value){
if (F.is.defined(value)){
// set only
this.sortValue = this.column.sortValue.call(this.column, value);
}
};
// overrides the public define method and replaces it with our own
F.Cell.extend('define', function(valueOrElement){
this._super(valueOrElement);
this.__sorting_define__(valueOrElement);
});
// overrides the public val method and replaces it with our own
F.Cell.extend('val', function(value){
var val = this._super(value);
this.__sorting_val__(value);
return val;
});
})(FooTable);
(function($, F){
/**
* The direction to sort if the {@link FooTable.Column#sorted} property is set to true. Can be "ASC", "DESC" or NULL. Added by the {@link FooTable.Sorting} component.
* @type {string}
* @default null
*/
F.Column.prototype.direction = null;
/**
* Whether or not the column can be sorted. Added by the {@link FooTable.Sorting} component.
* @type {boolean}
* @default true
*/
F.Column.prototype.sortable = true;
/**
* Whether or not the column is sorted. Added by the {@link FooTable.Sorting} component.
* @type {boolean}
* @default false
*/
F.Column.prototype.sorted = false;
/**
* This is supplied two values from the column for a comparison to be made and the result returned. Added by the {@link FooTable.Sorting} component.
* @param {*} a - The first value to be compared.
* @param {*} b - The second value to compare to the first.
* @returns {number}
* @example <caption>This example shows using pseudo code what a sort function would look like.</caption>
* "sorter": function(a, b){
* if (a is less than b by some ordering criterion) {
* return -1;
* }
* if (a is greater than b by the ordering criterion) {
* return 1;
* }
* // a must be equal to b
* return 0;
* }
*/
F.Column.prototype.sorter = function(a, b){
if (typeof a === 'string') a = a.toLowerCase();
if (typeof b === 'string') b = b.toLowerCase();
if (a === b) return 0;
if (a < b) return -1;
return 1;
};
/**
* This is supplied either the cell value or jQuery object to parse. A value must be returned from this method and will be used during sorting operations.
* @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
* @returns {*}
* @this FooTable.Column
*/
F.Column.prototype.sortValue = function(valueOrElement){
// if we have an element or a jQuery object use jQuery to get the value
if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)){
var data = $(valueOrElement).data('sortValue');
return F.is.defined(data) ? data : this.parser(valueOrElement);
}
// if options are supplied with the value
if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
if (F.is.string(valueOrElement.options.sortValue)) return valueOrElement.options.sortValue;
if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
}
if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement;
return null;
};
// this is used to define the sorting specific properties on column creation
F.Column.prototype.__sorting_define__ = function(definition){
this.sorter = F.checkFnValue(this, definition.sorter, this.sorter);
this.direction = F.is.type(definition.direction, 'string') ? F.Sorting.dir(definition.direction) : null;
this.sortable = F.is.boolean(definition.sortable) ? definition.sortable : true;
this.sorted = F.is.boolean(definition.sorted) ? definition.sorted : false;
this.sortValue = F.checkFnValue(this, definition.sortValue, this.sortValue);
};
// overrides the public define method and replaces it with our own
F.Column.extend('define', function(definition){
this._super(definition);
this.__sorting_define__(definition);
});
})(jQuery, FooTable);
(function(F){
/**
* An object containing the sorting options for the plugin. Added by the {@link FooTable.Sorting} component.
* @type {object}
* @prop {boolean} enabled=false - Whether or not to allow sorting on the table.
*/
F.Defaults.prototype.sorting = {
enabled: false
};
})(FooTable);
(function($, F){
F.HTMLColumn.extend('__sorting_define__', function(definition){
this._super(definition);
this.sortUse = F.is.string(definition.sortUse) && $.inArray(definition.sortUse, ['html','text']) !== -1 ? definition.sortUse : 'html';
});
/**
* This is supplied either the cell value or jQuery object to parse. A value must be returned from this method and will be used during sorting operations.
* @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
* @returns {*}
* @this FooTable.HTMLColumn
*/
F.HTMLColumn.prototype.sortValue = function(valueOrElement){
// if we have an element or a jQuery object use jQuery to get the data value or pass it off to the parser
if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)){
var data = $(valueOrElement).data('sortValue');
return F.is.defined(data) ? data : $.trim($(valueOrElement)[this.sortUse]());
}
// if options are supplied with the value
if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
if (F.is.string(valueOrElement.options.sortValue)) return valueOrElement.options.sortValue;
if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
}
if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement;
return null;
};
})(jQuery, FooTable);
(function(F){
/**
* Sort the table using the specified column and direction. Added by the {@link FooTable.Sorting} component.
* @instance
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
* @returns {jQuery.Promise}
* @fires FooTable.Sorting#"change.ft.sorting"
* @fires FooTable.Sorting#"changed.ft.sorting"
* @see FooTable.Sorting#sort
*/
F.Table.prototype.sort = function(column, direction){
return this.use(F.Sorting).sort(column, direction);
};
})(FooTable);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,362 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
(function($, F){
// global int to use if the table has no ID
var _uid = 0,
// a hash value for the current url
_url_hash = (function(str){
var i, l, hval = 0x811c9dc5;
for (i = 0, l = str.length; i < l; i++) {
hval ^= str.charCodeAt(i);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
return hval >>> 0;
})(location.origin + location.pathname);
F.State = F.Component.extend(/** @lends FooTable.State */{
/**
* The state component adds the ability for the table to remember its basic state for filtering, paging and sorting.
* @constructs
* @extends FooTable.Component
* @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
* @returns {FooTable.State}
*/
construct: function(table){
// call the constructor of the base class
this._super(table, table.o.state.enabled);
// Change this value if an update to this component requires any stored data to be reset
this._key = '1';
/**
* The key to use to store the state for this table.
* @type {(null|string)}
*/
this.key = this._key + (F.is.string(table.o.state.key) ? table.o.state.key : this._uid());
/**
* Whether or not to allow the filtering component to store it's state.
* @type {boolean}
*/
this.filtering = F.is.boolean(table.o.state.filtering) ? table.o.state.filtering : true;
/**
* Whether or not to allow the paging component to store it's state.
* @type {boolean}
*/
this.paging = F.is.boolean(table.o.state.paging) ? table.o.state.paging : true;
/**
* Whether or not to allow the sorting component to store it's state.
* @type {boolean}
*/
this.sorting = F.is.boolean(table.o.state.sorting) ? table.o.state.sorting : true;
},
/* PROTECTED */
/**
* Checks the supplied data and options for the state component.
* @instance
* @protected
* @param {object} data - The jQuery data object from the parent table.
* @fires FooTable.State#"preinit.ft.state"
* @this FooTable.State
*/
preinit: function(data){
var self = this;
/**
* The preinit.ft.state event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
* Calling preventDefault on this event will disable the component.
* @event FooTable.State#"preinit.ft.state"
* @param {jQuery.Event} e - The jQuery.Event object for the event.
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
* @param {object} data - The jQuery data object of the table raising the event.
*/
this.ft.raise('preinit.ft.state', [data]).then(function(){
self.enabled = F.is.boolean(data.state)
? data.state
: self.enabled;
if (!self.enabled) return;
self.key = self._key + (F.is.string(data.stateKey) ? data.stateKey : self.key);
self.filtering = F.is.boolean(data.stateFiltering) ? data.stateFiltering : self.filtering;
self.paging = F.is.boolean(data.statePaging) ? data.statePaging : self.paging;
self.sorting = F.is.boolean(data.stateSorting) ? data.stateSorting : self.sorting;
}, function(){
self.enabled = false;
});
},
/**
* Gets the state value for the specified key for this table.
* @instance
* @param {string} key - The key to get the value for.
* @returns {(*|null)}
*/
get: function(key){
return JSON.parse(localStorage.getItem(this.key + ':' + key));
},
/**
* Sets the state value for the specified key for this table.
* @instance
* @param {string} key - The key to set the value for.
* @param {*} data - The value to store for the key. This value must be JSON.stringify friendly.
*/
set: function(key, data){
localStorage.setItem(this.key + ':' + key, JSON.stringify(data));
},
/**
* Clears the state value for the specified key for this table.
* @instance
* @param {string} key - The key to clear the value for.
*/
remove: function(key){
localStorage.removeItem(this.key + ':' + key);
},
/**
* Executes the {@link FooTable.Component#readState} function on all components.
* @instance
*/
read: function(){
this.ft.execute(false, true, 'readState');
},
/**
* Executes the {@link FooTable.Component#writeState} function on all components.
* @instance
*/
write: function(){
this.ft.execute(false, true, 'writeState');
},
/**
* Executes the {@link FooTable.Component#clearState} function on all components.
* @instance
*/
clear: function(){
this.ft.execute(false, true, 'clearState');
},
/**
* Generates a unique identifier for the current {@link FooTable.Table} if one is not supplied through the options.
* This value is a combination of the url hash and either the element ID or an incremented global int value.
* @instance
* @returns {*}
* @private
*/
_uid: function(){
var id = this.ft.$el.attr('id');
return _url_hash + '_' + (F.is.string(id) ? id : ++_uid);
}
});
F.components.register('state', F.State, 700);
})(jQuery, FooTable);
(function(F){
/**
* This method is called from the {@link FooTable.State#read} method and allows a component to retrieve its' stored state.
* @instance
* @protected
* @function
*/
F.Component.prototype.readState = function(){};
/**
* This method is called from the {@link FooTable.State#write} method and allows a component to write its' current state to the store.
* @instance
* @protected
* @function
*/
F.Component.prototype.writeState = function(){};
/**
* This method is called from the {@link FooTable.State#clear} method and allows a component to clear any stored state.
* @instance
* @protected
* @function
*/
F.Component.prototype.clearState = function(){};
})(FooTable);
(function(F){
/**
* An object containing the state options for the plugin. Added by the {@link FooTable.State} component.
* @type {object}
* @prop {boolean} enabled=false - Whether or not to allow state to be stored for the table. This overrides the individual component enable options.
* @prop {boolean} filtering=true - Whether or not to allow the filtering state to be stored.
* @prop {boolean} paging=true - Whether or not to allow the filtering state to be stored.
* @prop {boolean} sorting=true - Whether or not to allow the filtering state to be stored.
* @prop {string} key=null - The unique key to use to store the table's data.
*/
F.Defaults.prototype.state = {
enabled: false,
filtering: true,
paging: true,
sorting: true,
key: null
};
})(FooTable);
(function(F){
if (!F.Filtering) return;
/**
* Allows the filtering component to retrieve its' stored state.
*/
F.Filtering.prototype.readState = function(){
if (this.ft.state.filtering){
var state = this.ft.state.get('filtering');
if (F.is.hash(state) && !F.is.emptyArray(state.filters)){
this.filters = this.ensure(state.filters);
}
}
};
/**
* Allows the filtering component to write its' current state to the store.
*/
F.Filtering.prototype.writeState = function(){
if (this.ft.state.filtering) {
var filters = F.arr.map(this.filters, function (f) {
return {
name: f.name,
query: f.query instanceof F.Query ? f.query.val() : f.query,
columns: F.arr.map(f.columns, function (c) {
return c.name;
}),
hidden: f.hidden,
space: f.space,
connectors: f.connectors,
ignoreCase: f.ignoreCase
};
});
this.ft.state.set('filtering', {filters: filters});
}
};
/**
* Allows the filtering component to clear any stored state.
*/
F.Filtering.prototype.clearState = function(){
if (this.ft.state.filtering) {
this.ft.state.remove('filtering');
}
};
})(FooTable);
(function(F){
if (!F.Paging) return;
/**
* Allows the paging component to retrieve its' stored state.
*/
F.Paging.prototype.readState = function(){
if (this.ft.state.paging) {
var state = this.ft.state.get('paging');
if (F.is.hash(state)) {
this.current = state.current;
this.size = state.size;
}
}
};
/**
* Allows the paging component to write its' current state to the store.
*/
F.Paging.prototype.writeState = function(){
if (this.ft.state.paging) {
this.ft.state.set('paging', {
current: this.current,
size: this.size
});
}
};
/**
* Allows the paging component to clear any stored state.
*/
F.Paging.prototype.clearState = function(){
if (this.ft.state.paging) {
this.ft.state.remove('paging');
}
};
})(FooTable);
(function(F){
if (!F.Sorting) return;
/**
* Allows the sorting component to retrieve its' stored state.
*/
F.Sorting.prototype.readState = function(){
if (this.ft.state.sorting) {
var state = this.ft.state.get('sorting');
if (F.is.hash(state)) {
var column = this.ft.columns.get(state.column);
if (column instanceof F.Column) {
this.column = column;
this.column.direction = state.direction;
}
}
}
};
/**
* Allows the sorting component to write its' current state to the store.
*/
F.Sorting.prototype.writeState = function(){
if (this.ft.state.sorting && this.column instanceof F.Column){
this.ft.state.set('sorting', {
column: this.column.name,
direction: this.column.direction
});
}
};
/**
* Allows the sorting component to clear any stored state.
*/
F.Sorting.prototype.clearState = function(){
if (this.ft.state.sorting) {
this.ft.state.remove('sorting');
}
};
})(FooTable);
(function(F){
// hook into the _construct method so we can add the state property to the table.
F.Table.extend('_construct', function(ready){
this.state = this.use(FooTable.State);
this._super(ready);
});
// hook into the _preinit method so we can trigger a plugin wide read state operation.
F.Table.extend('_preinit', function(){
var self = this;
return self._super().then(function(){
if (self.state.enabled){
self.state.read();
}
});
});
// hook into the draw method so we can trigger a plugin wide write state operation.
F.Table.extend('draw', function(){
var self = this;
return self._super().then(function(){
if (self.state.enabled){
self.state.write();
}
});
});
})(FooTable);

View File

@ -0,0 +1,8 @@
/*
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
* @version 3.1.4
* @link http://fooplugins.com
* @copyright Steven Usher & Brad Vincent 2015
* @license Released under the GPLv3 license.
*/
!function(a,b){var c=0,d=function(a){var b,c,d=2166136261;for(b=0,c=a.length;c>b;b++)d^=a.charCodeAt(b),d+=(d<<1)+(d<<4)+(d<<7)+(d<<8)+(d<<24);return d>>>0}(location.origin+location.pathname);b.State=b.Component.extend({construct:function(a){this._super(a,a.o.state.enabled),this._key="1",this.key=this._key+(b.is.string(a.o.state.key)?a.o.state.key:this._uid()),this.filtering=b.is["boolean"](a.o.state.filtering)?a.o.state.filtering:!0,this.paging=b.is["boolean"](a.o.state.paging)?a.o.state.paging:!0,this.sorting=b.is["boolean"](a.o.state.sorting)?a.o.state.sorting:!0},preinit:function(a){var c=this;this.ft.raise("preinit.ft.state",[a]).then(function(){c.enabled=b.is["boolean"](a.state)?a.state:c.enabled,c.enabled&&(c.key=c._key+(b.is.string(a.stateKey)?a.stateKey:c.key),c.filtering=b.is["boolean"](a.stateFiltering)?a.stateFiltering:c.filtering,c.paging=b.is["boolean"](a.statePaging)?a.statePaging:c.paging,c.sorting=b.is["boolean"](a.stateSorting)?a.stateSorting:c.sorting)},function(){c.enabled=!1})},get:function(a){return JSON.parse(localStorage.getItem(this.key+":"+a))},set:function(a,b){localStorage.setItem(this.key+":"+a,JSON.stringify(b))},remove:function(a){localStorage.removeItem(this.key+":"+a)},read:function(){this.ft.execute(!1,!0,"readState")},write:function(){this.ft.execute(!1,!0,"writeState")},clear:function(){this.ft.execute(!1,!0,"clearState")},_uid:function(){var a=this.ft.$el.attr("id");return d+"_"+(b.is.string(a)?a:++c)}}),b.components.register("state",b.State,700)}(jQuery,FooTable),function(a){a.Component.prototype.readState=function(){},a.Component.prototype.writeState=function(){},a.Component.prototype.clearState=function(){}}(FooTable),function(a){a.Defaults.prototype.state={enabled:!1,filtering:!0,paging:!0,sorting:!0,key:null}}(FooTable),function(a){a.Filtering&&(a.Filtering.prototype.readState=function(){if(this.ft.state.filtering){var b=this.ft.state.get("filtering");a.is.hash(b)&&!a.is.emptyArray(b.filters)&&(this.filters=this.ensure(b.filters))}},a.Filtering.prototype.writeState=function(){if(this.ft.state.filtering){var b=a.arr.map(this.filters,function(b){return{name:b.name,query:b.query instanceof a.Query?b.query.val():b.query,columns:a.arr.map(b.columns,function(a){return a.name}),hidden:b.hidden,space:b.space,connectors:b.connectors,ignoreCase:b.ignoreCase}});this.ft.state.set("filtering",{filters:b})}},a.Filtering.prototype.clearState=function(){this.ft.state.filtering&&this.ft.state.remove("filtering")})}(FooTable),function(a){a.Paging&&(a.Paging.prototype.readState=function(){if(this.ft.state.paging){var b=this.ft.state.get("paging");a.is.hash(b)&&(this.current=b.current,this.size=b.size)}},a.Paging.prototype.writeState=function(){this.ft.state.paging&&this.ft.state.set("paging",{current:this.current,size:this.size})},a.Paging.prototype.clearState=function(){this.ft.state.paging&&this.ft.state.remove("paging")})}(FooTable),function(a){a.Sorting&&(a.Sorting.prototype.readState=function(){if(this.ft.state.sorting){var b=this.ft.state.get("sorting");if(a.is.hash(b)){var c=this.ft.columns.get(b.column);c instanceof a.Column&&(this.column=c,this.column.direction=b.direction)}}},a.Sorting.prototype.writeState=function(){this.ft.state.sorting&&this.column instanceof a.Column&&this.ft.state.set("sorting",{column:this.column.name,direction:this.column.direction})},a.Sorting.prototype.clearState=function(){this.ft.state.sorting&&this.ft.state.remove("sorting")})}(FooTable),function(a){a.Table.extend("_construct",function(a){this.state=this.use(FooTable.State),this._super(a)}),a.Table.extend("_preinit",function(){var a=this;return a._super().then(function(){a.state.enabled&&a.state.read()})}),a.Table.extend("draw",function(){var a=this;return a._super().then(function(){a.state.enabled&&a.state.write()})})}(FooTable);

View File

@ -10,7 +10,7 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.2.0
@version 2.3.0
@created 30th April, 2015
@package Component Builder
@subpackage compiler.php
@ -41,17 +41,29 @@ class Compiler extends Infusion
*/
private $tempPath;
/*
* The timer
*
* @var string
*/
private $time_start;
private $time_end;
public $secondsCompiled;
public $filepath = '';
// fixed pathes
protected $dynamicIntegration = false;
protected $backupPath = false;
protected $gitPath = false;
protected $addCustomCodeAt = array();
/**
* Constructor
*/
public function __construct($config = array ())
{
// to check the compiler speed
$this->time_start = microtime(true);
// first we run the perent constructor
if (parent::__construct($config))
{
@ -86,36 +98,29 @@ class Compiler extends Infusion
{
return false;
}
// we can remove all undeeded data
$this->freeMemory();
// check if this component is install on the current website
if ($paths = $this->getLocalInstallPaths())
{
// start Automatic import of custom code
$userId = JFactory::getUser()->id;
$today = JFactory::getDate()->toSql();
// Get a db connection.
$db = JFactory::getDbo();
// get the custom code from installed files
$this->customCodeFactory($paths, $db, $userId, $today);
}
// check if we have custom code to add
$this->getCustomCode();
// now insert into the new files
if (ComponentbuilderHelper::checkArray($this->customCode))
{
// load error messages incase code can not be added
$app = JFactory::getApplication();
$this->addCustomCode($app);
if ($this->getCustomCode())
{
$this->addCustomCode();
}
// set the lang data now
$this->setLangFileData();
// move the update server into place
$this->setUpdateServer();
// set the global counters
$this->setCountingStuff();
// build read me
$this->buildReadMe();
// zip the component
if (!$this->zipComponent())
{
// done
// done with error
return false;
}
// end the timer here
$this->time_end = microtime(true);
$this->secondsCompiled = $this->time_end - $this->time_start;
// completed the compilation
return true;
}
return false;
@ -147,7 +152,9 @@ class Compiler extends Infusion
protected function updateFiles()
{
if (isset($this->newFiles['static']) && ComponentbuilderHelper::checkArray($this->newFiles['static']) && isset($this->newFiles['dynamic']) && ComponentbuilderHelper::checkArray($this->newFiles['dynamic']))
{
{
// we don't update lang now since we will still posible add custom code
$langCheck = 'en-GB.com_'.$this->fileContentStatic['###component###'].'.';
// get the bom file
$bom = JFile::read($this->bomPath);
// first we do the static files
@ -155,6 +162,12 @@ class Compiler extends Infusion
{
if (JFile::exists($static['path']))
{
// skip lang files and store for later
if (strpos($static['path'], $langCheck))
{
$this->langFiles[] = $static;
continue;
}
$this->fileContentStatic['###FILENAME###'] = $static['name'];
$php = '';
if (ComponentbuilderHelper::checkFileType($static['name'],'php'))
@ -165,13 +178,14 @@ class Compiler extends Infusion
if (strpos($string,'###BOM###') !== false)
{
list($wast,$code) = explode('###BOM###',$string);
$answer = str_replace(array_keys($this->fileContentStatic),array_values($this->fileContentStatic),$php.$bom.$code);
$string = $php.$bom.$code;
$answer = $this->setPlaceholders($string, $this->fileContentStatic, 3);
// add to zip array
$this->writeFile($static['path'],$answer);
}
else
{
$answer = str_replace(array_keys($this->fileContentStatic),array_values($this->fileContentStatic),$string);
$answer = $this->setPlaceholders($string, $this->fileContentStatic, 3);
// add to zip array
$this->writeFile($static['path'],$answer);
}
@ -201,15 +215,16 @@ class Compiler extends Infusion
if (strpos($string,'###BOM###') !== false)
{
list($bin,$code) = explode('###BOM###',$string);
$answer = str_replace(array_keys($this->fileContentStatic),array_values($this->fileContentStatic),$php.$bom.$code);
$answer = str_replace(array_keys($this->fileContentDynamic[$view]),array_values($this->fileContentDynamic[$view]),$answer);
$string = $php.$bom.$code;
$answer = $this->setPlaceholders($string, $this->fileContentStatic, 3);
$answer = $this->setPlaceholders($answer, $this->fileContentDynamic[$view], 3);
// add to zip array
$this->writeFile($file['path'],$answer);
}
else
{
$answer = str_replace(array_keys($this->fileContentStatic),array_values($this->fileContentStatic),$string);
$answer = str_replace(array_keys($this->fileContentDynamic[$view]),array_values($this->fileContentDynamic[$view]),$answer);
$answer = $this->setPlaceholders($string, $this->fileContentStatic, 3);
$answer = $this->setPlaceholders($answer, $this->fileContentDynamic[$view], 3);
// add to zip array
$this->writeFile($file['path'],$answer);
}
@ -223,97 +238,11 @@ class Compiler extends Infusion
}
// free up some memory
unset($this->newFiles['dynamic']);
// do a final run to update the readme file
$two = 0;
foreach ($this->newFiles['static'] as $static)
{
if (('README.md' === $static['name'] || 'README.txt' === $static['name']) && $this->componentData->addreadme && JFile::exists($static['path']))
{
$this->buildReadMe($static['path']);
$two++;
}
if ($two == 2)
{
break;
}
}
return true;
}
return false;
}
protected function freeMemory()
{
// free up some memory
unset($this->newFiles['static']);
unset($this->customScriptBuilder);
unset($this->permissionCore);
unset($this->permissionDashboard);
unset($this->componentData->admin_views);
unset($this->componentData->site_views);
unset($this->componentData->custom_admin_views);
unset($this->componentData->config);
unset($this->joomlaVersionData);
unset($this->langContent);
unset($this->dbKeys);
unset($this->permissionBuilder);
unset($this->layoutBuilder);
unset($this->historyBuilder);
unset($this->aliasBuilder);
unset($this->titleBuilder);
unset($this->customBuilderList);
unset($this->hiddenFieldsBuilder);
unset($this->intFieldsBuilder);
unset($this->dynamicfieldsBuilder);
unset($this->maintextBuilder);
unset($this->customFieldLinksBuilder);
unset($this->setScriptUserSwitch);
unset($this->categoryBuilder);
unset($this->catCodeBuilder);
unset($this->checkboxBuilder);
unset($this->jsonItemBuilder);
unset($this->base64Builder);
unset($this->basicEncryptionBuilder);
unset($this->advancedEncryptionBuilder);
unset($this->getItemsMethodListStringFixBuilder);
unset($this->getItemsMethodEximportStringFixBuilder);
unset($this->selectionTranslationFixBuilder);
unset($this->listBuilder);
unset($this->customBuilder);
unset($this->editBodyViewScriptBuilder);
unset($this->queryBuilder);
unset($this->sortBuilder);
unset($this->searchBuilder);
unset($this->filterBuilder);
unset($this->fieldsNames);
unset($this->siteFields);
unset($this->siteFieldData);
unset($this->customFieldScript);
unset($this->configFieldSets);
unset($this->jsonStringBuilder);
unset($this->importCustomScripts);
unset($this->eximportView);
unset($this->uninstallBuilder);
unset($this->listColnrBuilder);
unset($this->customFieldBuilder);
unset($this->permissionFields);
unset($this->getAsLookup);
unset($this->secondRunAdmin);
unset($this->uninstallScriptBuilder);
unset($this->buildCategories);
unset($this->iconBuilder);
unset($this->validationFixBuilder);
unset($this->targetRelationControl);
unset($this->targetControlsScriptChecker);
unset($this->accessBuilder);
unset($this->tabCounter);
unset($this->linkedAdminViews);
unset($this->uniquekeys);
unset($this->uniquecodes);
$this->unsetNow('_adminViewData');
$this->unsetNow('_fieldData');
}
/**
* move the local update server xml file to a remote ftp server
*
@ -375,8 +304,59 @@ class Compiler extends Infusion
$this->fileContentStatic['###BUILDDATE###'] = $this->fileContentStatic['###BUILDDATE###GLOBAL'];
$this->fileContentStatic['###VERSION###'] = $this->fileContentStatic['###VERSION###GLOBAL'];
}
// set all global numbers
protected function setCountingStuff()
{
// what is the size in terms of an A4 book
$this->pageCount = round($this->lineCount / 56);
// setup the unrealistic numbers
$this->folderSeconds = $this->folderCount * 5;
$this->fileSeconds = $this->fileCount * 5;
$this->lineSeconds = $this->lineCount * 10;
$this->seconds = $this->folderSeconds + $this->fileSeconds + $this->lineSeconds;
$this->totalHours = round($this->seconds / 3600);
$this->totalDays = round($this->totalHours / 8);
// setup the more realistic numbers
$this->secondsDebugging = $this->seconds / 4;
$this->secondsPlanning = $this->seconds / 7;
$this->secondsMapping = $this->seconds / 10;
$this->secondsOffice = $this->seconds / 6;
$this->actualSeconds = $this->folderSeconds + $this->fileSeconds + $this->lineSeconds + $this->secondsDebugging + $this->secondsPlanning + $this->secondsMapping + $this->secondsOffice;
$this->actualTotalHours = round($this->actualSeconds / 3600);
$this->actualTotalDays = round($this->actualTotalHours / 8);
$this->debuggingHours = round($this->secondsDebugging / 3600);
$this->planningHours = round($this->secondsPlanning / 3600);
$this->mappingHours = round($this->secondsMapping / 3600);
$this->officeHours = round($this->secondsOffice / 3600);
// the actual time spent
$this->actualHoursSpent = $this->actualTotalHours - $this->totalHours;
$this->actualDaysSpent = $this->actualTotalDays - $this->totalDays;
// calculate the projects actual time frame of completion
$this->projectWeekTime = round($this->actualTotalDays / 5,1);
$this->projectMonthTime = round($this->actualTotalDays / 24,1);
}
private function buildReadMe($path)
private function buildReadMe()
{
// do a final run to update the readme file
$two = 0;
foreach ($this->newFiles['static'] as $static)
{
if (('README.md' === $static['name'] || 'README.txt' === $static['name']) && $this->componentData->addreadme && JFile::exists($static['path']))
{
$this->setReadMe($static['path']);
$two++;
}
if ($two == 2)
{
break;
}
}
unset($this->newFiles['static']);
}
private function setReadMe($path)
{
// set readme data if not set already
if (!isset($this->fileContentStatic['###LINE_COUNT###']) || $this->fileContentStatic['###LINE_COUNT###'] != $this->lineCount)
@ -386,62 +366,46 @@ class Compiler extends Infusion
// get the file
$string = JFile::read($path);
// update the file
$answer = str_replace(array_keys($this->fileContentStatic),array_values($this->fileContentStatic),$string);
$answer = $this->setPlaceholders($string, $this->fileContentStatic);
// add to zip array
$this->writeFile($path,$answer);
}
private function buildReadMeData()
{
// setup the unrealistic numbers
$folders = $this->folderCount * 5;
$files = $this->fileCount * 5;
$lines = $this->lineCount * 10;
$seconds = $folders + $files + $lines;
$totalHours = round($seconds / 3600);
$totalDays = round($totalHours / 8);
// setup the more realistic numbers
$debugging = $seconds / 4;
$planning = $seconds / 7;
$mapping = $seconds / 10;
$office = $seconds / 6;
$seconds = $folders + $files + $lines + $debugging + $planning + $mapping + $office;
$actualTotalHours = round($seconds / 3600);
$actualTotalDays = round($actualTotalHours / 8);
$debuggingHours = round($debugging / 3600);
$planningHours = round($planning / 3600);
$mappingHours = round($mapping / 3600);
$officeHours = round($office / 3600);
// the actual time spent
$actualHoursSpent = $actualTotalHours - $totalHours;
$actualDaysSpent = $actualTotalDays - $totalDays;
// calculate the projects actual time frame of completion
$projectWeekTime = round($actualTotalDays / 5,1);
$projectMonthTime = round($actualTotalDays / 24,1);
// set some defaults
$this->fileContentStatic['###LINE_COUNT###'] = $this->lineCount;
$this->fileContentStatic['###FILE_COUNT###'] = $this->fileCount;
$this->fileContentStatic['###FOLDER_COUNT###'] = $this->folderCount;
$this->fileContentStatic['###folders###'] = $folders;
$this->fileContentStatic['###files###'] = $files;
$this->fileContentStatic['###lines###'] = $lines;
$this->fileContentStatic['###seconds###'] = $seconds;
$this->fileContentStatic['###totalHours###'] = $totalHours;
$this->fileContentStatic['###totalDays###'] = $totalDays;
$this->fileContentStatic['###debugging###'] = $debugging;
$this->fileContentStatic['###planning###'] = $planning;
$this->fileContentStatic['###mapping###'] = $mapping;
$this->fileContentStatic['###office###'] = $office;
$this->fileContentStatic['###actualTotalHours###'] = $actualTotalHours;
$this->fileContentStatic['###actualTotalDays###'] = $actualTotalDays;
$this->fileContentStatic['###debuggingHours###'] = $debuggingHours;
$this->fileContentStatic['###planningHours###'] = $planningHours;
$this->fileContentStatic['###mappingHours###'] = $mappingHours;
$this->fileContentStatic['###officeHours###'] = $officeHours;
$this->fileContentStatic['###actualHoursSpent###'] = $actualHoursSpent;
$this->fileContentStatic['###actualDaysSpent###'] = $actualDaysSpent;
$this->fileContentStatic['###projectWeekTime###'] = $projectWeekTime;
$this->fileContentStatic['###projectMonthTime###'] = $projectMonthTime;
$this->fileContentStatic['###LINE_COUNT###'] = $this->lineCount;
$this->fileContentStatic['###FILE_COUNT###'] = $this->fileCount;
$this->fileContentStatic['###FOLDER_COUNT###'] = $this->folderCount;
$this->fileContentStatic['###PAGE_COUNT###'] = $this->pageCount;
$this->fileContentStatic['###folders###'] = $this->folderSeconds;
$this->fileContentStatic['###foldersSeconds###'] = $this->folderSeconds;
$this->fileContentStatic['###files###'] = $this->fileSeconds;
$this->fileContentStatic['###filesSeconds###'] = $this->fileSeconds;
$this->fileContentStatic['###lines###'] = $this->lineSeconds;
$this->fileContentStatic['###linesSeconds###'] = $this->lineSeconds;
$this->fileContentStatic['###seconds###'] = $this->actualSeconds;
$this->fileContentStatic['###actualSeconds###'] = $this->actualSeconds;
$this->fileContentStatic['###totalHours###'] = $this->totalHours;
$this->fileContentStatic['###totalDays###'] = $this->totalDays;
$this->fileContentStatic['###debugging###'] = $this->secondsDebugging;
$this->fileContentStatic['###secondsDebugging###'] = $this->secondsDebugging;
$this->fileContentStatic['###planning###'] = $this->secondsPlanning;
$this->fileContentStatic['###secondsPlanning###'] = $this->secondsPlanning;
$this->fileContentStatic['###mapping###'] = $this->secondsMapping;
$this->fileContentStatic['###secondsMapping###'] = $this->secondsMapping;
$this->fileContentStatic['###office###'] = $this->secondsOffice;
$this->fileContentStatic['###secondsOffice###'] = $this->secondsOffice;
$this->fileContentStatic['###actualTotalHours###'] = $this->actualTotalHours;
$this->fileContentStatic['###actualTotalDays###'] = $this->actualTotalDays;
$this->fileContentStatic['###debuggingHours###'] = $this->debuggingHours;
$this->fileContentStatic['###planningHours###'] = $this->planningHours;
$this->fileContentStatic['###mappingHours###'] = $this->mappingHours;
$this->fileContentStatic['###officeHours###'] = $this->officeHours;
$this->fileContentStatic['###actualHoursSpent###'] = $this->actualHoursSpent;
$this->fileContentStatic['###actualDaysSpent###'] = $this->actualDaysSpent;
$this->fileContentStatic['###projectWeekTime###'] = $this->projectWeekTime;
$this->fileContentStatic['###projectMonthTime###'] = $this->projectMonthTime;
}
private function zipComponent()
@ -591,8 +555,13 @@ class Compiler extends Infusion
return false;
}
protected function addCustomCode($app)
protected function addCustomCode()
{
// load error messages incase code can not be added
$app = JFactory::getApplication();
// reset all these
$this->clearFromPlaceHolders('view');
$this->clearFromPlaceHolders('arg');
foreach($this->customCode as $nr => $target)
{
// reset each time per custom code
@ -622,7 +591,7 @@ class Compiler extends Infusion
$foundEnd = true;
}
$counter = 0;
// check if file is new structure
// check if file exist
if (JFile::exists($file))
{
foreach (new SplFileObject($file) as $lineNumber => $lineContent)
@ -686,8 +655,8 @@ class Compiler extends Infusion
}
if ($found)
{
$placeholder = $this->getPlaceHolder($target['type'], $target['id']);
$data = $placeholder['start'] . "\n" . $target['code'] . $placeholder['end'];
$placeholder = $this->getPlaceHolder((int) $target['comment_type'].$target['type'], $target['id']);
$data = $placeholder['start'] . PHP_EOL . $this->setPlaceholders($target['code'], $this->placeholders). $placeholder['end'] . PHP_EOL;
if ($target['type'] == 2)
{
// found it now add code from the next line
@ -696,20 +665,20 @@ class Compiler extends Infusion
elseif ($target['type'] == 1 && $foundEnd)
{
// found it now add code from the next line
$this->addDataToFile($file, $data . "\n", $bites, (int) array_sum($replace));
$this->addDataToFile($file, $data, $bites, (int) array_sum($replace));
}
else
{
// Load escaped code since the target endhash has changed
$this->loadEscapedCode($file, $target, $lineBites);
$app->enqueueMessage(JText::sprintf('Custom code could not be added to <b>%s</b> please review the file at line %s. This could be due to a change to lines below the custom code.', $target['path'], $target['from_line']), 'warning');
$app->enqueueMessage(JText::sprintf('Custom code could not be added to <b>%s</b> please review the file at <b>line %s</b>. This could be due to a change to lines below the custom code.', $target['path'], $target['from_line']), 'warning');
}
}
else
{
// Load escaped code since the target hash has changed
$this->loadEscapedCode($file, $target, $lineBites);
$app->enqueueMessage(JText::sprintf('Custom code could not be added to <b>%s</b> please review the file at line %s. This could be due to a change to lines above the custom code.', $target['path'], $target['from_line']), 'warning');
$app->enqueueMessage(JText::sprintf('Custom code could not be added to <b>%s</b> please review the file at <b>line %s</b>. This could be due to a change to lines above the custom code.', $target['path'], $target['from_line']), 'warning');
}
}
else
@ -724,12 +693,12 @@ class Compiler extends Infusion
protected function loadEscapedCode($file, $target, $lineBites)
{
// escape the code
$code = explode("\n", $target['code']);
$code = "\n// " .implode("\n// ",$code). "\n";
$code = explode(PHP_EOL, $target['code']);
$code = PHP_EOL."// " .implode(PHP_EOL."// ",$code). PHP_EOL;
// get place holders
$placeholder = $this->getPlaceHolder($target['type'], $target['id']);
$placeholder = $this->getPlaceHolder((int) $target['comment_type'].$target['type'], $target['id']);
// build the data
$data = $placeholder['start'] . $code . $placeholder['end']. "\n";
$data = $placeholder['start'] . $code . $placeholder['end']. PHP_EOL;
// get the bites before insertion
$bitBucket = array();
foreach($lineBites as $line => $value)
@ -746,23 +715,31 @@ class Compiler extends Infusion
// Thanks to http://stackoverflow.com/a/16813550/1429677
protected function addDataToFile($file, $data, $position, $replace = null)
{
// start the process
$fpFile = fopen($file, "rw+");
$fpTemp = fopen('php://temp', "rw+");
$len = stream_copy_to_stream($fpFile, $fpTemp); // make a copy
fseek($fpFile, $position); // move to the position
// make a copy of the file
stream_copy_to_stream($fpFile, $fpTemp);
// move to the position where we should add the data
fseek($fpFile, $position);
// Add the data
fwrite($fpFile, $data);
// truncate file at the end of the data that was added
$remove = bcadd($position, mb_strlen($data, '8bit'));
ftruncate($fpFile, $remove);
// check if this was a replacement of data
if ($replace)
{
$position = bcadd($position, $replace);
}
fseek($fpTemp, $position); // move to the position
fwrite($fpFile, $data); // Add the data
// move to the position of the data that should remain below the new data
fseek($fpTemp, $position);
// copy that remaining data to the file
stream_copy_to_stream($fpTemp, $fpFile); // @Jack
fclose($fpFile); // close file
fclose($fpTemp); // close tmp
// done close both files
fclose($fpFile);
fclose($fpTemp);
// any help to improve this is welcome...
}
}

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.2.0
@version 2.3.0
@created 30th April, 2015
@package Component Builder
@subpackage compiler.php
@ -45,6 +45,13 @@ class Structure extends Get
*/
public $fileCount = 0;
/**
* The page counter
*
* @var int
*/
public $pageCount = 0;
/**
* The line counter
*
@ -52,6 +59,153 @@ class Structure extends Get
*/
public $lineCount = 0;
/**
* The seconds counter
*
* @var int
*/
public $seconds = 0;
/**
* The actual seconds counter
*
* @var int
*/
public $actualSeconds = 0;
/**
* The folder seconds counter
*
* @var int
*/
public $folderSeconds = 0;
/**
* The file seconds counter
*
* @var int
*/
public $fileSeconds = 0;
/**
* The line seconds counter
*
* @var int
*/
public $lineSeconds = 0;
/**
* The seconds debugging counter
*
* @var int
*/
public $secondsDebugging = 0;
/**
* The seconds planning counter
*
* @var int
*/
public $secondsPlanning = 0;
/**
* The seconds mapping counter
*
* @var int
*/
public $secondsMapping = 0;
/**
* The seconds office counter
*
* @var int
*/
public $secondsOffice = 0;
/**
* The total hours counter
*
* @var int
*/
public $totalHours = 0;
/**
* The debugging hours counter
*
* @var int
*/
public $debuggingHours = 0;
/**
* The planning hours counter
*
* @var int
*/
public $planningHours = 0;
/**
* The mapping hours counter
*
* @var int
*/
public $mappingHours = 0;
/**
* The office hours counter
*
* @var int
*/
public $officeHours = 0;
/**
* The actual Total Hours counter
*
* @var int
*/
public $actualTotalHours = 0;
/**
* The actual hours spent counter
*
* @var int
*/
public $actualHoursSpent = 0;
/**
* The actual days spent counter
*
* @var int
*/
public $actualDaysSpent = 0;
/**
* The total days counter
*
* @var int
*/
public $totalDays = 0;
/**
* The actual Total Days counter
*
* @var int
*/
public $actualTotalDays = 0;
/**
* The project week time counter
*
* @var int
*/
public $projectWeekTime = 0;
/**
* The project month time counter
*
* @var int
*/
public $projectMonthTime = 0;
/**
* The Joomla Version
*
@ -513,14 +667,14 @@ class Structure extends Get
{
// set list view$view
$target = array('custom_admin' => $view['settings']->code);
$config = array('###CREATIONDATE###' => $created, '###BUILDDATE###' => JFactory::getDate($view['settings']->modified)->format('jS F, Y'),'###VERSION###' => $view['settings']->version);
$config = array('###CREATIONDATE###' => $created, '###BUILDDATE###' => $modified,'###VERSION###' => $view['settings']->version);
$this->buildDynamique($target,'list', false, $config);
}
elseif ($view['settings']->main_get->gettype == 1)
{
// set single view
$target = array('custom_admin' => $view['settings']->code);
$config = array('###CREATIONDATE###' => $created, '###BUILDDATE###' => JFactory::getDate($view['settings']->modified)->format('jS F, Y'),'###VERSION###' => $view['settings']->version);
$config = array('###CREATIONDATE###' => $created, '###BUILDDATE###' => $modified,'###VERSION###' => $view['settings']->version);
$this->buildDynamique($target, 'single', false, $config);
}
}
@ -811,7 +965,7 @@ class Structure extends Get
}
if (count($pathArray) == 1 && $firstFolder === 'media')
{
$this->fileContentStatic['###EXSTRA_MEDIA_FOLDERS###'] .= "\n\t\t<folder>".$lastFolder."</folder>";
$this->fileContentStatic['###EXSTRA_MEDIA_FOLDERS###'] .= PHP_EOL."\t\t<folder>".$lastFolder."</folder>";
}
// check if we sould add it to the site xml list
if (!isset($this->fileContentStatic['###EXSTRA_SITE_FOLDERS###']))
@ -820,7 +974,7 @@ class Structure extends Get
}
if (count($pathArray) == 1 && $firstFolder === 'site')
{
$this->fileContentStatic['###EXSTRA_SITE_FOLDERS###'] .= "\n\t\t<folder>".$lastFolder."</folder>";
$this->fileContentStatic['###EXSTRA_SITE_FOLDERS###'] .= PHP_EOL."\t\t<folder>".$lastFolder."</folder>";
}
// check if we sould add it to the admin xml list
if (!isset($this->fileContentStatic['###EXSTRA_ADMIN_FOLDERS###']))
@ -829,7 +983,7 @@ class Structure extends Get
}
if (count($pathArray) == 1 && $firstFolder === 'admin')
{
$this->fileContentStatic['###EXSTRA_ADMIN_FOLDERS###'] .= "\n\t\t\t<folder>".$lastFolder."</folder>";
$this->fileContentStatic['###EXSTRA_ADMIN_FOLDERS###'] .= PHP_EOL."\t\t\t<folder>".$lastFolder."</folder>";
}
// make we have not duplicates
$key_pointer = ComponentbuilderHelper::safeString($custom['folder']).'_f'.$pointer_tracker;
@ -969,38 +1123,4 @@ class Structure extends Get
}
return false;
}
/**
* get the local installed path of this component
*
* @return array of paths on success
*
*/
public function getLocalInstallPaths()
{
// set the local paths to search
$localPaths = array();
// the admin path
$localPaths['admin'] = JPATH_ADMINISTRATOR . '/components/com_'. $this->componentCodeName;
// only check for site path if the component has a site area!
if (!$this->removeSiteFolder)
{
$localPaths['site'] = JPATH_ROOT . '/components/com_'. $this->componentCodeName;
}
// TODO later to include the JS and CSS
// $localPaths['media'] = JPATH_ROOT . '/media/com_'. $this->fileContentStatic['###component###'];
// check if the local install is found
foreach ($localPaths as $key => $localPath)
{
if (!JFolder::exists($localPath))
{
unset($localPaths[$key]);
}
}
if (ComponentbuilderHelper::checkArray($localPaths))
{
return $localPaths;
}
return false;
}
}

View File

@ -11,7 +11,7 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.2.0
@version 2.3.0
@created 30th April, 2015
@package Component Builder
@subpackage compiler.php
@ -311,7 +311,14 @@ class Fields extends Structure
*
* @var array
*/
public $fieldsNames = array();
public $fieldsNames = array();
/**
* Set unique Names
*
* @var array
*/
public $uniqueNames = array();
/**
* Default Fields
@ -368,6 +375,19 @@ class Fields extends Structure
// setup the list view and single view name
$listViewName = ComponentbuilderHelper::safeString($view['settings']->name_list);
$viewName = ComponentbuilderHelper::safeString($view['settings']->name_single);
// set some place holder for this view
$this->placeholders['###view###'] = $viewName;
$this->placeholders['###VIEW###'] = strtoupper($viewName);
$this->placeholders['###View###'] = ucfirst($viewName);
$this->placeholders['[[[view]]]'] = $this->placeholders['###view###'];
$this->placeholders['[[[VIEW]]]'] = $this->placeholders['###VIEW###'];
$this->placeholders['[[[View]]]'] = $this->placeholders['###View###'];
$this->placeholders['###views###'] = $listViewName;
$this->placeholders['###VIEWS###'] = strtoupper($listViewName);
$this->placeholders['###Views###'] = ucfirst($listViewName);
$this->placeholders['[[[views]]]'] = $this->placeholders['###views###'];
$this->placeholders['[[[VIEWS]]]'] = $this->placeholders['###VIEWS###'];
$this->placeholders['[[[Views]]]'] = $this->placeholders['###Views###'];
// add metadata to the view
if ($view['metadata'])
{
@ -382,15 +402,15 @@ class Fields extends Structure
$readOnly = "";
if ($view['settings']->type == 2)
{
$readOnly = "\t\t\t" . 'readonly="true"' . "\n\t\t\t" . 'disabled="true"';
$readOnly = "\t\t\t" . 'readonly="true"' . PHP_EOL."\t\t\t" . 'disabled="true"';
}
// main lang prefix
$langView = $this->langPrefix . '_' . ComponentbuilderHelper::safeString($view['settings']->name_single, 'U');
$langViews = $this->langPrefix . '_' . ComponentbuilderHelper::safeString($view['settings']->name_list, 'U');
$langView = $this->langPrefix . '_' . $this->placeholders['###VIEW###'];
$langViews = $this->langPrefix . '_' . $this->placeholders['###VIEWS###'];
// set default lang
$this->langContent[$this->lang][$langView] = $view['settings']->name_single;
$this->langContent[$this->lang][$langViews] = $view['settings']->name_list;
// set the singel name
// set the single name
$viewSingleName = ComponentbuilderHelper::safeString($view['settings']->name_single, 'W');
// set global item strings
$this->langContent[$this->lang][$langViews . '_N_ITEMS_ARCHIVED'] = "%s " . $view['settings']->name_list . " archived.";
@ -427,20 +447,21 @@ class Fields extends Structure
$this->langContent[$this->lang][$langView . '_VERSION_DESC'] = "A count of the number of times this " . $view['settings']->name_single . " has been revised.";
$this->langContent[$this->lang][$langView . '_SAVE_WARNING'] = "Alias already existed so a number was added at the end. You can re-edit the " . $view['settings']->name_single . " to customise the alias.";
// check if the same field is added multiple times
foreach ($view['settings']->fields as $field)
{
$name = ComponentbuilderHelper::safeString($field['settings']->name);
$this->setUniqueNameKeeper($field, $view['settings']->type, $name, $viewName);
}
// start adding dynamc fields
$dynamcfields = '';
// place holders
$placeholders = array(
'###component###' => $component,
'###view###' => $viewName,
'###views###' => $listViewName);
$spacerCounter = 'a';
// set the custom table key
$dbkey = 'g';
// TODO we should add the global and local view switch if field for front end
foreach ($view['settings']->fields as $field)
{
$dynamcfields .= $this->setDynamicField($field, $view, $view['settings']->type, $langView, $viewName, $listViewName, $spacerCounter, $placeholders, $dbkey, true);
$dynamcfields .= $this->setDynamicField($field, $view, $view['settings']->type, $langView, $viewName, $listViewName, $spacerCounter, $this->placeholders, $dbkey, true);
}
// set the defautl fields
@ -601,7 +622,7 @@ class Fields extends Structure
// check if metadata is added to this view
if (isset($this->metadataBuilder[$viewName]) && ComponentbuilderHelper::checkString($this->metadataBuilder[$viewName]))
{
$fieldSet[] = "\n\t<!--" . $this->setLine(__LINE__) . " Metadata Fields. -->";
$fieldSet[] = PHP_EOL."\t<!--" . $this->setLine(__LINE__) . " Metadata Fields. -->";
$fieldSet[] = "\t<fields" . ' name="metadata" label="JGLOBAL_FIELDSET_METADATA_OPTIONS">';
$fieldSet[] = "\t\t" . '<fieldset name="vdmmetadata"';
$fieldSet[] = "\t\t\t" . 'label="JGLOBAL_FIELDSET_METADATA_OPTIONS">';
@ -633,8 +654,10 @@ class Fields extends Structure
$fieldSet[] = "\t\t</fieldset>";
$fieldSet[] = "\t</fields>";
}
// just to be safe, lets clear the view placeholders
$this->clearFromPlaceHolders('view');
// retunr the set
return implode("\n", $fieldSet);
return implode(PHP_EOL, $fieldSet);
}
return '';
}
@ -797,14 +820,14 @@ class Fields extends Structure
if ($setType === 'option')
{
// now add to the field set
$fieldSet .= "\n\t" . $taber . "\t<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla) -->";
$fieldSet .= "\n\t" . $taber . "\t<field";
$fieldSet .= PHP_EOL."\t" . $taber . "\t<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla) -->";
$fieldSet .= PHP_EOL."\t" . $taber . "\t<field";
$optionSet = '';
foreach ($fieldAttributes as $property => $value)
{
if ($property != 'option')
{
$fieldSet .= "\n\t\t" . $taber . "\t" . $property . '="' . $value . '"';
$fieldSet .= PHP_EOL."\t\t" . $taber . "\t" . $property . '="' . $value . '"';
}
elseif ($property === 'option')
{
@ -823,7 +846,7 @@ class Fields extends Structure
// add to lang array
$this->langContent[$this->lang][$langValue] = $t;
// no add to option set
$optionSet .= "\n\t" . $taber . "\t\t" . '<option value="' . $v . '">' . "\n\t" . $taber . "\t\t\t" . $langValue . '</option>';
$optionSet .= PHP_EOL."\t" . $taber . "\t\t" . '<option value="' . $v . '">' . PHP_EOL."\t" . $taber . "\t\t\t" . $langValue . '</option>';
$optionArray[$v] = $langValue;
}
else
@ -833,7 +856,7 @@ class Fields extends Structure
// add to lang array
$this->langContent[$this->lang][$langValue] = $option;
// no add to option set
$optionSet .= "\n\t\t" . $taber . "\t" . '<option value="' . $option . '">' . "\n\t\t" . $taber . "\t\t" . $langValue . '</option>';
$optionSet .= PHP_EOL."\t\t" . $taber . "\t" . '<option value="' . $option . '">' . PHP_EOL."\t\t" . $taber . "\t\t" . $langValue . '</option>';
$optionArray[$option] = $langValue;
}
}
@ -849,7 +872,7 @@ class Fields extends Structure
// add to lang array
$this->langContent[$this->lang][$langValue] = $t;
// no add to option set
$optionSet .= "\n\t\t" . $taber . "\t" . '<option value="' . $v . '">' . "\n\t\t" . $taber . "\t\t" . $langValue . '</option>';
$optionSet .= PHP_EOL."\t\t" . $taber . "\t" . '<option value="' . $v . '">' . PHP_EOL."\t\t" . $taber . "\t\t" . $langValue . '</option>';
$optionArray[$v] = $langValue;
}
else
@ -859,7 +882,7 @@ class Fields extends Structure
// add to lang array
$this->langContent[$this->lang][$langValue] = $value;
// no add to option set
$optionSet .= "\n\t\t" . $taber . "\t" . '<option value="' . $value . '">' . "\n\t\t" . $taber . "\t\t" . $langValue . '</option>';
$optionSet .= PHP_EOL."\t\t" . $taber . "\t" . '<option value="' . $value . '">' . PHP_EOL."\t\t" . $taber . "\t\t" . $langValue . '</option>';
$optionArray[$value] = $langValue;
}
}
@ -868,41 +891,41 @@ class Fields extends Structure
if (ComponentbuilderHelper::checkString($optionSet))
{
$fieldSet .= '>';
$fieldSet .= "\n\t\t\t" . $taber . "<!--" . $this->setLine(__LINE__) . " Option Set. -->";
$fieldSet .= PHP_EOL."\t\t\t" . $taber . "<!--" . $this->setLine(__LINE__) . " Option Set. -->";
$fieldSet .= $optionSet;
$fieldSet .= "\n\t\t" . $taber . "</field>";
$fieldSet .= PHP_EOL."\t\t" . $taber . "</field>";
}
elseif ($typeName === 'sql')
{
$optionArray = false;
$fieldSet .= "\n\t\t" . $taber . "/>";
$fieldSet .= PHP_EOL."\t\t" . $taber . "/>";
}
else
{
$optionArray = false;
$fieldSet .= "\n\t\t\t" . $taber . "<!--" . $this->setLine(__LINE__) . " No Manual Options Were Added In Field Settings. -->";
$fieldSet .= "\n\t\t" . $taber . "/>";
$fieldSet .= PHP_EOL."\t\t\t" . $taber . "<!--" . $this->setLine(__LINE__) . " No Manual Options Were Added In Field Settings. -->";
$fieldSet .= PHP_EOL."\t\t" . $taber . "/>";
}
}
elseif ($setType === 'plain')
{
// now add to the field set
$fieldSet .= "\n\t\t" . $taber . "<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla) -->";
$fieldSet .= "\n\t\t" . $taber . "<field";
$fieldSet .= PHP_EOL."\t\t" . $taber . "<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla) -->";
$fieldSet .= PHP_EOL."\t\t" . $taber . "<field";
foreach ($fieldAttributes as $property => $value)
{
if ($property != 'option')
{
$fieldSet .= "\n\t\t" . $taber . "\t" . $property . '="' . $value . '"';
$fieldSet .= PHP_EOL."\t\t" . $taber . "\t" . $property . '="' . $value . '"';
}
}
$fieldSet .= "\n\t\t" . $taber . "/>";
$fieldSet .= PHP_EOL."\t\t" . $taber . "/>";
}
elseif ($setType === 'spacer')
{
// now add to the field set
$fieldSet .= "\n\t\t<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". A None Database Field. (joomla) -->";
$fieldSet .= "\n\t\t<field";
$fieldSet .= PHP_EOL."\t\t<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". A None Database Field. (joomla) -->";
$fieldSet .= PHP_EOL."\t\t<field";
foreach ($fieldAttributes as $property => $value)
{
if ($property != 'option')
@ -918,19 +941,19 @@ class Fields extends Structure
if ($typeName === 'repeatable')
{
// now add to the field set
$fieldSet .= "\n\t\t<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla) -->";
$fieldSet .= "\n\t\t<field";
$fieldSet .= PHP_EOL."\t\t<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla) -->";
$fieldSet .= PHP_EOL."\t\t<field";
$fieldsSet = array();
foreach ($fieldAttributes as $property => $value)
{
if ($property != 'fields')
{
$fieldSet .= "\n\t\t\t" . $property . '="' . $value . '"';
$fieldSet .= PHP_EOL."\t\t\t" . $property . '="' . $value . '"';
}
}
$fieldSet .= ">";
$fieldSet .= "\n\t\t\t" . '<fields name="' . $fieldAttributes['name'] . '_fields" label="">';
$fieldSet .= "\n\t\t\t\t" . '<fieldset hidden="true" name="' . $fieldAttributes['name'] . '_modal" repeat="true">';
$fieldSet .= PHP_EOL."\t\t\t" . '<fields name="' . $fieldAttributes['name'] . '_fields" label="">';
$fieldSet .= PHP_EOL."\t\t\t\t" . '<fieldset hidden="true" name="' . $fieldAttributes['name'] . '_modal" repeat="true">';
if (strpos($fieldAttributes['fields'], ',') !== false)
{
// mulitpal fields
@ -999,24 +1022,24 @@ class Fields extends Structure
}
}
}
$fieldSet .= "\n\t\t\t\t</fieldset>";
$fieldSet .= "\n\t\t\t</fields>";
$fieldSet .= "\n\t\t</field>";
$fieldSet .= PHP_EOL."\t\t\t\t</fieldset>";
$fieldSet .= PHP_EOL."\t\t\t</fields>";
$fieldSet .= PHP_EOL."\t\t</field>";
}
}
elseif ($setType === 'custom')
{
// now add to the field set
$fieldSet .= "\n\t\t" . $taber . "<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (custom) -->";
$fieldSet .= "\n\t\t" . $taber . "<field";
$fieldSet .= PHP_EOL."\t\t" . $taber . "<!--" . $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (custom) -->";
$fieldSet .= PHP_EOL."\t\t" . $taber . "<field";
foreach ($fieldAttributes as $property => $value)
{
if ($property != 'option')
{
$fieldSet .= "\n\t\t" . $taber . "\t" . $property . '="' . $value . '"';
$fieldSet .= PHP_EOL."\t\t" . $taber . "\t" . $property . '="' . $value . '"';
}
}
$fieldSet .= "\n\t\t" . $taber . "/>";
$fieldSet .= PHP_EOL."\t\t" . $taber . "/>";
// incase the field is in the config and has not been set
if ('config' === $viewName && 'configs' === $listViewName)
{
@ -1135,18 +1158,18 @@ class Fields extends Structure
/**
* set field attributes
*
* @param array $field The field data
* @param int $viewType The view type
* @param string $name The field name
* @param string $typeName The field type
* @param boolean $multiple The switch to set multiple selection option
* @param string $langLabel The language string for field label
* @param string $langView The language string of the view
* @param array $field The field data
* @param int $viewType The view type
* @param string $name The field name
* @param string $typeName The field type
* @param boolean $multiple The switch to set multiple selection option
* @param string $langLabel The language string for field label
* @param string $langView The language string of the view
* @param string $spacerCounter The space counter value
* @param string $listViewName The list view name
* @param string $viewName The singel view name
* @param array $placeholders The place holder and replace values
* @param boolean $repeatable The repeatable field switch
* @param string $listViewName The list view name
* @param string $viewName The singel view name
* @param array $placeholders The place holder and replace values
* @param boolean $repeatable The repeatable field switch
*
* @return array The field attributes
*
@ -1219,7 +1242,7 @@ class Fields extends Structure
{
// quick check if this is a category linked to view page
$requeSt_id = ComponentbuilderHelper::getBetween($field['settings']->xml, 'name="', '"');
if (strpos($requeSt_id, '_request_id') !== false)
if (strpos($requeSt_id, '_request_id') !== false || strpos($requeSt_id, '_request_catid') !== false)
{
// keep it then, don't change
$xmlValue = $requeSt_id;
@ -1264,19 +1287,23 @@ class Fields extends Structure
// use field core name only if not found in xml
if (!ComponentbuilderHelper::checkString($xmlValue))
{
// make sure the XML name is uniqe, so we can add one field multiple times
$name = $this->uniqueName($name, $viewName);
$xmlValue = $name;
}
// set the name if found
else
{
$name = $xmlValue;
// make sure the XML name is uniqe, so we can add one field multiple times
$xmlValue = $this->uniqueName($xmlValue, $viewName);
$name = $this->setPlaceholders($xmlValue, $placeholders);
}
}
elseif ($property['name'] === 'extension' || $property['name'] === 'directory')
{
$xmlValue = ComponentbuilderHelper::getBetween($field['settings']->xml, $property['name'] . '="', '"');
// replace the placeholders
$xmlValue = str_replace(array_keys($placeholders), array_values($placeholders), $xmlValue);
$xmlValue = $this->setPlaceholders($xmlValue, $placeholders);
}
elseif (strpos($property['name'], 'type_php_') !== false && $setCustom)
{
@ -1312,14 +1339,14 @@ class Fields extends Structure
// load the component name
$fieldAttributes['custom']['component'] = ComponentbuilderHelper::getBetween($field['settings']->xml, 'component="', '"');
// replace the placeholders
$fieldAttributes['custom']['component'] = str_replace(array_keys($placeholders), array_values($placeholders), $fieldAttributes['custom']['component']);
$fieldAttributes['custom']['component'] = $this->setPlaceholders($fieldAttributes['custom']['component'], $placeholders);
}
elseif ($property['name'] === 'table' && $setCustom)
{
// load the main table that is queried
$fieldAttributes['custom']['table'] = ComponentbuilderHelper::getBetween($field['settings']->xml, 'table="', '"');
// replace the placeholders
$fieldAttributes['custom']['table'] = str_replace(array_keys($placeholders), array_values($placeholders), $fieldAttributes['custom']['table']);
$fieldAttributes['custom']['table'] = $this->setPlaceholders($fieldAttributes['custom']['table'], $placeholders);
}
elseif ($property['name'] === 'value_field' && $setCustom)
{
@ -1381,8 +1408,16 @@ class Fields extends Structure
// check if translatable
if (ComponentbuilderHelper::checkString($xmlValue) && $property['translatable'] == 1)
{
// update lable if field use multiple times
if ($property['name'] === 'label')
{
if (isset($fieldAttributes['name']) && isset($this->uniqueNames[$viewName]['names'][$fieldAttributes['name']]))
{
$xmlValue .= ' (' . ComponentbuilderHelper::safeString($this->uniqueNames[$viewName]['names'][$fieldAttributes['name']]) . ')';
}
}
// replace placeholders
$xmlValue = str_replace(array_keys($placeholders), array_values($placeholders), $xmlValue);
$xmlValue = $this->setPlaceholders($xmlValue, $placeholders);
// insure custom lables dont get messed up
if ($setCustom)
{
@ -1432,18 +1467,17 @@ class Fields extends Structure
$xmlValue = $property['example'];
}
}
$fieldAttributes[$property['name']] = $xmlValue;
// load to langBuilder down the line
if ($property['name'] === 'label')
{
$langLabel = $xmlValue;
if ($setCustom)
{
$fieldAttributes['custom']['label'] = $customLabel;
}
$langLabel = $xmlValue;
}
// now set the value
$fieldAttributes[$property['name']] = $xmlValue;
}
}
// do some nice twigs beyond the default
@ -1460,6 +1494,123 @@ class Fields extends Structure
return $fieldAttributes;
}
/**
* Keep track of the field names, to see if it used multiple times
*
* @param array $field The field data
* @param string $typeName The field type
* @param string $name The field name
* @param string $viewName The singel view name
*
* @return void
*
*/
protected function setUniqueNameKeeper(&$field, &$typeName, &$name, $viewName)
{
// setup a default field
if (ComponentbuilderHelper::checkArray($field['settings']->properties))
{
foreach ($field['settings']->properties as $property)
{
// reset
$xmlValue = '';
if ($property['name'] === 'name')
{
// if category then name must be catid (only one per view)
if ($typeName === 'category')
{
// only one allowed
return;
}
// if tag is set then enable all tag options for this view (only one per view)
elseif ($typeName === 'tag')
{
// only one allowed
return;
}
// if the field is set as alias it must be called alias
elseif (isset($field['alias']) && $field['alias'])
{
// only one allowed
return;
}
elseif ($typeName === 'spacer')
{
// not needed here
return;
}
else
{
$xmlValue = ComponentbuilderHelper::safeString(ComponentbuilderHelper::getBetween($field['settings']->xml, 'name="', '"'));
}
// use field core name only if not found in xml
if (!ComponentbuilderHelper::checkString($xmlValue))
{
$xmlValue = $name;
}
// make sure the XML name is uniqe, so we can add one field multiple times
return $this->setUniqueNameCounter($xmlValue, $viewName);
}
}
}
}
/**
* Count how many times the same field is used per view
*
* @param string $name The name of the field
* @param string $view The name of the view
*
* @return void
*
*/
protected function setUniqueNameCounter($name, $view)
{
if (!isset($this->uniqueNames[$view]))
{
$this->uniqueNames[$view] = array();
$this->uniqueNames[$view]['counter'] = array();
$this->uniqueNames[$view]['names'] = array();
}
if (!isset($this->uniqueNames[$view]['counter'][$name]))
{
$this->uniqueNames[$view]['counter'][$name] = 1;
return;
}
// count how many times the field is used
$this->uniqueNames[$view]['counter'][$name]++;
return;
}
/**
* Naming each field with an unique name
*
* @param string $name The name of the field
* @param string $view The name of the view
*
* @return string the name
*
*/
protected function uniqueName($name, $view)
{
// only increment if the field name is used multiple times
if (isset($this->uniqueNames[$view]['counter'][$name]) && $this->uniqueNames[$view]['counter'][$name] > 1)
{
$counter = $this->uniqueNames[$view]['counter'][$name];
$uniqueName = ComponentbuilderHelper::safeString($name . '_' . $counter);
while (isset($this->uniqueNames[$view]['names'][$uniqueName]))
{
$counter--;
$uniqueName = ComponentbuilderHelper::safeString($name . '_' . $counter);
}
// set the new name
$this->uniqueNames[$view]['names'][$uniqueName] = $counter;
return $uniqueName;
}
return $name;
}
/**
* set Builders
@ -1791,7 +1942,7 @@ class Fields extends Structure
// set tab and break replacements
$tabBreak = array(
'\t' => "\t",
'\n' => "\n"
'\n' => PHP_EOL
);
// make field dynamic
$replace = array(
@ -1818,16 +1969,16 @@ class Fields extends Structure
{
if ($line == 1)
{
$phpCode .= str_replace(array_keys($tabBreak),array_values($tabBreak),$code);
$phpCode .= $this->setPlaceholders($code, $tabBreak);
}
else
{
$phpCode .= "\n\t\t".str_replace(array_keys($tabBreak),array_values($tabBreak),$code);
$phpCode .= PHP_EOL."\t\t".$this->setPlaceholders($code, $tabBreak);
}
}
}
// replace the placholders
$phpCode = str_replace(array_keys($replace),array_values($replace),$phpCode);
$phpCode = $this->setPlaceholders($phpCode, $replace);
}
else
{
@ -1851,16 +2002,16 @@ class Fields extends Structure
{
if ($line == 1)
{
$phpxCode .= str_replace(array_keys($tabBreak),array_values($tabBreak),$code);
$phpxCode .= $this->setPlaceholders($code, $tabBreak);
}
else
{
$phpxCode .= "\n\t\t".str_replace(array_keys($tabBreak),array_values($tabBreak),$code);
$phpxCode .= PHP_EOL."\t\t".$this->setPlaceholders($code, $tabBreak);
}
}
}
// replace the placholders
$phpxCode = str_replace(array_keys($replace),array_values($replace),$phpxCode);
$phpxCode = $this->setPlaceholders($phpxCode, $replace);
}
else
{

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.2.0
@version 2.3.0
@created 30th April, 2015
@package Component Builder
@subpackage compiler.php
@ -34,6 +34,7 @@ class Infusion extends Interpretation
public $eximportView = array();
public $importCustomScripts = array();
public $langFiles = array();
public $removeSiteFolder = false;
/**
@ -79,13 +80,13 @@ class Infusion extends Interpretation
if (isset($this->componentData->admin_views) && ComponentbuilderHelper::checkArray($this->componentData->admin_views))
{
// ###COMPONENT###
$this->fileContentStatic['###COMPONENT###'] = ComponentbuilderHelper::safeString($this->componentData->name_code, 'U');
$this->fileContentStatic['###COMPONENT###'] = $this->placeholders['###COMPONENT###'];
// ###Component###
$this->fileContentStatic['###Component###'] = ComponentbuilderHelper::safeString($this->componentData->name_code, 'F');
$this->fileContentStatic['###Component###'] = $this->placeholders['###Component###'];
// ###component###
$this->fileContentStatic['###component###'] = ComponentbuilderHelper::safeString($this->componentData->name_code);
$this->fileContentStatic['###component###'] = $this->placeholders['###component###'];
// ###COMPANYNAME###
$this->fileContentStatic['###COMPANYNAME###'] = trim(JFilterOutput::cleanText($this->componentData->companyname));
@ -131,34 +132,27 @@ class Infusion extends Interpretation
// ###ACCESS_SECTIONS###
$this->fileContentStatic['###ACCESS_SECTIONS###'] = $this->setAccessSections();
// set component place holders
$this->placeholders = array(
'###Component###' => $this->fileContentStatic['###Component###'],
'###component###' => $this->fileContentStatic['###component###'],
'###COMPONENT###' => $this->fileContentStatic['###COMPONENT###'],
'[[[Component]]]' => $this->fileContentStatic['###Component###'],
'[[[component]]]' => $this->fileContentStatic['###component###'],
'[[[COMPONENT]]]' => $this->fileContentStatic['###COMPONENT###']
);
// ###CONFIG_FIELDSETS###
$keepLang = $this->lang;
$this->lang = 'admin';
// start loading the category tree scripts
$this->fileContentStatic['###CATEGORY_CLASS_TREES###'] = '';
// run the field sets for first time
$this->setConfigFieldsets(1);
$this->lang = $keepLang;
// ###ADMINCSS###
$this->fileContentStatic['###ADMINCSS###'] = str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['component_css']);
$this->fileContentStatic['###ADMINCSS###'] = $this->setPlaceholders($this->customScriptBuilder['component_css'], $this->placeholders);
// ###SITECSS###
$this->fileContentStatic['###SITECSS###'] = str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['component_css']);
$this->fileContentStatic['###SITECSS###'] = $this->setPlaceholders($this->customScriptBuilder['component_css'], $this->placeholders);
// ###CUSTOM_HELPER_SCRIPT###
$this->fileContentStatic['###CUSTOM_HELPER_SCRIPT###'] = str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['component_php_helper_admin']);
$this->fileContentStatic['###CUSTOM_HELPER_SCRIPT###'] = $this->setPlaceholders($this->customScriptBuilder['component_php_helper_admin'], $this->placeholders);
// ###BOTH_CUSTOM_HELPER_SCRIPT###
$this->fileContentStatic['###BOTH_CUSTOM_HELPER_SCRIPT###'] = str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['component_php_helper_both']);
$this->fileContentStatic['###BOTH_CUSTOM_HELPER_SCRIPT###'] = $this->setPlaceholders($this->customScriptBuilder['component_php_helper_both'], $this->placeholders);
// ###ADMIN_GLOBAL_EVENT_HELPER###
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] = '';
@ -173,22 +167,22 @@ class Infusion extends Interpretation
if ($this->componentData->add_admin_event == 1)
{
// ###ADMIN_GLOBAL_EVENT###
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT###'] = "\n\n".'// Triger the Global Admin Event';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT###'] .= "\n".$this->fileContentStatic['###Component###'].'Helper::globalEvent($document);';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT###'] = PHP_EOL.PHP_EOL.'// Triger the Global Admin Event';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT###'] .= PHP_EOL.$this->fileContentStatic['###Component###'].'Helper::globalEvent($document);';
// ###ADMIN_GLOBAL_EVENT_HELPER###
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] = "\n\n\t".'/**';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= "\n\t".'* The Global Admin Event Method.';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= "\n\t".'**/';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= "\n\t".'public static function globalEvent($document)';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= "\n\t".'{';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= "\n".str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['component_php_admin_event']);
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= "\n\t".'}';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] = PHP_EOL.PHP_EOL."\t".'/**';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'* The Global Admin Event Method.';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'**/';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'public static function globalEvent($document)';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'{';
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= PHP_EOL.$this->setPlaceholders($this->customScriptBuilder['component_php_admin_event'], $this->placeholders);
$this->fileContentStatic['###ADMIN_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'}';
}
// now load the readme file if needed
if ($this->componentData->addreadme == 1)
{
$this->fileContentStatic['###EXSTRA_ADMIN_FILES###'] .= "\n\t\t\t<filename>README.txt</filename>";
$this->fileContentStatic['###EXSTRA_ADMIN_FILES###'] .= PHP_EOL."\t\t\t<filename>README.txt</filename>";
}
// ###HELPER_CREATEUSER###
@ -215,6 +209,9 @@ class Infusion extends Interpretation
// start dynamic build
foreach ($this->componentData->admin_views as $view)
{
// just to be safe, lets clear the view placeholders
$this->clearFromPlaceHolders('view');
// set the target
$this->target = 'admin';
$this->lang = 'admin';
// set main keys
@ -252,8 +249,11 @@ class Infusion extends Interpretation
// set some place holder for the views
$this->placeholders['###view###'] = $viewName_single;
$this->placeholders['###VIEW###'] = $viewName_u;
$this->placeholders['###View###'] = $viewName_f;
$this->placeholders['###VIEW###'] = $viewName_u;
$this->placeholders['[[[view]]]'] = $viewName_single;
$this->placeholders['[[[View]]]'] = $viewName_f;
$this->placeholders['[[[VIEW]]]'] = $viewName_u;
// set license per view if needed
$this->setLockLicensePer($viewName_single, $this->target);
@ -287,7 +287,7 @@ class Infusion extends Interpretation
{
// ###DOCUMENT_CUSTOM_PHP### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_single]['###DOCUMENT_CUSTOM_PHP###']
= "\n".str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['php_document'][$viewName_single]);
= PHP_EOL.$this->setPlaceholders($this->customScriptBuilder['php_document'][$viewName_single], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder['php_document'][$viewName_single]);
}
@ -324,16 +324,16 @@ class Infusion extends Interpretation
$this->fileContentDynamic[$viewName_single]['###LINKEDVIEWMETHODS###'] = '';
// ###JMODELADMIN_BEFORE_DELETE### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_single]['###JMODELADMIN_BEFORE_DELETE###'] = $this->getCustomScriptBuilder('php_before_delete', $viewName_single, "\n");
$this->fileContentDynamic[$viewName_single]['###JMODELADMIN_BEFORE_DELETE###'] = $this->getCustomScriptBuilder('php_before_delete', $viewName_single, PHP_EOL);
// ###JMODELADMIN_AFTER_DELETE### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_single]['###JMODELADMIN_AFTER_DELETE###'] = $this->getCustomScriptBuilder('php_after_delete', $viewName_single, "\n\n");
$this->fileContentDynamic[$viewName_single]['###JMODELADMIN_AFTER_DELETE###'] = $this->getCustomScriptBuilder('php_after_delete', $viewName_single, PHP_EOL.PHP_EOL);
// ###JMODELADMIN_BEFORE_DELETE### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_single]['###JMODELADMIN_BEFORE_PUBLISH###'] = $this->getCustomScriptBuilder('php_before_publish', $viewName_single, "\n");
$this->fileContentDynamic[$viewName_single]['###JMODELADMIN_BEFORE_PUBLISH###'] = $this->getCustomScriptBuilder('php_before_publish', $viewName_single, PHP_EOL);
// ###JMODELADMIN_AFTER_DELETE### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_single]['###JMODELADMIN_AFTER_PUBLISH###'] = $this->getCustomScriptBuilder('php_after_publish', $viewName_single, "\n\n");
$this->fileContentDynamic[$viewName_single]['###JMODELADMIN_AFTER_PUBLISH###'] = $this->getCustomScriptBuilder('php_after_publish', $viewName_single, PHP_EOL.PHP_EOL);
// ###CHECKBOX_SAVE### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_single]['###CHECKBOX_SAVE###'] = $this->setCheckboxSave($viewName_single);
@ -342,13 +342,13 @@ class Infusion extends Interpretation
$this->fileContentDynamic[$viewName_single]['###METHOD_ITEM_SAVE###'] = $this->setMethodItemSave($viewName_single);
// ###POSTSAVEHOOK### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_single]['###POSTSAVEHOOK###'] = $this->getCustomScriptBuilder('php_postsavehook', $viewName_single, "\n", null, true, "\n\t\treturn;", "\n\n\t\treturn;");
$this->fileContentDynamic[$viewName_single]['###POSTSAVEHOOK###'] = $this->getCustomScriptBuilder('php_postsavehook', $viewName_single, PHP_EOL, null, true, PHP_EOL."\t\treturn;", PHP_EOL.PHP_EOL."\t\treturn;");
if (isset($this->customScriptBuilder['css_view'][$viewName_single]) && ComponentbuilderHelper::checkString($this->customScriptBuilder['css_view'][$viewName_single]))
{
// ###VIEWCSS### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_single]['###VIEWCSS###']
= str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['css_view'][$viewName_single]);
= $this->setPlaceholders($this->customScriptBuilder['css_view'][$viewName_single], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder['css_view'][$viewName_single]);
}
@ -385,8 +385,11 @@ class Infusion extends Interpretation
// set some place holder for the views
$this->placeholders['###views###'] = $viewName_list;
$this->placeholders['###VIEWS###'] = $viewsName_u;
$this->placeholders['###Views###'] = $viewsName_f;
$this->placeholders['###VIEWS###'] = $viewsName_u;
$this->placeholders['[[[views]]]'] = $viewName_list;
$this->placeholders['[[[Views]]]'] = $viewsName_f;
$this->placeholders['[[[VIEWS]]]'] = $viewsName_u;
// set the export/import option
if ($view['port'])
@ -419,12 +422,14 @@ class Infusion extends Interpretation
// ###CHECKINCALL### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_list]['###CHECKINCALL###'] = '';
}
// ###ADMIN_CUSTOM_BUTTONS_LIST###
$this->fileContentDynamic[$viewName_list]['###ADMIN_CUSTOM_BUTTONS_LIST###'] = $this->setCustomButtons($view, 3, "\t");
// ###GET_ITEMS_METHOD_STRING_FIX### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_list]['###GET_ITEMS_METHOD_STRING_FIX###'] = $this->setGetItemsMethodStringFix($viewName_single,$this->fileContentStatic['###Component###']);
// ###GET_ITEMS_METHOD_AFTER_ALL### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_list]['###GET_ITEMS_METHOD_AFTER_ALL###'] = $this->getCustomScriptBuilder('php_getitems_after_all', $viewName_single, "\n");
$this->fileContentDynamic[$viewName_list]['###GET_ITEMS_METHOD_AFTER_ALL###'] = $this->getCustomScriptBuilder('php_getitems_after_all', $viewName_single, PHP_EOL);
// ###SELECTIONTRANSLATIONFIX### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_list]['###SELECTIONTRANSLATIONFIX###'] = $this->setSelectionTranslationFix($viewName_list,$this->fileContentStatic['###Component###']);
@ -491,7 +496,7 @@ class Infusion extends Interpretation
{
// ###VIEWCSS### <<<DYNAMIC>>>
$this->fileContentDynamic[$viewName_list]['###VIEWSCSS###']
= str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['css_views'][$viewName_list]);
= $this->setPlaceholders($this->customScriptBuilder['css_views'][$viewName_list], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder['css_views'][$viewName_list]);
}
@ -554,7 +559,7 @@ class Infusion extends Interpretation
if ($view['edit_create_site_view'])
{
// add needed router stuff for front edit views
$this->fileContentStatic['###ROUTER_PARSE_SWITCH###'] .= $this->routerParseSwitch($viewName_single);
$this->fileContentStatic['###ROUTER_PARSE_SWITCH###'] .= $this->routerParseSwitch($viewName_single, null, false);
$this->fileContentStatic['###ROUTER_BUILD_VIEWS###'] .= $this->routerBuildViews($viewName_single);
}
@ -623,7 +628,7 @@ class Infusion extends Interpretation
{
// ###CUSTOM_ADMIN_BEFORE_GET_ITEM### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_BEFORE_GET_ITEM###']
= str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_before_getitem'][$view['settings']->code]);
= $this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_before_getitem'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_before_getitem'][$view['settings']->code]);
}
@ -641,7 +646,7 @@ class Infusion extends Interpretation
{
// ###CUSTOM_ADMIN_AFTER_GET_ITEM### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_AFTER_GET_ITEM###']
= str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_after_getitem'][$view['settings']->code]);
= $this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_after_getitem'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_after_getitem'][$view['settings']->code]);
}
@ -661,7 +666,7 @@ class Infusion extends Interpretation
{
// ###CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY###']
= "\n".str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_getlistquery'][$view['settings']->code]);
= PHP_EOL.$this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_getlistquery'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_getlistquery'][$view['settings']->code]);
}
@ -676,7 +681,7 @@ class Infusion extends Interpretation
{
// ###CUSTOM_ADMIN_BEFORE_GET_ITEMS### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_BEFORE_GET_ITEMS###']
= "\n".str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_before_getitems'][$view['settings']->code]);
= PHP_EOL.$this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_before_getitems'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_before_getitems'][$view['settings']->code]);
}
@ -694,7 +699,7 @@ class Infusion extends Interpretation
{
// ###CUSTOM_ADMIN_AFTER_GET_ITEMS### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_AFTER_GET_ITEMS###']
= "\n".str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_after_getitems'][$view['settings']->code]);
= PHP_EOL.$this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_after_getitems'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_after_getitems'][$view['settings']->code]);
}
@ -730,10 +735,10 @@ class Infusion extends Interpretation
}
// ###VIEWARRAY###
$this->fileContentStatic['###VIEWARRAY###'] = "\n".implode(",\n",$viewarray);
$this->fileContentStatic['###VIEWARRAY###'] = PHP_EOL.implode(",".PHP_EOL,$viewarray);
// ###CUSTOM_ADMIN_EDIT_VIEW_ARRAY###
$this->fileContentStatic['###SITE_EDIT_VIEW_ARRAY###'] = "\n".implode(",\n",$site_edit_view_array);
$this->fileContentStatic['###SITE_EDIT_VIEW_ARRAY###'] = PHP_EOL.implode(",".PHP_EOL,$site_edit_view_array);
// ###MAINMENUS###
$this->fileContentStatic['###MAINMENUS###'] = $this->setMainMenus();
@ -890,7 +895,7 @@ class Infusion extends Interpretation
{
// ###SITE_BEFORE_GET_ITEM### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###SITE_BEFORE_GET_ITEM###']
= str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_before_getitem'][$view['settings']->code]);
= $this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_before_getitem'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_before_getitem'][$view['settings']->code]);
}
@ -908,7 +913,7 @@ class Infusion extends Interpretation
{
// ###SITE_AFTER_GET_ITEM### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###SITE_AFTER_GET_ITEM###']
= str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_after_getitem'][$view['settings']->code]);
= $this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_after_getitem'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_after_getitem'][$view['settings']->code]);
}
@ -930,7 +935,7 @@ class Infusion extends Interpretation
{
// ###SITE_BEFORE_GET_ITEMS### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###SITE_BEFORE_GET_ITEMS###']
= "\n".str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_before_getitems'][$view['settings']->code]);
= PHP_EOL.$this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_before_getitems'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_before_getitems'][$view['settings']->code]);
}
@ -948,7 +953,7 @@ class Infusion extends Interpretation
{
// ###SITE_AFTER_GET_ITEMS### <<<DYNAMIC>>>
$this->fileContentDynamic[$view['settings']->code]['###SITE_AFTER_GET_ITEMS###']
= "\n".str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder[$this->target.'_php_after_getitems'][$view['settings']->code]);
= PHP_EOL.$this->setPlaceholders($this->customScriptBuilder[$this->target.'_php_after_getitems'][$view['settings']->code], $this->placeholders);
// clear some memory
unset($this->customScriptBuilder[$this->target.'_php_after_getitems'][$view['settings']->code]);
}
@ -986,7 +991,7 @@ class Infusion extends Interpretation
}
// set site custom script to helper class
// ###SITE_CUSTOM_HELPER_SCRIPT###
$this->fileContentStatic['###SITE_CUSTOM_HELPER_SCRIPT###'] = str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['component_php_helper_site']);
$this->fileContentStatic['###SITE_CUSTOM_HELPER_SCRIPT###'] = $this->setPlaceholders($this->customScriptBuilder['component_php_helper_site'], $this->placeholders);
// ###SITE_GLOBAL_EVENT_HELPER###
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] = '';
// ###SITE_GLOBAL_EVENT###
@ -994,16 +999,16 @@ class Infusion extends Interpretation
// now load the data for the global event if needed
if ($this->componentData->add_site_event == 1)
{
$this->fileContentStatic['###SITE_GLOBAL_EVENT###'] = "\n\n".'// Triger the Global Site Event';
$this->fileContentStatic['###SITE_GLOBAL_EVENT###'] .= "\n".$this->fileContentStatic['###Component###'].'Helper::globalEvent($document);';
$this->fileContentStatic['###SITE_GLOBAL_EVENT###'] = PHP_EOL.PHP_EOL.'// Triger the Global Site Event';
$this->fileContentStatic['###SITE_GLOBAL_EVENT###'] .= PHP_EOL.$this->fileContentStatic['###Component###'].'Helper::globalEvent($document);';
// ###SITE_GLOBAL_EVENT_HELPER###
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] = "\n\n\t".'/**';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= "\n\t".'* The Global Site Event Method.';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= "\n\t".'**/';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= "\n\t".'public static function globalEvent($document)';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= "\n\t".'{';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= "\n".str_replace(array_keys($this->placeholders),array_values($this->placeholders),$this->customScriptBuilder['component_php_site_event']);
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= "\n\t".'}';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] = PHP_EOL.PHP_EOL."\t".'/**';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'* The Global Site Event Method.';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'**/';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'public static function globalEvent($document)';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'{';
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= PHP_EOL.$this->setPlaceholders($this->customScriptBuilder['component_php_site_event'], $this->placeholders);
$this->fileContentStatic['###SITE_GLOBAL_EVENT_HELPER###'] .= PHP_EOL."\t".'}';
}
// setup the layouts
$this->setCustomViewLayouts();
@ -1013,24 +1018,12 @@ class Infusion extends Interpretation
// clear all site folder since none is needed
$this->removeSiteFolder = true;
}
// ###LANG_ADMIN###
$this->fileContentStatic['###LANG_ADMIN###'] = $this->setLangAdmin();
// ###LANG_ADMIN_SYS###
$this->fileContentStatic['###LANG_ADMIN_SYS###'] = $this->setLangAdminSys();
// ###LANG_SITE###
$this->fileContentStatic['###LANG_SITE###'] = $this->setLangSite();
// ###LANG_SITE_SYS###
$this->fileContentStatic['###LANG_SITE_SYS###'] = $this->setLangSiteSys();
// ###PREINSTALLSCRIPT###
$this->fileContentStatic['###PREINSTALLSCRIPT###'] = $this->getCustomScriptBuilder('php_preflight', 'install', "\n", null, true);
$this->fileContentStatic['###PREINSTALLSCRIPT###'] = $this->getCustomScriptBuilder('php_preflight', 'install', PHP_EOL, null, true);
// ###PREUPDATESCRIPT###
$this->fileContentStatic['###PREUPDATESCRIPT###'] = $this->getCustomScriptBuilder('php_preflight', 'update', "\n", null, true);
$this->fileContentStatic['###PREUPDATESCRIPT###'] = $this->getCustomScriptBuilder('php_preflight', 'update', PHP_EOL, null, true);
// ###POSTINSTALLSCRIPT###
$this->fileContentStatic['###POSTINSTALLSCRIPT###'] = $this->setPostInstallScript();
@ -1045,7 +1038,7 @@ class Infusion extends Interpretation
$this->fileContentStatic['###HELPER_UIKIT###'] = $this->setUikitHelperMethods();
// ###CONFIG_FIELDSETS###
$this->fileContentStatic['###CONFIG_FIELDSETS###'] = implode("\n",$this->configFieldSets);
$this->fileContentStatic['###CONFIG_FIELDSETS###'] = implode(PHP_EOL,$this->configFieldSets);
// check if this has been set
if (!isset($this->fileContentStatic['###ROUTER_BUILD_VIEWS###']) || !ComponentbuilderHelper::checkString($this->fileContentStatic['###ROUTER_BUILD_VIEWS###']))
@ -1066,5 +1059,41 @@ class Infusion extends Interpretation
}
return false;
}
/**
* Build the lang values and insert to fiel
*
*
* @return boolean on success
*
*/
public function setLangFileData()
{
// First we build the strings
$lang = array();
// ###LANG_ADMIN###
$lang['###LANG_ADMIN###'] = $this->setLangAdmin();
// ###LANG_ADMIN_SYS###
$lang['###LANG_ADMIN_SYS###'] = $this->setLangAdminSys();
// ###LANG_SITE###
$lang['###LANG_SITE###'] = $this->setLangSite();
// ###LANG_SITE_SYS###
$lang['###LANG_SITE_SYS###'] = $this->setLangSiteSys();
// now we insert the values into the files
if (ComponentbuilderHelper::checkArray($this->langFiles))
{
foreach ($this->langFiles as $file)
{
$string = JFile::read($file['path']);
// load the data
$answer = $this->setPlaceholders($string, $lang, 3);
// add to zip array
$this->writeFile($file['path'],$answer);
// set the line counter
$this->lineCount = $this->lineCount + substr_count($answer, PHP_EOL);
}
}
}
}

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage componentbuilder.php
@ -412,7 +412,10 @@ abstract class ComponentbuilderHelper
{
JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_COMPILER'), 'index.php?option=com_componentbuilder&view=compiler', $submenu === 'compiler');
}
JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_COMPONENTS'), 'index.php?option=com_componentbuilder&view=components', $submenu === 'components');
if ($user->authorise('joomla_component.access', 'com_componentbuilder') && $user->authorise('joomla_component.submenu', 'com_componentbuilder'))
{
JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_JOOMLA_COMPONENTS'), 'index.php?option=com_componentbuilder&view=joomla_components', $submenu === 'joomla_components');
}
if ($user->authorise('admin_view.access', 'com_componentbuilder') && $user->authorise('admin_view.submenu', 'com_componentbuilder'))
{
JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_ADMIN_VIEWS'), 'index.php?option=com_componentbuilder&view=admin_views', $submenu === 'admin_views');
@ -795,13 +798,18 @@ abstract class ComponentbuilderHelper
if (self::checkArray($where))
{
// prep main <-- why? well if $main='' is empty then $table can be categories or users
if (self::checkString($main))
{
$main = '_'.ltrim($main, '_');
}
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
$query->select($db->quoteName(array($what)));
$query->from($db->quoteName('#__'.$main.'_'.$table));
$query->from($db->quoteName('#_'.$main.'_'.$table));
$query->where($db->quoteName($whereString) . ' '.$operator.' (' . implode(',',$where) . ')');
$db->setQuery($query);
$db->execute();
@ -1330,57 +1338,86 @@ abstract class ComponentbuilderHelper
return $string;
}
public static function safeString($string, $type = 'L', $spacer = '_')
public static function safeString($string, $type = 'L', $spacer = '_', $replaceNumbers = true)
{
// remove all numbers and replace with english text version (works well only up to a thousand)
$string = self::replaceNumbers($string);
if ($replaceNumbers === true)
{
// remove all numbers and replace with english text version (works well only up to millions)
$string = self::replaceNumbers($string);
}
// 0nly continue if we have a string
if (self::checkString($string))
{
// remove all other characters
$string = trim($string);
$string = preg_replace('/'.$spacer.'+/', ' ', $string);
$string = preg_replace('/\s+/', ' ', $string);
$string = preg_replace("/[^A-Za-z ]/", '', $string);
// return a string with all first letter of each word uppercase(no undersocre)
if ($type == 'W')
{
return ucwords(strtolower($string));
}
elseif ($type == 'w')
{
return strtolower($string);
}
elseif ($type == 'Ww')
{
return ucfirst(strtolower($string));
}
elseif ($type == 'WW')
{
return strtoupper($string);
}
elseif ($type == 'U')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return all upper
return strtoupper($string);
}
elseif ($type == 'F')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return with first caracter to upper
return ucfirst(strtolower($string));
}
elseif ($type == 'L')
// create file name without the extention that is safe
if ($type === 'filename')
{
// make sure VDM is not in the string
$string = str_replace('VDM', 'vDm', $string);
// Remove anything which isn't a word, whitespace, number
// or any of the following caracters -_()
// If you don't need to handle multi-byte characters
// you can use preg_replace rather than mb_ereg_replace
// Thanks @Łukasz Rysiak!
$string = mb_ereg_replace("([^\w\s\d\-_\(\)])", '', $string);
// http://stackoverflow.com/a/2021729/1429677
return preg_replace('/\s+/', ' ', $string);
}
// remove all other characters
$string = trim($string);
$string = preg_replace('/'.$spacer.'+/', ' ', $string);
$string = preg_replace('/\s+/', ' ', $string);
$string = preg_replace("/[^A-Za-z ]/", '', $string);
// select final adaptations
if ($type === 'L' || $type === 'strtolower')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// default is to return lower
return strtolower($string);
}
elseif ($type === 'W')
{
// return a string with all first letter of each word uppercase(no undersocre)
return ucwords(strtolower($string));
}
elseif ($type === 'w' || $type === 'word')
{
// return a string with all lowercase(no undersocre)
return strtolower($string);
}
elseif ($type === 'Ww' || $type === 'Word')
{
// return a string with first letter of the first word uppercase and all the rest lowercase(no undersocre)
return ucfirst(strtolower($string));
}
elseif ($type === 'WW' || $type === 'WORD')
{
// return a string with all the uppercase(no undersocre)
return strtoupper($string);
}
elseif ($type === 'U' || $type === 'strtoupper')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return all upper
return strtoupper($string);
}
elseif ($type === 'F' || $type === 'ucfirst')
{
// replace white space with underscore
$string = preg_replace('/\s+/', $spacer, $string);
// return with first caracter to upper
return ucfirst(strtolower($string));
}
elseif ($type === 'cA' || $type === 'cAmel' || $type === 'camelcase')
{
// convert all words to first letter uppercase
$string = ucwords(strtolower($string));
// remove white space
$string = preg_replace('/\s+/', '', $string);
// now return first letter lowercase
return lcfirst($string);
}
// return string
return $string;
}

View File

@ -69,12 +69,12 @@ class Mapping
* The datatypes and it linked field types (basic)
* (TODO) We may need to set this dynamicly
*/
protected $dataTypes = array( 'CHAR' => 'Text', 'VARCHAR' => 'Text',
'TEXT' => 'Textarea', 'MEDIUMTEXT' => 'Textarea',
'LONGTEXT' => 'Textarea', 'DATE' => 'Text', 'TIME' => 'Text',
'DATETIME' => 'Calendar', 'INT' => 'Text', 'TINYINT' => 'Text',
'BIGINT' => 'Text', 'FLOAT' => 'Text', 'DECIMAL' => 'Text',
'DOUBLE' => 'Text');
protected $dataTypes = array( 'VARCHAR' => 'Text', 'CHAR' => 'Text',
'MEDIUMTEXT' => 'Textarea', 'LONGTEXT' => 'Textarea',
'TEXT' => 'Textarea', 'DATETIME' => 'Calendar',
'DATE' => 'Text', 'TIME' => 'Text', 'TINYINT' => 'Text',
'BIGINT' => 'Text', 'INT' => 'Text', 'FLOAT' => 'Text',
'DECIMAL' => 'Text', 'DOUBLE' => 'Text');
/**
* The datasize identifiers

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage headercheck.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage batch_.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage indenter.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage js.php

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage minify.php

File diff suppressed because it is too large Load Diff

View File

@ -3,13 +3,13 @@ COM_COMPONENTBUILDER_CONFIGURATION="Component Builder Configuration"
COM_COMPONENTBUILDER_MENU="&#187; Component Builder"
COM_COMPONENTBUILDER_MENU_ADMIN_VIEWS="Admin Views"
COM_COMPONENTBUILDER_MENU_COMPILER="Compiler"
COM_COMPONENTBUILDER_MENU_COMPONENTS="Components"
COM_COMPONENTBUILDER_MENU_CUSTOM_ADMIN_VIEWS="Custom Admin Views"
COM_COMPONENTBUILDER_MENU_CUSTOM_CODES="Custom Codes"
COM_COMPONENTBUILDER_MENU_DYNAMIC_GETS="Dynamic Gets"
COM_COMPONENTBUILDER_MENU_FIELDS="Fields"
COM_COMPONENTBUILDER_MENU_FIELDTYPES="Fieldtypes"
COM_COMPONENTBUILDER_MENU_HELP_DOCUMENTS="Help Documents"
COM_COMPONENTBUILDER_MENU_JOOMLA_COMPONENTS="Joomla Components"
COM_COMPONENTBUILDER_MENU_LAYOUTS="Layouts"
COM_COMPONENTBUILDER_MENU_SITE_VIEWS="Site Views"
COM_COMPONENTBUILDER_MENU_SNIPPETS="Snippets"

View File

@ -10,8 +10,8 @@
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 2.3.0
@build 4th February, 2017
@version 2.3.7
@build 12th March, 2017
@created 30th April, 2015
@package Component Builder
@subpackage css_fullwidth.php

Some files were not shown because too many files have changed in this diff Show More