diff --git a/README.md b/README.md index 3de97d706..c5be8b615 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) 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.9.11) 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.9.13) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -106,10 +106,11 @@ Where can you get support and help? + [German Basic Introduction](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wu0tDFxJtZFwW7AxA4JHQV7) + [Hello World Tutorial](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) + [The JCB! Wiki](https://github.com/vdm-io/Joomla-Component-Builder/wiki) -+ [JCB Google Group/forum](https://vdm.bz/jcb-forum) ++ [Google Group](https://vdm.bz/jcb-forum) + [Report a Security Issue](http://joomlacomponentbuilder.com/report-security-issues) + [Community Complaint](http://joomlacomponentbuilder.com/community-complaint) + [Open Issue On Github](https://github.com/vdm-io/Joomla-Component-Builder/issues) ^^ ++ [Telegram Group](https://t.me/jcb_group) + [JCB IRC Channel](https://vdm.bz/jcb-irc) Since [JCB](http://joomlacomponentbuilder.com) has [become a community](https://github.com/vdm-io/Joomla-Component-Builder/blob/staging/.github/SUPPORT.md) project [VDM.io](https://www.vdm.io/) is **no longer solely responsible** for support. @@ -145,14 +146,14 @@ TODO + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](https://github.com/vdm-io/Joomla-Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 12th February, 2019 -+ *Version*: 2.9.11 ++ *Last Build*: 15th February, 2019 ++ *Version*: 2.9.13 + *Copyright*: Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **195897** -+ *Field count*: **1089** -+ *File count*: **1277** -+ *Folder count*: **201** ++ *Line count*: **202937** ++ *Field count*: **1113** ++ *File count*: **1336** ++ *Folder count*: **209** > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com). > Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) diff --git a/admin/README.txt b/admin/README.txt index 3de97d706..c5be8b615 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -12,7 +12,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) 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.9.11) 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.9.13) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -106,10 +106,11 @@ Where can you get support and help? + [German Basic Introduction](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wu0tDFxJtZFwW7AxA4JHQV7) + [Hello World Tutorial](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) + [The JCB! Wiki](https://github.com/vdm-io/Joomla-Component-Builder/wiki) -+ [JCB Google Group/forum](https://vdm.bz/jcb-forum) ++ [Google Group](https://vdm.bz/jcb-forum) + [Report a Security Issue](http://joomlacomponentbuilder.com/report-security-issues) + [Community Complaint](http://joomlacomponentbuilder.com/community-complaint) + [Open Issue On Github](https://github.com/vdm-io/Joomla-Component-Builder/issues) ^^ ++ [Telegram Group](https://t.me/jcb_group) + [JCB IRC Channel](https://vdm.bz/jcb-irc) Since [JCB](http://joomlacomponentbuilder.com) has [become a community](https://github.com/vdm-io/Joomla-Component-Builder/blob/staging/.github/SUPPORT.md) project [VDM.io](https://www.vdm.io/) is **no longer solely responsible** for support. @@ -145,14 +146,14 @@ TODO + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](https://github.com/vdm-io/Joomla-Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 12th February, 2019 -+ *Version*: 2.9.11 ++ *Last Build*: 15th February, 2019 ++ *Version*: 2.9.13 + *Copyright*: Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **195897** -+ *Field count*: **1089** -+ *File count*: **1277** -+ *Folder count*: **201** ++ *Line count*: **202937** ++ *Field count*: **1113** ++ *File count*: **1336** ++ *Folder count*: **209** > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com). > Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) diff --git a/admin/access.xml b/admin/access.xml index 1dd2545b9..c78fd341a 100644 --- a/admin/access.xml +++ b/admin/access.xml @@ -146,6 +146,16 @@ + + + + + + + + + + @@ -221,7 +231,6 @@ - @@ -339,6 +348,18 @@ + + + + + + + + + + + + @@ -479,6 +500,15 @@ +
+ + + + + + + +
@@ -709,6 +739,17 @@
+
+ + + + + + + + + +
diff --git a/admin/assets/css/component_placeholders.css b/admin/assets/css/component_placeholders.css new file mode 100644 index 000000000..e7aab2271 --- /dev/null +++ b/admin/assets/css/component_placeholders.css @@ -0,0 +1,13 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/* CSS Document */ + + diff --git a/admin/assets/css/components_placeholders.css b/admin/assets/css/components_placeholders.css new file mode 100644 index 000000000..e7aab2271 --- /dev/null +++ b/admin/assets/css/components_placeholders.css @@ -0,0 +1,13 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/* CSS Document */ + + diff --git a/admin/assets/css/placeholder.css b/admin/assets/css/placeholder.css new file mode 100644 index 000000000..e7aab2271 --- /dev/null +++ b/admin/assets/css/placeholder.css @@ -0,0 +1,13 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/* CSS Document */ + + diff --git a/admin/assets/css/placeholders.css b/admin/assets/css/placeholders.css new file mode 100644 index 000000000..e7aab2271 --- /dev/null +++ b/admin/assets/css/placeholders.css @@ -0,0 +1,13 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/* CSS Document */ + + diff --git a/admin/assets/images/icons/fieldtype_add.png b/admin/assets/images/icons/fieldtype_add.png deleted file mode 100644 index 57e356980..000000000 Binary files a/admin/assets/images/icons/fieldtype_add.png and /dev/null differ diff --git a/admin/assets/images/icons/placeholders.png b/admin/assets/images/icons/placeholders.png new file mode 100644 index 000000000..dae19113e Binary files /dev/null and b/admin/assets/images/icons/placeholders.png differ diff --git a/admin/controller.php b/admin/controller.php index 90c05d5cf..8756c8b67 100644 --- a/admin/controller.php +++ b/admin/controller.php @@ -98,6 +98,7 @@ class ComponentbuilderController extends JControllerLegacy 'layout' => 'layouts', 'dynamic_get' => 'dynamic_gets', 'custom_code' => 'custom_codes', + 'placeholder' => 'placeholders', 'library' => 'libraries', 'snippet' => 'snippets', 'validation_rule' => 'validation_rules', @@ -120,6 +121,7 @@ class ComponentbuilderController extends JControllerLegacy 'component_config' => 'components_config', 'component_dashboard' => 'components_dashboard', 'component_files_folders' => 'components_files_folders', + 'component_placeholders' => 'components_placeholders', 'snippet_type' => 'snippet_types', 'library_config' => 'libraries_config', 'library_files_folders_urls' => 'libraries_files_folders_urls' diff --git a/admin/controllers/component_placeholders.php b/admin/controllers/component_placeholders.php new file mode 100644 index 000000000..cb1f83dde --- /dev/null +++ b/admin/controllers/component_placeholders.php @@ -0,0 +1,321 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Component_placeholders Controller + */ +class ComponentbuilderControllerComponent_placeholders extends JControllerForm +{ + /** + * Current or most recently performed task. + * + * @var string + * @since 12.2 + * @note Replaces _task. + */ + protected $task; + + /** + * Class constructor. + * + * @param array $config A named array of configuration variables. + * + * @since 1.6 + */ + public function __construct($config = array()) + { + $this->view_list = 'Components_placeholders'; // safeguard for setting the return view listing to the main view. + parent::__construct($config); + } + + /** + * Method override to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowAdd($data = array()) + { + // Get user object. + $user = JFactory::getUser(); + // Access check. + $access = $user->authorise('component_placeholders.access', 'com_componentbuilder'); + if (!$access) + { + return false; + } + + // In the absense of better information, revert to the component permissions. + return $user->authorise('component_placeholders.create', $this->option); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // get user object. + $user = JFactory::getUser(); + // get record id. + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + + + // Access check. + $access = ($user->authorise('component_placeholders.access', 'com_componentbuilder.component_placeholders.' . (int) $recordId) && $user->authorise('component_placeholders.access', 'com_componentbuilder')); + if (!$access) + { + return false; + } + + if ($recordId) + { + // The record has been set. Check the record permissions. + $permission = $user->authorise('component_placeholders.edit', 'com_componentbuilder.component_placeholders.' . (int) $recordId); + if (!$permission) + { + if ($user->authorise('component_placeholders.edit.own', 'com_componentbuilder.component_placeholders.' . $recordId)) + { + // Now test the owner is the user. + $ownerId = (int) isset($data['created_by']) ? $data['created_by'] : 0; + if (empty($ownerId)) + { + // Need to do a lookup from the model. + $record = $this->getModel()->getItem($recordId); + + if (empty($record)) + { + return false; + } + $ownerId = $record->created_by; + } + + // If the owner matches 'me' then allow. + if ($ownerId == $user->id) + { + if ($user->authorise('component_placeholders.edit.own', 'com_componentbuilder')) + { + return true; + } + } + } + return false; + } + } + // Since there is no permission, revert to the component permissions. + return $user->authorise('component_placeholders.edit', $this->option); + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since 1.6 + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + // get the referral options (old method use return instead see parent) + $ref = $this->input->get('ref', 0, 'string'); + $refid = $this->input->get('refid', 0, 'int'); + + // get redirect info. + $append = parent::getRedirectToItemAppend($recordId, $urlVar); + + // set the referral options + if ($refid && $ref) + { + $append = '&ref=' . (string)$ref . '&refid='. (int)$refid . $append; + } + elseif ($ref) + { + $append = '&ref='. (string)$ref . $append; + } + + return $append; + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 2.5 + */ + public function batch($model = null) + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Component_placeholders', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=components_placeholders' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + + /** + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + * + * @since 12.2 + */ + public function cancel($key = null) + { + // get the referral options + $this->ref = $this->input->get('ref', 0, 'word'); + $this->refid = $this->input->get('refid', 0, 'int'); + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + $cancel = parent::cancel($key); + + if (!is_null($return) && JUri::isInternal(base64_decode($return))) + { + $redirect = base64_decode($return); + + // Redirect to the return value. + $this->setRedirect( + JRoute::_( + $redirect, false + ) + ); + } + elseif ($this->refid && $this->ref) + { + $redirect = '&view=' . (string)$this->ref . '&layout=edit&id=' . (int)$this->refid; + + // Redirect to the item screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . $redirect, false + ) + ); + } + elseif ($this->ref) + { + $redirect = '&view='.(string)$this->ref; + + // Redirect to the list screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . $redirect, false + ) + ); + } + return $cancel; + } + + /** + * Method to save a record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean True if successful, false otherwise. + * + * @since 12.2 + */ + public function save($key = null, $urlVar = null) + { + // get the referral options + $this->ref = $this->input->get('ref', 0, 'word'); + $this->refid = $this->input->get('refid', 0, 'int'); + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + $canReturn = (!is_null($return) && JUri::isInternal(base64_decode($return))); + + if ($this->ref || $this->refid || $canReturn) + { + // to make sure the item is checkedin on redirect + $this->task = 'save'; + } + + $saved = parent::save($key, $urlVar); + + // This is not needed since parent save already does this + // Due to the ref and refid implementation we need to add this + if ($canReturn) + { + $redirect = base64_decode($return); + + // Redirect to the return value. + $this->setRedirect( + JRoute::_( + $redirect, false + ) + ); + } + elseif ($this->refid && $this->ref) + { + $redirect = '&view=' . (string)$this->ref . '&layout=edit&id=' . (int)$this->refid; + + // Redirect to the item screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . $redirect, false + ) + ); + } + elseif ($this->ref) + { + $redirect = '&view=' . (string)$this->ref; + + // Redirect to the list screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . $redirect, false + ) + ); + } + return $saved; + } + + /** + * Function that allows child controller access to model data + * after the data has been saved. + * + * @param JModel &$model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 11.1 + */ + protected function postSaveHook(JModelLegacy $model, $validData = array()) + { + return; + } + +} diff --git a/admin/controllers/components_placeholders.php b/admin/controllers/components_placeholders.php new file mode 100644 index 000000000..2a2112f59 --- /dev/null +++ b/admin/controllers/components_placeholders.php @@ -0,0 +1,43 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Components_placeholders Controller + */ +class ComponentbuilderControllerComponents_placeholders extends JControllerAdmin +{ + /** + * The prefix to use with controller messages. + * + * @var string + * @since 1.6 + */ + protected $text_prefix = 'COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS'; + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JModelLegacy The model. + * + * @since 1.6 + */ + public function getModel($name = 'Component_placeholders', $prefix = 'ComponentbuilderModel', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/admin/controllers/placeholder.php b/admin/controllers/placeholder.php new file mode 100644 index 000000000..f641889a4 --- /dev/null +++ b/admin/controllers/placeholder.php @@ -0,0 +1,321 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Placeholder Controller + */ +class ComponentbuilderControllerPlaceholder extends JControllerForm +{ + /** + * Current or most recently performed task. + * + * @var string + * @since 12.2 + * @note Replaces _task. + */ + protected $task; + + /** + * Class constructor. + * + * @param array $config A named array of configuration variables. + * + * @since 1.6 + */ + public function __construct($config = array()) + { + $this->view_list = 'Placeholders'; // safeguard for setting the return view listing to the main view. + parent::__construct($config); + } + + /** + * Method override to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowAdd($data = array()) + { + // Get user object. + $user = JFactory::getUser(); + // Access check. + $access = $user->authorise('placeholder.access', 'com_componentbuilder'); + if (!$access) + { + return false; + } + + // In the absense of better information, revert to the component permissions. + return $user->authorise('placeholder.create', $this->option); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // get user object. + $user = JFactory::getUser(); + // get record id. + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + + + // Access check. + $access = ($user->authorise('placeholder.access', 'com_componentbuilder.placeholder.' . (int) $recordId) && $user->authorise('placeholder.access', 'com_componentbuilder')); + if (!$access) + { + return false; + } + + if ($recordId) + { + // The record has been set. Check the record permissions. + $permission = $user->authorise('placeholder.edit', 'com_componentbuilder.placeholder.' . (int) $recordId); + if (!$permission) + { + if ($user->authorise('placeholder.edit.own', 'com_componentbuilder.placeholder.' . $recordId)) + { + // Now test the owner is the user. + $ownerId = (int) isset($data['created_by']) ? $data['created_by'] : 0; + if (empty($ownerId)) + { + // Need to do a lookup from the model. + $record = $this->getModel()->getItem($recordId); + + if (empty($record)) + { + return false; + } + $ownerId = $record->created_by; + } + + // If the owner matches 'me' then allow. + if ($ownerId == $user->id) + { + if ($user->authorise('placeholder.edit.own', 'com_componentbuilder')) + { + return true; + } + } + } + return false; + } + } + // Since there is no permission, revert to the component permissions. + return $user->authorise('placeholder.edit', $this->option); + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since 1.6 + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + // get the referral options (old method use return instead see parent) + $ref = $this->input->get('ref', 0, 'string'); + $refid = $this->input->get('refid', 0, 'int'); + + // get redirect info. + $append = parent::getRedirectToItemAppend($recordId, $urlVar); + + // set the referral options + if ($refid && $ref) + { + $append = '&ref=' . (string)$ref . '&refid='. (int)$refid . $append; + } + elseif ($ref) + { + $append = '&ref='. (string)$ref . $append; + } + + return $append; + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 2.5 + */ + public function batch($model = null) + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Placeholder', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=placeholders' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + + /** + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + * + * @since 12.2 + */ + public function cancel($key = null) + { + // get the referral options + $this->ref = $this->input->get('ref', 0, 'word'); + $this->refid = $this->input->get('refid', 0, 'int'); + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + $cancel = parent::cancel($key); + + if (!is_null($return) && JUri::isInternal(base64_decode($return))) + { + $redirect = base64_decode($return); + + // Redirect to the return value. + $this->setRedirect( + JRoute::_( + $redirect, false + ) + ); + } + elseif ($this->refid && $this->ref) + { + $redirect = '&view=' . (string)$this->ref . '&layout=edit&id=' . (int)$this->refid; + + // Redirect to the item screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . $redirect, false + ) + ); + } + elseif ($this->ref) + { + $redirect = '&view='.(string)$this->ref; + + // Redirect to the list screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . $redirect, false + ) + ); + } + return $cancel; + } + + /** + * Method to save a record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean True if successful, false otherwise. + * + * @since 12.2 + */ + public function save($key = null, $urlVar = null) + { + // get the referral options + $this->ref = $this->input->get('ref', 0, 'word'); + $this->refid = $this->input->get('refid', 0, 'int'); + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + $canReturn = (!is_null($return) && JUri::isInternal(base64_decode($return))); + + if ($this->ref || $this->refid || $canReturn) + { + // to make sure the item is checkedin on redirect + $this->task = 'save'; + } + + $saved = parent::save($key, $urlVar); + + // This is not needed since parent save already does this + // Due to the ref and refid implementation we need to add this + if ($canReturn) + { + $redirect = base64_decode($return); + + // Redirect to the return value. + $this->setRedirect( + JRoute::_( + $redirect, false + ) + ); + } + elseif ($this->refid && $this->ref) + { + $redirect = '&view=' . (string)$this->ref . '&layout=edit&id=' . (int)$this->refid; + + // Redirect to the item screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . $redirect, false + ) + ); + } + elseif ($this->ref) + { + $redirect = '&view=' . (string)$this->ref; + + // Redirect to the list screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . $redirect, false + ) + ); + } + return $saved; + } + + /** + * Function that allows child controller access to model data + * after the data has been saved. + * + * @param JModel &$model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 11.1 + */ + protected function postSaveHook(JModelLegacy $model, $validData = array()) + { + return; + } + +} diff --git a/admin/controllers/placeholders.php b/admin/controllers/placeholders.php new file mode 100644 index 000000000..3492372b8 --- /dev/null +++ b/admin/controllers/placeholders.php @@ -0,0 +1,106 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Placeholders Controller + */ +class ComponentbuilderControllerPlaceholders extends JControllerAdmin +{ + /** + * The prefix to use with controller messages. + * + * @var string + * @since 1.6 + */ + protected $text_prefix = 'COM_COMPONENTBUILDER_PLACEHOLDERS'; + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JModelLegacy The model. + * + * @since 1.6 + */ + public function getModel($name = 'Placeholder', $prefix = 'ComponentbuilderModel', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + public function exportData() + { + // Check for request forgeries + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + // check if export is allowed for this user. + $user = JFactory::getUser(); + if ($user->authorise('placeholder.export', 'com_componentbuilder') && $user->authorise('core.export', 'com_componentbuilder')) + { + // Get the input + $input = JFactory::getApplication()->input; + $pks = $input->post->get('cid', array(), 'array'); + // Sanitize the input + JArrayHelper::toInteger($pks); + // Get the model + $model = $this->getModel('Placeholders'); + // 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,'Placeholders_'.$date->format('jS_F_Y'),'Placeholders exported ('.$date->format('jS F, Y').')','placeholders'); + } + } + // Redirect to the list screen with error. + $message = JText::_('COM_COMPONENTBUILDER_EXPORT_FAILED'); + $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=placeholders', false), $message, 'error'); + return; + } + + + public function importData() + { + // Check for request forgeries + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + // check if import is allowed for this user. + $user = JFactory::getUser(); + if ($user->authorise('placeholder.import', 'com_componentbuilder') && $user->authorise('core.import', 'com_componentbuilder')) + { + // Get the import model + $model = $this->getModel('Placeholders'); + // get the headers to import + $headers = $model->getExImPortHeaders(); + if (ComponentbuilderHelper::checkObject($headers)) + { + // Load headers to session. + $session = JFactory::getSession(); + $headers = json_encode($headers); + $session->set('placeholder_VDM_IMPORTHEADERS', $headers); + $session->set('backto_VDM_IMPORT', 'placeholders'); + $session->set('dataType_VDM_IMPORTINTO', 'placeholder'); + // Redirect to import view. + $message = JText::_('COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_PLACEHOLDERS'); + $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=placeholders', false), $message, 'error'); + return; + } +} diff --git a/admin/helpers/compiler/a_Get.php b/admin/helpers/compiler/a_Get.php index 43ef444b7..c48ea2cf1 100644 --- a/admin/helpers/compiler/a_Get.php +++ b/admin/helpers/compiler/a_Get.php @@ -53,6 +53,13 @@ class Get */ public $params; + /** + * The global placeholders + * + * @var array + */ + public $globalPlaceholders = array(); + /** * The placeholders * @@ -781,6 +788,8 @@ class Get $this->user = JFactory::getUser(); // Get a db connection. $this->db = JFactory::getDbo(); + // get global placeholders + $this->globalPlaceholders = $this->getGlobalPlaceholders(); // check if this component is install on the current website if ($paths = $this->getLocalInstallPaths()) { @@ -857,6 +866,36 @@ class Get return ''; } + /** + * get all System Placeholders + * + * @return array The global placeholders + * + */ + public function getGlobalPlaceholders() + { + // reset bucket + $bucket = array(); + // Create a new query object. + $query = $this->db->getQuery(true); + $query->select($this->db->quoteName(array('a.target','a.value'))); + // from these tables + $query->from('#__componentbuilder_placeholder AS a'); + // Reset the query using our newly populated query object. + $this->db->setQuery($query); + // Load the items + $this->db->execute(); + if ($this->db->getNumRows()) + { + $bucket = $this->db->loadAssocList('target', 'value'); + foreach ($bucket as $key => &$code) + { + $code = base64_decode($code); + } + } + return $bucket; + } + /** * get all Component Data * @@ -888,7 +927,8 @@ class Get 'i.php_dashboard_methods', 'f.sql_tweak', 'e.version_update', - 'e.id' + 'e.id', + 'k.addplaceholders' ), array( 'addadmin_views', 'addadmin_views_id', @@ -904,7 +944,8 @@ class Get 'php_dashboard_methods', 'sql_tweak', 'version_update', - 'version_update_id' + 'version_update_id', + '_placeholders' ) ) ); @@ -919,6 +960,7 @@ class Get $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_config', 'h') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('h.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_dashboard', 'i') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('i.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_files_folders', 'j') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('j.joomla_component') . ')'); + $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_placeholders', 'k') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('k.joomla_component') . ')'); $query->where($this->db->quoteName('a.id') . ' = ' . (int) $this->componentID); // Reset the query using our newly populated query object. @@ -971,6 +1013,26 @@ class Get $this->placeholders[$this->bbb . 'Component' . $this->ddd] = $this->placeholders[$this->hhh . 'Component' . $this->hhh]; $this->placeholders[$this->bbb . 'COMPONENT' . $this->ddd] = $this->placeholders[$this->hhh . 'COMPONENT' . $this->hhh]; + // set the addcustommenus data + $component->_placeholders = (isset($component->_placeholders) && ComponentbuilderHelper::checkJson($component->_placeholders)) ? json_decode($component->_placeholders, true) : null; + if (ComponentbuilderHelper::checkArray($component->_placeholders)) + { + foreach($component->_placeholders as $row) + { + $this->globalPlaceholders[$row['target']] = $row['value']; + } + } + unset($component->_placeholders); + + // load the global placeholders + if (ComponentbuilderHelper::checkArray($this->globalPlaceholders)) + { + foreach ($this->globalPlaceholders as $globalPlaceholder => $gloabalValue) + { + $this->placeholders[$globalPlaceholder] = $gloabalValue; + } + } + // set component sales name $component->sales_name = ComponentbuilderHelper::safeString($component->system_name); @@ -2810,7 +2872,7 @@ class Get if (strpos($requeSt_id, '_request_id') !== false || strpos($requeSt_id, '_request_catid') !== false) { // keep it then, don't change - $name = $requeSt_id; + $name = $this->setPlaceholders($requeSt_id, $this->placeholders); } else { @@ -2846,7 +2908,7 @@ class Get else { // get value from xml - $xml = ComponentbuilderHelper::safeString(ComponentbuilderHelper::getBetween($field['settings']->xml, 'name="', '"')); + $xml = ComponentbuilderHelper::safeString($this->setPlaceholders(ComponentbuilderHelper::getBetween($field['settings']->xml, 'name="', '"'), $this->placeholders)); // check if a value was found if (ComponentbuilderHelper::checkString($xml)) { @@ -5662,6 +5724,7 @@ class Get $placeholders[ComponentbuilderHelper::safeString($this->componentCodeName, 'F') . 'Helper::'] = $this->bbb . 'Component' . $this->ddd . 'Helper::'; $placeholders['COM_' . ComponentbuilderHelper::safeString($this->componentCodeName, 'U')] = 'COM_' . $this->bbb . 'COMPONENT' . $this->ddd; $placeholders['com_' . $this->componentCodeName] = 'com_' . $this->bbb . 'component' . $this->ddd; + foreach ($paths as $target => $path) { // we are changing the working directory to the componet path diff --git a/admin/helpers/compiler/c_Fields.php b/admin/helpers/compiler/c_Fields.php index 34f689c2d..9e0f836a2 100644 --- a/admin/helpers/compiler/c_Fields.php +++ b/admin/helpers/compiler/c_Fields.php @@ -2295,7 +2295,7 @@ class Fields extends Structure else { // set the rest of the fields - $xmlValue = (string) ComponentbuilderHelper::getBetween($field['settings']->xml, $property['name'] . '="', '"'); + $xmlValue = (string) $this->setPlaceholders(ComponentbuilderHelper::getBetween($field['settings']->xml, $property['name'] . '="', '"'), $placeholders); } // check if translatable @@ -2872,6 +2872,14 @@ class Fields extends Structure // now set the value $replace[$replacekey] = $replacevalue; } + // load the global placeholders + if (ComponentbuilderHelper::checkArray($this->globalPlaceholders)) + { + foreach ($this->globalPlaceholders as $globalPlaceholder => $gloabalValue) + { + $replace[$globalPlaceholder] = $gloabalValue; + } + } // start loading the field type $this->fileContentDynamic['customfield_' . $data['type']] = array(); // Type <<>> diff --git a/admin/helpers/compiler/e_Interpretation.php b/admin/helpers/compiler/e_Interpretation.php index 9ec391f36..6ae77e63b 100644 --- a/admin/helpers/compiler/e_Interpretation.php +++ b/admin/helpers/compiler/e_Interpretation.php @@ -13645,10 +13645,26 @@ class Interpretation extends Fields $component = ComponentbuilderHelper::safeString($this->componentData->name_code); $viewName = 'config'; $listViewName = 'configs'; - $placeholders = array( - $this->hhh . 'component' . $this->hhh => $component, - $this->hhh . 'view' . $this->hhh => $viewName, - $this->hhh . 'views' . $this->hhh => $listViewName); + // set place holders + $placeholders = array(); + $placeholders[$this->hhh . 'component' . $this->hhh] = ComponentbuilderHelper::safeString($this->componentData->name_code); + $placeholders[$this->hhh . 'Component' . $this->hhh] = ComponentbuilderHelper::safeString($this->componentData->name_code, 'F'); + $placeholders[$this->hhh . 'COMPONENT' . $this->hhh] = ComponentbuilderHelper::safeString($this->componentData->name_code, 'U'); + $placeholders[$this->hhh . 'view' . $this->hhh] = $viewName; + $placeholders[$this->hhh . 'views' . $this->hhh] = $listViewName; + $placeholders[$this->bbb . 'component' . $this->ddd] = $placeholders[$this->hhh . 'component' . $this->hhh]; + $placeholders[$this->bbb . 'Component' . $this->ddd] = $placeholders[$this->hhh . 'Component' . $this->hhh]; + $placeholders[$this->bbb . 'COMPONENT' . $this->ddd] = $placeholders[$this->hhh . 'COMPONENT' . $this->hhh]; + $placeholders[$this->bbb . 'view' . $this->ddd] = $viewName; + $placeholders[$this->bbb . 'views' . $this->ddd] = $listViewName; + // load the global placeholders + if (ComponentbuilderHelper::checkArray($this->globalPlaceholders)) + { + foreach ($this->globalPlaceholders as $globalPlaceholder => $gloabalValue) + { + $placeholders[$globalPlaceholder] = $gloabalValue; + } + } $view = ''; $viewType = 0; // set the custom table key @@ -13676,8 +13692,8 @@ class Interpretation extends Fields { $this->configFieldSetsCustomField[$field['tabname']][] = $xmlField; // set global params to db on install - $fieldName = ComponentbuilderHelper::safeString(ComponentbuilderHelper::getBetween($xmlField, 'name="', '"')); - $fieldDefault = ComponentbuilderHelper::getBetween($xmlField, 'default="', '"'); + $fieldName = ComponentbuilderHelper::safeString($this->setPlaceholders(ComponentbuilderHelper::getBetween($xmlField, 'name="', '"'), $placeholders)); + $fieldDefault = $this->setPlaceholders(ComponentbuilderHelper::getBetween($xmlField, 'default="', '"'), $placeholders); if (isset($field['custom_value']) && ComponentbuilderHelper::checkString($field['custom_value'])) { // add array if found diff --git a/admin/helpers/compiler/f_Infusion.php b/admin/helpers/compiler/f_Infusion.php index e5a1d0663..61062975d 100644 --- a/admin/helpers/compiler/f_Infusion.php +++ b/admin/helpers/compiler/f_Infusion.php @@ -213,6 +213,15 @@ class Infusion extends Interpretation // add the helper emailer if set $this->fileContentStatic[$this->hhh . 'HELPER_EMAIL' . $this->hhh] = $this->addEmailHelper(); + // load the global placeholders + if (ComponentbuilderHelper::checkArray($this->globalPlaceholders)) + { + foreach ($this->globalPlaceholders as $globalPlaceholder => $gloabalValue) + { + $this->fileContentStatic[$globalPlaceholder] = $gloabalValue; + } + } + // reset view array $viewarray = array(); $site_edit_view_array = array(); diff --git a/admin/helpers/componentbuilder.php b/admin/helpers/componentbuilder.php index 35d3dbfbb..12ff6336c 100644 --- a/admin/helpers/componentbuilder.php +++ b/admin/helpers/componentbuilder.php @@ -1179,6 +1179,20 @@ abstract class ComponentbuilderHelper return false; } + /** + * validate that a placeholder is unique + **/ + public static function validateUniquePlaceholder($string) + { + $string = self::safeString($string); + // this list may grow as we find more cases that break the compiler (just open an issue on github) + if (in_array($string, array('component', 'view', 'views'))) + { + return false; + } + return true; + } + /** * The array of dynamic content * @@ -4476,6 +4490,10 @@ abstract class ComponentbuilderHelper { JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_CUSTOM_CODES'), 'index.php?option=com_componentbuilder&view=custom_codes', $submenu === 'custom_codes'); } + if ($user->authorise('placeholder.access', 'com_componentbuilder') && $user->authorise('placeholder.submenu', 'com_componentbuilder')) + { + JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_PLACEHOLDERS'), 'index.php?option=com_componentbuilder&view=placeholders', $submenu === 'placeholders'); + } if ($user->authorise('library.access', 'com_componentbuilder') && $user->authorise('library.submenu', 'com_componentbuilder')) { JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_LIBRARIES'), 'index.php?option=com_componentbuilder&view=libraries', $submenu === 'libraries'); diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index 8a5c5cd38..6dbf5bc61 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -1723,6 +1723,46 @@ COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_N_ITEMS_UNFEATURED="%s Components m COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_N_ITEMS_UNFEATURED_1="%s Component mysql Tweaks unfeatured." COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_N_ITEMS_UNPUBLISHED="%s Components mysql Tweaks unpublished." COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_N_ITEMS_UNPUBLISHED_1="%s Component mysql Tweaks unpublished." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS="Components Placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_ACCESS="Components Placeholders Access" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_ACCESS_DESC="Allows the users in this group to access access components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_OPTIONS="Batch process the selected Components Placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_TIP="All changes will be applied to all selected Components Placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE="Components Placeholders Batch Use" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_CREATE="Components Placeholders Create" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_CREATE_DESC="Allows the users in this group to create create components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_DELETE="Components Placeholders Delete" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_DELETE_DESC="Allows the users in this group to delete delete components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT="Components Placeholders Edit" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_CREATED_BY="Components Placeholders Edit Created By" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_CREATED_BY_DESC="Allows the users in this group to update the created by of the edit created by components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_CREATED_DATE="Components Placeholders Edit Created Date" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_CREATED_DATE_DESC="Allows the users in this group to update the created date of the edit created components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_DESC="Allows the users in this group to edit the component placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_OWN="Components Placeholders Edit Own" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_OWN_DESC="Allows the users in this group to edit edit own components placeholders created by them" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_STATE="Components Placeholders Edit State" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION="Components Placeholders Edit Version" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_ARCHIVED="%s Components Placeholders archived." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_ARCHIVED_1="%s Component Placeholders archived." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_CHECKED_IN_0="No Component Placeholders successfully checked in." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_CHECKED_IN_1="%d Component Placeholders successfully checked in." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_CHECKED_IN_MORE="%d Components Placeholders successfully checked in." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_DELETED="%s Components Placeholders deleted." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_DELETED_1="%s Component Placeholders deleted." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_FEATURED="%s Components Placeholders featured." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_FEATURED_1="%s Component Placeholders featured." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_PUBLISHED="%s Components Placeholders published." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_PUBLISHED_1="%s Component Placeholders published." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_TRASHED="%s Components Placeholders trashed." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_TRASHED_1="%s Component Placeholders trashed." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_UNFEATURED="%s Components Placeholders unfeatured." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_UNFEATURED_1="%s Component Placeholders unfeatured." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_UNPUBLISHED="%s Components Placeholders unpublished." +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_UNPUBLISHED_1="%s Component Placeholders unpublished." COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS="Components Site Views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_ACCESS="Components Site Views Access" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_ACCESS_DESC="Allows the users in this group to access access components site views" @@ -2602,6 +2642,41 @@ COM_COMPONENTBUILDER_COMPONENT_MYSQL_TWEAKS_TWEAKS="Tweaks" COM_COMPONENTBUILDER_COMPONENT_MYSQL_TWEAKS_VERSION_DESC="A count of the number of times this Component mysql Tweaks has been revised." COM_COMPONENTBUILDER_COMPONENT_MYSQL_TWEAKS_VERSION_LABEL="Revision" COM_COMPONENTBUILDER_COMPONENT_MYSQL_TWEAKS_YES_INCLUDE_BASED_ON_OPTIONS="Yes include based on options" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS="Component Placeholders" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_ADDPLACEHOLDERS="Addplaceholders" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_ADDPLACEHOLDERS_DESCRIPTION="Set dnamic placeholders for this component." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_ADDPLACEHOLDERS_LABEL="Placeholders" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_CREATED_BY_DESC="The user that created this Component Placeholders." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_CREATED_BY_LABEL="Created By" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_CREATED_DATE_DESC="The date this Component Placeholders was created." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_CREATED_DATE_LABEL="Created Date" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_DETAILS="Details" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_EDIT="Editing the Component Placeholders" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_ERROR_UNIQUE_ALIAS="Another Component Placeholders has the same alias." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_ID="Id" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_JOOMLA_COMPONENT="Joomla Component" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_JOOMLA_COMPONENT_DESCRIPTION="Select a Joomla Component" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_JOOMLA_COMPONENT_LABEL="Component" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_MODIFIED_BY_DESC="The last user that modified this Component Placeholders." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_MODIFIED_BY_LABEL="Modified By" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_MODIFIED_DATE_DESC="The date this Component Placeholders was modified." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_MODIFIED_DATE_LABEL="Modified Date" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_NEW="A New Component Placeholders" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_ORDERING_LABEL="Ordering" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_PERMISSION="Permissions" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_PUBLISHING="Publishing" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the Component Placeholders to customise the alias." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_STATUS="Status" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_TARGET_DESCRIPTION="Set the text you would like to target as a placeholder" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_TARGET_HINT="[[[core]]]" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_TARGET_LABEL="Target String Placeholder" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_TARGET_MESSAGE="Error! That target placeholder text already exist. Please add an unique placeholder target." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_VALUE_DESCRIPTION="Set the text you would like to set as the replacement value for the targeted placeholder." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_VALUE_HINT="membersmanager" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_VALUE_LABEL="Set String Value" +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_VALUE_MESSAGE="Error! Please add some set target value here." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_VERSION_DESC="A count of the number of times this Component Placeholders has been revised." +COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_VERSION_LABEL="Revision" COM_COMPONENTBUILDER_COMPONENT_SITE_VIEWS="Component Site Views" COM_COMPONENTBUILDER_COMPONENT_SITE_VIEWS_ACCESS_DESCRIPTION="Select if this view
should use access." COM_COMPONENTBUILDER_COMPONENT_SITE_VIEWS_ACCESS_LABEL="Add Access" @@ -3776,7 +3851,6 @@ COM_COMPONENTBUILDER_DASHBOARD_FIELDS="Fields

" COM_COMPONENTBUILDER_DASHBOARD_FIELDS_CATID="Category  For
Fields" COM_COMPONENTBUILDER_DASHBOARD_FIELDTYPES="Fieldtypes

" COM_COMPONENTBUILDER_DASHBOARD_FIELDTYPES_CATID="Category  For
Fieldtypes" -COM_COMPONENTBUILDER_DASHBOARD_FIELDTYPE_ADD="Add Fieldtype

" COM_COMPONENTBUILDER_DASHBOARD_FIELD_ADD="Add Field

" COM_COMPONENTBUILDER_DASHBOARD_GET_SNIPPETS="Get Snippets

" COM_COMPONENTBUILDER_DASHBOARD_HELP_DOCUMENTS="Help Documents

" @@ -3788,6 +3862,7 @@ COM_COMPONENTBUILDER_DASHBOARD_LAYOUTS="Layouts

" COM_COMPONENTBUILDER_DASHBOARD_LAYOUT_ADD="Add Layout

" COM_COMPONENTBUILDER_DASHBOARD_LIBRARIES="Libraries

" COM_COMPONENTBUILDER_DASHBOARD_LIST_OF_RECORDS="Dashboard (list of records)" +COM_COMPONENTBUILDER_DASHBOARD_PLACEHOLDERS="Placeholders

" COM_COMPONENTBUILDER_DASHBOARD_SERVERS="Servers

" COM_COMPONENTBUILDER_DASHBOARD_SITE_VIEWS="Site Views

" COM_COMPONENTBUILDER_DASHBOARD_SITE_VIEW_ADD="Add Site View

" @@ -4226,8 +4301,6 @@ COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE="Fieldtypes Batch Use" COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_CREATE="Fieldtypes Create" COM_COMPONENTBUILDER_FIELDTYPES_CREATE_DESC="Allows the users in this group to create create fieldtypes" -COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_ADD="Fieldtypes Dashboard Add" -COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_ADD_DESC="Allows the users in this group to dashboard add of fieldtype" COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_LIST="Fieldtypes Dashboard List" COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of fieldtype" COM_COMPONENTBUILDER_FIELDTYPES_DELETE="Fieldtypes Delete" @@ -4764,6 +4837,7 @@ COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_JOOMLA_COMPONENTS="Select the file t COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_LANGUAGES="Select the file to import data to languages." COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_LANGUAGE_TRANSLATIONS="Select the file to import data to language_translations." COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_LAYOUTS="Select the file to import data to layouts." +COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_PLACEHOLDERS="Select the file to import data to placeholders." COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_SERVERS="Select the file to import data to servers." COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_SITE_VIEWS="Select the file to import data to site_views." COM_COMPONENTBUILDER_IMPORT_SELECT_FILE_FOR_SNIPPETS="Select the file to import data to snippets." @@ -6011,8 +6085,83 @@ COM_COMPONENTBUILDER_PAIDLOCKED="Paid/Locked" COM_COMPONENTBUILDER_PATH_CODESCODE="Path: %s" COM_COMPONENTBUILDER_PATH_TO_THE_ZIPPED_PACKAGE_IS_CODESCODE_BR_S_S="Path to the zipped package is: %s
%s %s" COM_COMPONENTBUILDER_PERMISSIONS="Permissions" +COM_COMPONENTBUILDER_PLACEHOLDER="Placeholder" +COM_COMPONENTBUILDER_PLACEHOLDERS="Placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS="Placeholders Access" +COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS_DESC="Allows the users in this group to access access placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_OPTIONS="Batch process the selected Placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_TIP="All changes will be applied to all selected Placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE="Placeholders Batch Use" +COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_CREATE="Placeholders Create" +COM_COMPONENTBUILDER_PLACEHOLDERS_CREATE_DESC="Allows the users in this group to create create placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_DASHBOARD_LIST="Placeholders Dashboard List" +COM_COMPONENTBUILDER_PLACEHOLDERS_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of placeholder" +COM_COMPONENTBUILDER_PLACEHOLDERS_DELETE="Placeholders Delete" +COM_COMPONENTBUILDER_PLACEHOLDERS_DELETE_DESC="Allows the users in this group to delete delete placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT="Placeholders Edit" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_DESC="Allows the users in this group to edit the placeholder" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_OWN="Placeholders Edit Own" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_OWN_DESC="Allows the users in this group to edit edit own placeholders created by them" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_STATE="Placeholders Edit State" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the placeholder" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION="Placeholders Edit Version" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_EXPORT="Placeholders Export" +COM_COMPONENTBUILDER_PLACEHOLDERS_EXPORT_DESC="Allows the users in this group to export export placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_IMPORT="Placeholders Import" +COM_COMPONENTBUILDER_PLACEHOLDERS_IMPORT_DESC="Allows the users in this group to import import placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_ARCHIVED="%s Placeholders archived." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_ARCHIVED_1="%s Placeholder archived." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_CHECKED_IN_0="No Placeholder successfully checked in." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_CHECKED_IN_1="%d Placeholder successfully checked in." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_CHECKED_IN_MORE="%d Placeholders successfully checked in." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_DELETED="%s Placeholders deleted." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_DELETED_1="%s Placeholder deleted." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_FEATURED="%s Placeholders featured." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_FEATURED_1="%s Placeholder featured." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_PUBLISHED="%s Placeholders published." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_PUBLISHED_1="%s Placeholder published." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_TRASHED="%s Placeholders trashed." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_TRASHED_1="%s Placeholder trashed." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_UNFEATURED="%s Placeholders unfeatured." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_UNFEATURED_1="%s Placeholder unfeatured." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_UNPUBLISHED="%s Placeholders unpublished." +COM_COMPONENTBUILDER_PLACEHOLDERS_N_ITEMS_UNPUBLISHED_1="%s Placeholder unpublished." COM_COMPONENTBUILDER_PLACEHOLDERS_REMOVED="Placeholders Removed!" +COM_COMPONENTBUILDER_PLACEHOLDERS_SUBMENU="Placeholders Submenu" +COM_COMPONENTBUILDER_PLACEHOLDERS_SUBMENU_DESC="Allows the users in this group to submenu of placeholder" +COM_COMPONENTBUILDER_PLACEHOLDER_CREATED_BY_DESC="The user that created this Placeholder." +COM_COMPONENTBUILDER_PLACEHOLDER_CREATED_BY_LABEL="Created By" +COM_COMPONENTBUILDER_PLACEHOLDER_CREATED_DATE_DESC="The date this Placeholder was created." +COM_COMPONENTBUILDER_PLACEHOLDER_CREATED_DATE_LABEL="Created Date" +COM_COMPONENTBUILDER_PLACEHOLDER_DETAILS="Details" +COM_COMPONENTBUILDER_PLACEHOLDER_EDIT="Editing the Placeholder" +COM_COMPONENTBUILDER_PLACEHOLDER_ERROR_UNIQUE_ALIAS="Another Placeholder has the same alias." +COM_COMPONENTBUILDER_PLACEHOLDER_ID="Id" +COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_BY_DESC="The last user that modified this Placeholder." +COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_BY_LABEL="Modified By" +COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_DATE_DESC="The date this Placeholder was modified." +COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_DATE_LABEL="Modified Date" +COM_COMPONENTBUILDER_PLACEHOLDER_NEW="A New Placeholder" +COM_COMPONENTBUILDER_PLACEHOLDER_ORDERING_LABEL="Ordering" +COM_COMPONENTBUILDER_PLACEHOLDER_PERMISSION="Permissions" +COM_COMPONENTBUILDER_PLACEHOLDER_PUBLISHING="Publishing" COM_COMPONENTBUILDER_PLACEHOLDER_REMOVED="Placeholder Removed!" +COM_COMPONENTBUILDER_PLACEHOLDER_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the Placeholder to customise the alias." +COM_COMPONENTBUILDER_PLACEHOLDER_STATUS="Status" +COM_COMPONENTBUILDER_PLACEHOLDER_TARGET="Target" +COM_COMPONENTBUILDER_PLACEHOLDER_TARGET_DESCRIPTION="Set the text you would like to target as a placeholder" +COM_COMPONENTBUILDER_PLACEHOLDER_TARGET_HINT="[[[core]]]" +COM_COMPONENTBUILDER_PLACEHOLDER_TARGET_LABEL="Target String Placeholder" +COM_COMPONENTBUILDER_PLACEHOLDER_TARGET_MESSAGE="Error! That target placeholder text already exist. Please add an unique placeholder target." +COM_COMPONENTBUILDER_PLACEHOLDER_VALUE="Value" +COM_COMPONENTBUILDER_PLACEHOLDER_VALUE_DESCRIPTION="Set the text you would like to set as the replacement value for the targeted placeholder." +COM_COMPONENTBUILDER_PLACEHOLDER_VALUE_HINT="membersmanager" +COM_COMPONENTBUILDER_PLACEHOLDER_VALUE_LABEL="Set String Value" +COM_COMPONENTBUILDER_PLACEHOLDER_VALUE_MESSAGE="Error! Please add some set target value here." +COM_COMPONENTBUILDER_PLACEHOLDER_VERSION_DESC="A count of the number of times this Placeholder has been revised." +COM_COMPONENTBUILDER_PLACEHOLDER_VERSION_LABEL="Revision" COM_COMPONENTBUILDER_PLACES_ACROSS_JCB_WHERE_THIS_S_IS_LINKED="Places across JCB where this %s is linked." COM_COMPONENTBUILDER_PLEASE_ADD_FILES_TO_S="Please add files to (%s)" COM_COMPONENTBUILDER_PLEASE_ADD_FOLDERS_TO_S="Please add folders to (%s)" @@ -6890,6 +7039,7 @@ COM_COMPONENTBUILDER_SUBMENU_LANGUAGES="Languages" COM_COMPONENTBUILDER_SUBMENU_LANGUAGE_TRANSLATIONS="Language Translations" COM_COMPONENTBUILDER_SUBMENU_LAYOUTS="Layouts" COM_COMPONENTBUILDER_SUBMENU_LIBRARIES="Libraries" +COM_COMPONENTBUILDER_SUBMENU_PLACEHOLDERS="Placeholders" COM_COMPONENTBUILDER_SUBMENU_SERVERS="Servers" COM_COMPONENTBUILDER_SUBMENU_SITE_VIEWS="Site Views" COM_COMPONENTBUILDER_SUBMENU_SNIPPETS="Snippets" @@ -7058,6 +7208,7 @@ COM_COMPONENTBUILDER_THE_COMPONENT_CUSTOM_ADMIN_VIEWS="The component custom admi COM_COMPONENTBUILDER_THE_COMPONENT_DASHBOARD="The component dashboard" COM_COMPONENTBUILDER_THE_COMPONENT_FILES_FOLDERS="The component files & folders" COM_COMPONENTBUILDER_THE_COMPONENT_MYSQL_TWEAKS="The component mysql tweaks" +COM_COMPONENTBUILDER_THE_COMPONENT_PLACEHOLDERS="The component placeholders" COM_COMPONENTBUILDER_THE_COMPONENT_SITE_VIEWS="The component site views" COM_COMPONENTBUILDER_THE_COMPONENT_UPDATES="The component updates" COM_COMPONENTBUILDER_THE_COMPONENT_WITH_ALL_LINKED_ADMIN_VIEWS_FIELDS_LINKED_TO_ADMIN_VIEWS_CUSTOM_ADMIN_VIEWS_SITE_VIEWS_TEMPLATES_AND_LAYOUTS_WERE_CLONED_SUCCESSFUL="The Component with all linked admin views, fields linked to admin views, custom admin views, site views, templates and layouts were cloned successful!" diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini index 8cf3736f7..8a2e9fd9f 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini @@ -261,6 +261,26 @@ COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_STATE="Components Mysql Tweaks COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_VERSION="Components Mysql Tweaks Edit Version" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components mysql tweaks" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_ACCESS="Components Placeholders Access" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_ACCESS_DESC="Allows the users in this group to access access components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE="Components Placeholders Batch Use" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_CREATE="Components Placeholders Create" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_CREATE_DESC="Allows the users in this group to create create components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_DELETE="Components Placeholders Delete" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_DELETE_DESC="Allows the users in this group to delete delete components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT="Components Placeholders Edit" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_CREATED_BY="Components Placeholders Edit Created By" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_CREATED_BY_DESC="Allows the users in this group to update the created by of the edit created by components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_CREATED_DATE="Components Placeholders Edit Created Date" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_CREATED_DATE_DESC="Allows the users in this group to update the created date of the edit created components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_DESC="Allows the users in this group to edit the component placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_OWN="Components Placeholders Edit Own" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_OWN_DESC="Allows the users in this group to edit edit own components placeholders created by them" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_STATE="Components Placeholders Edit State" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION="Components Placeholders Edit Version" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components placeholders" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_ACCESS="Components Site Views Access" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_ACCESS_DESC="Allows the users in this group to access access components site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_USE="Components Site Views Batch Use" @@ -428,8 +448,6 @@ COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE="Fieldtypes Batch Use" COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_CREATE="Fieldtypes Create" COM_COMPONENTBUILDER_FIELDTYPES_CREATE_DESC="Allows the users in this group to create create fieldtypes" -COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_ADD="Fieldtypes Dashboard Add" -COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_ADD_DESC="Allows the users in this group to dashboard add of fieldtype" COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_LIST="Fieldtypes Dashboard List" COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of fieldtype" COM_COMPONENTBUILDER_FIELDTYPES_DELETE="Fieldtypes Delete" @@ -691,10 +709,35 @@ COM_COMPONENTBUILDER_MENU_JOOMLA_COMPONENTS="Joomla Components" COM_COMPONENTBUILDER_MENU_LANGUAGE_TRANSLATIONS="Language Translations" COM_COMPONENTBUILDER_MENU_LAYOUTS="Layouts" COM_COMPONENTBUILDER_MENU_LIBRARIES="Libraries" +COM_COMPONENTBUILDER_MENU_PLACEHOLDERS="Placeholders" COM_COMPONENTBUILDER_MENU_SITE_VIEWS="Site Views" COM_COMPONENTBUILDER_MENU_SNIPPETS="Snippets" COM_COMPONENTBUILDER_MENU_TEMPLATES="Templates" COM_COMPONENTBUILDER_MENU_VALIDATION_RULES="Validation Rules" +COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS="Placeholders Access" +COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS_DESC="Allows the users in this group to access access placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE="Placeholders Batch Use" +COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_CREATE="Placeholders Create" +COM_COMPONENTBUILDER_PLACEHOLDERS_CREATE_DESC="Allows the users in this group to create create placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_DASHBOARD_LIST="Placeholders Dashboard List" +COM_COMPONENTBUILDER_PLACEHOLDERS_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of placeholder" +COM_COMPONENTBUILDER_PLACEHOLDERS_DELETE="Placeholders Delete" +COM_COMPONENTBUILDER_PLACEHOLDERS_DELETE_DESC="Allows the users in this group to delete delete placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT="Placeholders Edit" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_DESC="Allows the users in this group to edit the placeholder" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_OWN="Placeholders Edit Own" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_OWN_DESC="Allows the users in this group to edit edit own placeholders created by them" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_STATE="Placeholders Edit State" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the placeholder" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION="Placeholders Edit Version" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_EXPORT="Placeholders Export" +COM_COMPONENTBUILDER_PLACEHOLDERS_EXPORT_DESC="Allows the users in this group to export export placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_IMPORT="Placeholders Import" +COM_COMPONENTBUILDER_PLACEHOLDERS_IMPORT_DESC="Allows the users in this group to import import placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_SUBMENU="Placeholders Submenu" +COM_COMPONENTBUILDER_PLACEHOLDERS_SUBMENU_DESC="Allows the users in this group to submenu of placeholder" COM_COMPONENTBUILDER_SERVERS_ACCESS="Servers Access" COM_COMPONENTBUILDER_SERVERS_ACCESS_DESC="Allows the users in this group to access access servers" COM_COMPONENTBUILDER_SERVERS_BATCH_USE="Servers Batch Use" diff --git a/admin/layouts/component_placeholders/details_above.php b/admin/layouts/component_placeholders/details_above.php new file mode 100644 index 000000000..da98e936b --- /dev/null +++ b/admin/layouts/component_placeholders/details_above.php @@ -0,0 +1,31 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$form = $displayData->getForm(); + +$fields = $displayData->get('fields') ?: array( + 'joomla_component' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> +
+ + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + +
diff --git a/admin/layouts/component_placeholders/details_fullwidth.php b/admin/layouts/component_placeholders/details_fullwidth.php new file mode 100644 index 000000000..c38954481 --- /dev/null +++ b/admin/layouts/component_placeholders/details_fullwidth.php @@ -0,0 +1,31 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$form = $displayData->getForm(); + +$fields = $displayData->get('fields') ?: array( + 'addplaceholders' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> +
+ + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + +
diff --git a/admin/layouts/component_placeholders/index.html b/admin/layouts/component_placeholders/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/admin/layouts/component_placeholders/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/layouts/component_placeholders/publishing.php b/admin/layouts/component_placeholders/publishing.php new file mode 100644 index 000000000..3ff2d0f98 --- /dev/null +++ b/admin/layouts/component_placeholders/publishing.php @@ -0,0 +1,32 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$form = $displayData->getForm(); + +$fields = $displayData->get('fields') ?: array( + 'created', + 'created_by', + 'modified', + 'modified_by' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + diff --git a/admin/layouts/component_placeholders/publlshing.php b/admin/layouts/component_placeholders/publlshing.php new file mode 100644 index 000000000..db19414f3 --- /dev/null +++ b/admin/layouts/component_placeholders/publlshing.php @@ -0,0 +1,34 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$form = $displayData->getForm(); + +$fields = $displayData->get('fields') ?: array( + 'published', + 'ordering', + 'access', + 'version', + 'hits', + 'id' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + diff --git a/admin/layouts/placeholder/details_left.php b/admin/layouts/placeholder/details_left.php new file mode 100644 index 000000000..a7af9fa84 --- /dev/null +++ b/admin/layouts/placeholder/details_left.php @@ -0,0 +1,29 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$form = $displayData->getForm(); + +$fields = $displayData->get('fields') ?: array( + 'target' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + diff --git a/admin/layouts/placeholder/details_right.php b/admin/layouts/placeholder/details_right.php new file mode 100644 index 000000000..810273690 --- /dev/null +++ b/admin/layouts/placeholder/details_right.php @@ -0,0 +1,29 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$form = $displayData->getForm(); + +$fields = $displayData->get('fields') ?: array( + 'value' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + diff --git a/admin/layouts/placeholder/index.html b/admin/layouts/placeholder/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/admin/layouts/placeholder/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/layouts/placeholder/publishing.php b/admin/layouts/placeholder/publishing.php new file mode 100644 index 000000000..3ff2d0f98 --- /dev/null +++ b/admin/layouts/placeholder/publishing.php @@ -0,0 +1,32 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$form = $displayData->getForm(); + +$fields = $displayData->get('fields') ?: array( + 'created', + 'created_by', + 'modified', + 'modified_by' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + diff --git a/admin/layouts/placeholder/publlshing.php b/admin/layouts/placeholder/publlshing.php new file mode 100644 index 000000000..db19414f3 --- /dev/null +++ b/admin/layouts/placeholder/publlshing.php @@ -0,0 +1,34 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$form = $displayData->getForm(); + +$fields = $displayData->get('fields') ?: array( + 'published', + 'ordering', + 'access', + 'version', + 'hits', + 'id' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + diff --git a/admin/layouts/server/linked_components_fullwidth.php b/admin/layouts/server/linked_components_fullwidth.php index c69fd2f6d..72ceb0921 100644 --- a/admin/layouts/server/linked_components_fullwidth.php +++ b/admin/layouts/server/linked_components_fullwidth.php @@ -107,6 +107,11 @@ $ref = ($id) ? "&ref=server&refid=" . $id . "&return=" . urlencode(base64_encode 'icon' => 'options') ); $_buttons[1] = array( + array( + 'view' => 'component_placeholders', + 'views' => 'components_placeholders', + 'title' => JText::_('COM_COMPONENTBUILDER_THE_COMPONENT_PLACEHOLDERS'), + 'icon' => 'search'), array( 'view' => 'component_updates', 'views' => 'components_updates', diff --git a/admin/models/component_placeholders.php b/admin/models/component_placeholders.php new file mode 100644 index 000000000..2bf049f0f --- /dev/null +++ b/admin/models/component_placeholders.php @@ -0,0 +1,864 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +use Joomla\Registry\Registry; + +/** + * Componentbuilder Component_placeholders Model + */ +class ComponentbuilderModelComponent_placeholders extends JModelAdmin +{ + /** + * @var string The prefix to use with controller messages. + * @since 1.6 + */ + protected $text_prefix = 'COM_COMPONENTBUILDER'; + + /** + * The type alias for this content type. + * + * @var string + * @since 3.2 + */ + public $typeAlias = 'com_componentbuilder.component_placeholders'; + + /** + * Returns a Table object, always creating it + * + * @param type $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'component_placeholders', $prefix = 'ComponentbuilderTable', $config = array()) + { + // add table path for when model gets used from other component + $this->addTablePath(JPATH_ADMINISTRATOR . '/components/com_componentbuilder/tables'); + // get instance of the table + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + if (!empty($item->params) && !is_array($item->params)) + { + // Convert the params field to an array. + $registry = new Registry; + $registry->loadString($item->params); + $item->params = $registry->toArray(); + } + + if (!empty($item->metadata)) + { + // Convert the metadata field to an array. + $registry = new Registry; + $registry->loadString($item->metadata); + $item->metadata = $registry->toArray(); + } + + if (!empty($item->addplaceholders)) + { + // Convert the addplaceholders field to an array. + $addplaceholders = new Registry; + $addplaceholders->loadString($item->addplaceholders); + $item->addplaceholders = $addplaceholders->toArray(); + } + + if (!empty($item->id)) + { + $item->tags = new JHelperTags; + $item->tags->getTagIds($item->id, 'com_componentbuilder.component_placeholders'); + } + } + + return $item; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * @param array $options Optional array of options for the form creation. + * + * @return mixed A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true, $options = array('control' => 'jform')) + { + // set load data option + $options['load_data'] = $loadData; + // Get the form. + $form = $this->loadForm('com_componentbuilder.component_placeholders', 'component_placeholders', $options); + + if (empty($form)) + { + return false; + } + + $jinput = JFactory::getApplication()->input; + + // The front end calls this model and uses a_id to avoid id clashes so we need to check for that first. + if ($jinput->get('a_id')) + { + $id = $jinput->get('a_id', 0, 'INT'); + } + // The back end uses id so we use that the rest of the time and set it to 0 by default. + else + { + $id = $jinput->get('id', 0, 'INT'); + } + + $user = JFactory::getUser(); + + // Check for existing item. + // Modify the form based on Edit State access controls. + if ($id != 0 && (!$user->authorise('component_placeholders.edit.state', 'com_componentbuilder.component_placeholders.' . (int) $id)) + || ($id == 0 && !$user->authorise('component_placeholders.edit.state', 'com_componentbuilder'))) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + // Disable fields while saving. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + } + // If this is a new item insure the greated by is set. + if (0 == $id) + { + // Set the created_by to this user + $form->setValue('created_by', null, $user->id); + } + // Modify the form based on Edit Creaded By access controls. + if ($id != 0 && (!$user->authorise('component_placeholders.edit.created_by', 'com_componentbuilder.component_placeholders.' . (int) $id)) + || ($id == 0 && !$user->authorise('component_placeholders.edit.created_by', 'com_componentbuilder'))) + { + // Disable fields for display. + $form->setFieldAttribute('created_by', 'disabled', 'true'); + // Disable fields for display. + $form->setFieldAttribute('created_by', 'readonly', 'true'); + // Disable fields while saving. + $form->setFieldAttribute('created_by', 'filter', 'unset'); + } + // Modify the form based on Edit Creaded Date access controls. + if ($id != 0 && (!$user->authorise('component_placeholders.edit.created', 'com_componentbuilder.component_placeholders.' . (int) $id)) + || ($id == 0 && !$user->authorise('component_placeholders.edit.created', 'com_componentbuilder'))) + { + // Disable fields for display. + $form->setFieldAttribute('created', 'disabled', 'true'); + // Disable fields while saving. + $form->setFieldAttribute('created', 'filter', 'unset'); + } + // Only load these values if no id is found + if (0 == $id) + { + // Set redirected view name + $redirectedView = $jinput->get('ref', null, 'STRING'); + // Set field name (or fall back to view name) + $redirectedField = $jinput->get('field', $redirectedView, 'STRING'); + // Set redirected view id + $redirectedId = $jinput->get('refid', 0, 'INT'); + // Set field id (or fall back to redirected view id) + $redirectedValue = $jinput->get('field_id', $redirectedId, 'INT'); + if (0 != $redirectedValue && $redirectedField) + { + // Now set the local-redirected field default value + $form->setValue($redirectedField, null, $redirectedValue); + } + } + return $form; + } + + /** + * Method to get the script that have to be included on the form + * + * @return string script files + */ + public function getScript() + { + return 'administrator/components/com_componentbuilder/models/forms/component_placeholders.js'; + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canDelete($record) + { + if (!empty($record->id)) + { + if ($record->published != -2) + { + return; + } + + $user = JFactory::getUser(); + // The record has been set. Check the record permissions. + return $user->authorise('component_placeholders.delete', 'com_componentbuilder.component_placeholders.' . (int) $record->id); + } + return false; + } + + /** + * Method to test whether a record can have its state edited. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canEditState($record) + { + $user = JFactory::getUser(); + $recordId = (!empty($record->id)) ? $record->id : 0; + + if ($recordId) + { + // The record has been set. Check the record permissions. + $permission = $user->authorise('component_placeholders.edit.state', 'com_componentbuilder.component_placeholders.' . (int) $recordId); + if (!$permission && !is_null($permission)) + { + return false; + } + } + // In the absense of better information, revert to the component permissions. + return $user->authorise('component_placeholders.edit.state', 'com_componentbuilder'); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * @since 2.5 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Check specific edit permission then general edit permission. + $user = JFactory::getUser(); + + return $user->authorise('component_placeholders.edit', 'com_componentbuilder.component_placeholders.'. ((int) isset($data[$key]) ? $data[$key] : 0)) or $user->authorise('component_placeholders.edit', 'com_componentbuilder'); + } + + /** + * Prepare and sanitise the table data prior to saving. + * + * @param JTable $table A JTable object. + * + * @return void + * + * @since 1.6 + */ + protected function prepareTable($table) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + if (isset($table->name)) + { + $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); + } + + if (isset($table->alias) && empty($table->alias)) + { + $table->generateAlias(); + } + + if (empty($table->id)) + { + $table->created = $date->toSql(); + // set the user + if ($table->created_by == 0 || empty($table->created_by)) + { + $table->created_by = $user->id; + } + // Set ordering to the last item if not set + if (empty($table->ordering)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering)') + ->from($db->quoteName('#__componentbuilder_component_placeholders')); + $db->setQuery($query); + $max = $db->loadResult(); + + $table->ordering = $max + 1; + } + } + else + { + $table->modified = $date->toSql(); + $table->modified_by = $user->id; + } + + if (!empty($table->id)) + { + // Increment the items version number. + $table->version++; + } + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_componentbuilder.edit.component_placeholders.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Method to get the unique fields of this table. + * + * @return mixed An array of field names, boolean false if none is set. + * + * @since 3.0 + */ + protected function getUniqeFields() + { + return false; + } + + /** + * 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) + { + if (!parent::delete($pks)) + { + return false; + } + + 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) + { + if (!parent::publish($pks, $value)) + { + return false; + } + + return true; + } + + /** + * Method to perform batch operations on an item or a set of items. + * + * @param array $commands An array of commands to perform. + * @param array $pks An array of item ids. + * @param array $contexts An array of item contexts. + * + * @return boolean Returns true on success, false on failure. + * + * @since 12.2 + */ + public function batch($commands, $pks, $contexts) + { + // Sanitize ids. + $pks = array_unique($pks); + JArrayHelper::toInteger($pks); + + // Remove any values of zero. + if (array_search(0, $pks, true)) + { + unset($pks[array_search(0, $pks, true)]); + } + + if (empty($pks)) + { + $this->setError(JText::_('JGLOBAL_NO_ITEM_SELECTED')); + return false; + } + + $done = false; + + // Set some needed variables. + $this->user = JFactory::getUser(); + $this->table = $this->getTable(); + $this->tableClassName = get_class($this->table); + $this->contentType = new JUcmType; + $this->type = $this->contentType->getTypeByTable($this->tableClassName); + $this->canDo = ComponentbuilderHelper::getActions('component_placeholders'); + $this->batchSet = true; + + if (!$this->canDo->get('core.batch')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + return false; + } + + if ($this->type == false) + { + $type = new JUcmType; + $this->type = $type->getTypeByAlias($this->typeAlias); + } + + $this->tagsObserver = $this->table->getObserverOfClass('JTableObserverTags'); + + if (!empty($commands['move_copy'])) + { + $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); + + if ($cmd == 'c') + { + $result = $this->batchCopy($commands, $pks, $contexts); + + if (is_array($result)) + { + foreach ($result as $old => $new) + { + $contexts[$new] = $contexts[$old]; + } + $pks = array_values($result); + } + else + { + return false; + } + } + elseif ($cmd == 'm' && !$this->batchMove($commands, $pks, $contexts)) + { + return false; + } + + $done = true; + } + + if (!$done) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Batch copy items to a new category or current. + * + * @param integer $values The new values. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return mixed An array of new IDs on success, boolean false on failure. + * + * @since 12.2 + */ + protected function batchCopy($values, $pks, $contexts) + { + if (empty($this->batchSet)) + { + // Set some needed variables. + $this->user = JFactory::getUser(); + $this->table = $this->getTable(); + $this->tableClassName = get_class($this->table); + $this->canDo = ComponentbuilderHelper::getActions('component_placeholders'); + } + + if (!$this->canDo->get('component_placeholders.create') && !$this->canDo->get('component_placeholders.batch')) + { + return false; + } + + // get list of uniqe fields + $uniqeFields = $this->getUniqeFields(); + // remove move_copy from array + unset($values['move_copy']); + + // make sure published is set + if (!isset($values['published'])) + { + $values['published'] = 0; + } + elseif (isset($values['published']) && !$this->canDo->get('component_placeholders.edit.state')) + { + $values['published'] = 0; + } + + $newIds = array(); + // Parent exists so let's proceed + while (!empty($pks)) + { + // Pop the first ID off the stack + $pk = array_shift($pks); + + $this->table->reset(); + + // only allow copy if user may edit this item. + if (!$this->user->authorise('component_placeholders.edit', $contexts[$pk])) + { + // Not fatal error + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + + // Check that the row actually exists + if (!$this->table->load($pk)) + { + if ($error = $this->table->getError()) + { + // Fatal error + $this->setError($error); + return false; + } + else + { + // Not fatal error + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // Only for strings + if (ComponentbuilderHelper::checkString($this->table->joomla_component) && !is_numeric($this->table->joomla_component)) + { + $this->table->joomla_component = $this->generateUniqe('joomla_component',$this->table->joomla_component); + } + + // insert all set values + if (ComponentbuilderHelper::checkArray($values)) + { + foreach ($values as $key => $value) + { + if (strlen($value) > 0 && isset($this->table->$key)) + { + $this->table->$key = $value; + } + } + } + + // update all uniqe fields + if (ComponentbuilderHelper::checkArray($uniqeFields)) + { + foreach ($uniqeFields as $uniqeField) + { + $this->table->$uniqeField = $this->generateUniqe($uniqeField,$this->table->$uniqeField); + } + } + + // Reset the ID because we are making a copy + $this->table->id = 0; + + // TODO: Deal with ordering? + // $this->table->ordering = 1; + + // Check the row. + if (!$this->table->check()) + { + $this->setError($this->table->getError()); + + return false; + } + + if (!empty($this->type)) + { + $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); + } + + // Store the row. + if (!$this->table->store()) + { + $this->setError($this->table->getError()); + + return false; + } + + // Get the new item ID + $newId = $this->table->get('id'); + + // Add the new ID to the array + $newIds[$pk] = $newId; + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + + /** + * Batch move items to a new category + * + * @param integer $value The new category ID. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 12.2 + */ + protected function batchMove($values, $pks, $contexts) + { + if (empty($this->batchSet)) + { + // Set some needed variables. + $this->user = JFactory::getUser(); + $this->table = $this->getTable(); + $this->tableClassName = get_class($this->table); + $this->canDo = ComponentbuilderHelper::getActions('component_placeholders'); + } + + if (!$this->canDo->get('component_placeholders.edit') && !$this->canDo->get('component_placeholders.batch')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + return false; + } + + // make sure published only updates if user has the permission. + if (isset($values['published']) && !$this->canDo->get('component_placeholders.edit.state')) + { + unset($values['published']); + } + // remove move_copy from array + unset($values['move_copy']); + + // Parent exists so we proceed + foreach ($pks as $pk) + { + if (!$this->user->authorise('component_placeholders.edit', $contexts[$pk])) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + return false; + } + + // Check that the row actually exists + if (!$this->table->load($pk)) + { + if ($error = $this->table->getError()) + { + // Fatal error + $this->setError($error); + return false; + } + else + { + // Not fatal error + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // insert all set values. + if (ComponentbuilderHelper::checkArray($values)) + { + foreach ($values as $key => $value) + { + // Do special action for access. + if ('access' === $key && strlen($value) > 0) + { + $this->table->$key = $value; + } + elseif (strlen($value) > 0 && isset($this->table->$key)) + { + $this->table->$key = $value; + } + } + } + + + // Check the row. + if (!$this->table->check()) + { + $this->setError($this->table->getError()); + + return false; + } + + if (!empty($this->type)) + { + $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); + } + + // Store the row. + if (!$this->table->store()) + { + $this->setError($this->table->getError()); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $input = JFactory::getApplication()->input; + $filter = JFilterInput::getInstance(); + + // set the metadata to the Item Data + if (isset($data['metadata']) && isset($data['metadata']['author'])) + { + $data['metadata']['author'] = $filter->clean($data['metadata']['author'], 'TRIM'); + + $metadata = new JRegistry; + $metadata->loadArray($data['metadata']); + $data['metadata'] = (string) $metadata; + } + + // Set the addplaceholders items to data. + if (isset($data['addplaceholders']) && is_array($data['addplaceholders'])) + { + $addplaceholders = new JRegistry; + $addplaceholders->loadArray($data['addplaceholders']); + $data['addplaceholders'] = (string) $addplaceholders; + } + elseif (!isset($data['addplaceholders'])) + { + // Set the empty addplaceholders to data + $data['addplaceholders'] = ''; + } + + // Set the Params Items to data + if (isset($data['params']) && is_array($data['params'])) + { + $params = new JRegistry; + $params->loadArray($data['params']); + $data['params'] = (string) $params; + } + + // Alter the uniqe field for save as copy + if ($input->get('task') === 'save2copy') + { + // Automatic handling of other uniqe fields + $uniqeFields = $this->getUniqeFields(); + if (ComponentbuilderHelper::checkArray($uniqeFields)) + { + foreach ($uniqeFields as $uniqeField) + { + $data[$uniqeField] = $this->generateUniqe($uniqeField,$data[$uniqeField]); + } + } + } + + if (parent::save($data)) + { + return true; + } + return false; + } + + /** + * Method to generate a uniqe value. + * + * @param string $field name. + * @param string $value data. + * + * @return string New value. + * + * @since 3.0 + */ + protected function generateUniqe($field,$value) + { + + // set field value uniqe + $table = $this->getTable(); + + while ($table->load(array($field => $value))) + { + $value = JString::increment($value); + } + + return $value; + } + + /** + * Method to change the title + * + * @param string $title The title. + * + * @return array Contains the modified title and alias. + * + */ + protected function _generateNewTitle($title) + { + + // Alter the title + $table = $this->getTable(); + + while ($table->load(array('title' => $title))) + { + $title = JString::increment($title); + } + + return $title; + } +} diff --git a/admin/models/componentbuilder.php b/admin/models/componentbuilder.php index 10e7b1aa2..52b4cc211 100644 --- a/admin/models/componentbuilder.php +++ b/admin/models/componentbuilder.php @@ -25,7 +25,7 @@ class ComponentbuilderModelComponentbuilder extends JModelList $icons = array(); // view groups array $viewGroups = array( - 'main' => array('png.compiler', 'png.joomla_component.add', 'png.joomla_components', 'png.admin_view.add', 'png.admin_views', 'png||importjcbpackages||index.php?option=com_componentbuilder&view=joomla_components&task=joomla_components.smartImport', 'png.custom_admin_view.add', 'png.custom_admin_views', 'png.site_view.add', 'png.site_views', 'png.template.add', 'png.templates', 'png.layout.add', 'png.layouts', 'png.dynamic_get.add', 'png.dynamic_gets', 'png.custom_codes', 'png.libraries', 'png.snippets', 'png.get_snippets', 'png.validation_rules', 'png.field.add', 'png.fields', 'png.fields.catid', 'png.fieldtype.add', 'png.fieldtypes', 'png.fieldtypes.catid', 'png.language_translations', 'png.servers', 'png.help_documents') + 'main' => array('png.compiler', 'png.joomla_component.add', 'png.joomla_components', 'png.admin_view.add', 'png.admin_views', 'png||importjcbpackages||index.php?option=com_componentbuilder&view=joomla_components&task=joomla_components.smartImport', 'png.custom_admin_view.add', 'png.custom_admin_views', 'png.site_view.add', 'png.site_views', 'png.template.add', 'png.templates', 'png.layout.add', 'png.layouts', 'png.dynamic_get.add', 'png.dynamic_gets', 'png.custom_codes', 'png.placeholders', 'png.libraries', 'png.snippets', 'png.get_snippets', 'png.validation_rules', 'png.field.add', 'png.fields', 'png.fields.catid', 'png.fieldtypes', 'png.fieldtypes.catid', 'png.language_translations', 'png.servers', 'png.help_documents') ); // view access array $viewAccess = array( @@ -76,6 +76,11 @@ class ComponentbuilderModelComponentbuilder extends JModelList 'custom_code.access' => 'custom_code.access', 'custom_codes.submenu' => 'custom_code.submenu', 'custom_codes.dashboard_list' => 'custom_code.dashboard_list', + 'placeholder.create' => 'placeholder.create', + 'placeholders.access' => 'placeholder.access', + 'placeholder.access' => 'placeholder.access', + 'placeholders.submenu' => 'placeholder.submenu', + 'placeholders.dashboard_list' => 'placeholder.dashboard_list', 'library.create' => 'library.create', 'libraries.access' => 'library.access', 'library.access' => 'library.access', @@ -101,7 +106,6 @@ class ComponentbuilderModelComponentbuilder extends JModelList 'fieldtype.access' => 'fieldtype.access', 'fieldtypes.submenu' => 'fieldtype.submenu', 'fieldtypes.dashboard_list' => 'fieldtype.dashboard_list', - 'fieldtype.dashboard_add' => 'fieldtype.dashboard_add', 'language_translation.create' => 'language_translation.create', 'language_translations.access' => 'language_translation.access', 'language_translation.access' => 'language_translation.access', @@ -160,6 +164,9 @@ class ComponentbuilderModelComponentbuilder extends JModelList 'component_files_folders.create' => 'component_files_folders.create', 'components_files_folders.access' => 'component_files_folders.access', 'component_files_folders.access' => 'component_files_folders.access', + 'component_placeholders.create' => 'component_placeholders.create', + 'components_placeholders.access' => 'component_placeholders.access', + 'component_placeholders.access' => 'component_placeholders.access', 'snippet_type.create' => 'snippet_type.create', 'snippet_types.access' => 'snippet_type.access', 'snippet_type.access' => 'snippet_type.access', diff --git a/admin/models/components_placeholders.php b/admin/models/components_placeholders.php new file mode 100644 index 000000000..1267253b4 --- /dev/null +++ b/admin/models/components_placeholders.php @@ -0,0 +1,237 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Components_placeholders Model + */ +class ComponentbuilderModelComponents_placeholders extends JModelList +{ + public function __construct($config = array()) + { + if (empty($config['filter_fields'])) + { + $config['filter_fields'] = array( + 'a.id','id', + 'a.published','published', + 'a.ordering','ordering', + 'a.created_by','created_by', + 'a.modified_by','modified_by' + ); + } + + parent::__construct($config); + } + + /** + * Method to auto-populate the model state. + * + * @return void + */ + protected function populateState($ordering = null, $direction = null) + { + $app = JFactory::getApplication(); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + + $sorting = $this->getUserStateFromRequest($this->context . '.filter.sorting', 'filter_sorting', 0, 'int'); + $this->setState('filter.sorting', $sorting); + + $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', 0, 'int'); + $this->setState('filter.access', $access); + + $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $published = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', ''); + $this->setState('filter.published', $published); + + $created_by = $this->getUserStateFromRequest($this->context . '.filter.created_by', 'filter_created_by', ''); + $this->setState('filter.created_by', $created_by); + + $created = $this->getUserStateFromRequest($this->context . '.filter.created', 'filter_created'); + $this->setState('filter.created', $created); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + */ + public function getItems() + { + // check in items + $this->checkInNow(); + + // load parent items + $items = parent::getItems(); + + // set values to display correctly. + if (ComponentbuilderHelper::checkArray($items)) + { + foreach ($items as $nr => &$item) + { + $access = (JFactory::getUser()->authorise('component_placeholders.access', 'com_componentbuilder.component_placeholders.' . (int) $item->id) && JFactory::getUser()->authorise('component_placeholders.access', 'com_componentbuilder')); + if (!$access) + { + unset($items[$nr]); + continue; + } + + } + } + + // return items + return $items; + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + */ + protected function getListQuery() + { + // Get the user object. + $user = JFactory::getUser(); + // Create a new query object. + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + + // Select some fields + $query->select('a.*'); + + // From the componentbuilder_item table + $query->from($db->quoteName('#__componentbuilder_component_placeholders', 'a')); + + // From the componentbuilder_joomla_component table. + $query->select($db->quoteName('g.system_name','joomla_component_system_name')); + $query->join('LEFT', $db->quoteName('#__componentbuilder_joomla_component', 'g') . ' ON (' . $db->quoteName('a.joomla_component') . ' = ' . $db->quoteName('g.id') . ')'); + + // Filter by published state + $published = $this->getState('filter.published'); + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.published = 0 OR a.published = 1)'); + } + + // Join over the asset groups. + $query->select('ag.title AS access_level'); + $query->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + // Implement View Level Access + if (!$user->authorise('core.options', 'com_componentbuilder')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering', 'a.id'); + $orderDirn = $this->state->get('list.direction', 'asc'); + if ($orderCol != '') + { + $query->order($db->escape($orderCol . ' ' . $orderDirn)); + } + + return $query; + } + + /** + * Method to get a store id based on model configuration state. + * + * @return string A store id. + * + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.ordering'); + $id .= ':' . $this->getState('filter.created_by'); + $id .= ':' . $this->getState('filter.modified_by'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to checkin all items left checked out longer then a set time. + * + * @return a bool + * + */ + protected function checkInNow() + { + // Get set check in time + $time = JComponentHelper::getParams('com_componentbuilder')->get('check_in'); + + if ($time) + { + + // Get a db connection. + $db = JFactory::getDbo(); + // reset query + $query = $db->getQuery(true); + $query->select('*'); + $query->from($db->quoteName('#__componentbuilder_component_placeholders')); + $db->setQuery($query); + $db->execute(); + if ($db->getNumRows()) + { + // Get Yesterdays date + $date = JFactory::getDate()->modify($time)->toSql(); + // reset query + $query = $db->getQuery(true); + + // Fields to update. + $fields = array( + $db->quoteName('checked_out_time') . '=\'0000-00-00 00:00:00\'', + $db->quoteName('checked_out') . '=0' + ); + + // Conditions for which records should be updated. + $conditions = array( + $db->quoteName('checked_out') . '!=0', + $db->quoteName('checked_out_time') . '<\''.$date.'\'' + ); + + // Check table + $query->update($db->quoteName('#__componentbuilder_component_placeholders'))->set($fields)->where($conditions); + + $db->setQuery($query); + + $db->execute(); + } + } + + return false; + } +} diff --git a/admin/models/field.php b/admin/models/field.php index 3c25a6ab3..f1d7c6ec2 100644 --- a/admin/models/field.php +++ b/admin/models/field.php @@ -930,6 +930,16 @@ class ComponentbuilderModelField extends JModelAdmin { // fix the values case 'name': + // check if we have placeholder in name + if (strpos($property['value'], '[[[') !== false || strpos($property['value'], '###') !== false) + { + $property['value'] = trim($property['value']); + } + else + { + $property['value'] = ComponentbuilderHelper::safeString($property['value']); + } + break; case 'type': $property['value'] = ComponentbuilderHelper::safeString($property['value']); break; diff --git a/admin/models/forms/component_placeholders.js b/admin/models/forms/component_placeholders.js new file mode 100644 index 000000000..4bb347a82 --- /dev/null +++ b/admin/models/forms/component_placeholders.js @@ -0,0 +1,11 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + + diff --git a/admin/models/forms/component_placeholders.xml b/admin/models/forms/component_placeholders.xml new file mode 100644 index 000000000..d861e5090 --- /dev/null +++ b/admin/models/forms/component_placeholders.xml @@ -0,0 +1,166 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + +
+ \ No newline at end of file diff --git a/admin/models/forms/placeholder.js b/admin/models/forms/placeholder.js new file mode 100644 index 000000000..4bb347a82 --- /dev/null +++ b/admin/models/forms/placeholder.js @@ -0,0 +1,11 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + + diff --git a/admin/models/forms/placeholder.xml b/admin/models/forms/placeholder.xml new file mode 100644 index 000000000..83376f8fa --- /dev/null +++ b/admin/models/forms/placeholder.xml @@ -0,0 +1,141 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + +
+
\ No newline at end of file diff --git a/admin/models/import_joomla_components.php b/admin/models/import_joomla_components.php index f0458d32a..90eedcb33 100644 --- a/admin/models/import_joomla_components.php +++ b/admin/models/import_joomla_components.php @@ -702,7 +702,8 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy 'template', 'layout', 'joomla_component', 'language', 'language_translation', 'custom_code', 'admin_fields', 'admin_fields_conditions', 'admin_fields_relations', 'admin_custom_tabs', 'component_admin_views', 'component_site_views', 'component_custom_admin_views', 'component_updates', 'component_mysql_tweaks', - 'component_custom_admin_menus', 'component_config', 'component_dashboard', 'component_files_folders' + 'component_custom_admin_menus', 'component_config', 'component_dashboard', 'component_files_folders', + 'component_placeholders' ); // get prefix $prefix = $this->_db->getPrefix(); @@ -2056,6 +2057,14 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy // update the repeatable fields $item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR); break; + case 'component_placeholders': + // diverged id already updated + if (!$diverged) + { + // update the joomla_component ID where needed + $item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type); + } + break; case 'component_files_folders': // diverged id already updated if (!$diverged) @@ -2845,6 +2854,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy case 'component_custom_admin_menus': case 'component_config': case 'component_dashboard': + case 'component_placeholders': case 'component_files_folders': // get by joomla_component (since there should only be one of each component) $getter = array('joomla_component'); diff --git a/admin/models/joomla_components.php b/admin/models/joomla_components.php index a46edc767..436eb41c0 100644 --- a/admin/models/joomla_components.php +++ b/admin/models/joomla_components.php @@ -298,7 +298,8 @@ class ComponentbuilderModelJoomla_components extends JModelList 'component_updates' => 'joomla_component', 'component_mysql_tweaks' => 'joomla_component', 'component_custom_admin_menus' => 'joomla_component', - 'component_dashboard' => 'joomla_component' ); + 'component_dashboard' => 'joomla_component', + 'component_placeholders' => 'joomla_component' ); // load all tables linked to joomla_component foreach($linkedTables as $table => $field) { @@ -868,7 +869,8 @@ class ComponentbuilderModelJoomla_components extends JModelList 'template', 'layout', 'joomla_component', 'language', 'language_translation', 'custom_code', 'admin_fields', 'admin_fields_conditions', 'admin_fields_relations', 'admin_custom_tabs', 'component_admin_views', 'component_site_views', 'component_custom_admin_views', 'component_updates', 'component_mysql_tweaks', - 'component_custom_admin_menus', 'component_config', 'component_dashboard', 'component_files_folders' + 'component_custom_admin_menus', 'component_config', 'component_dashboard', 'component_files_folders', + 'component_placeholders' ); // smart table loop foreach ($tables as $table) diff --git a/admin/models/placeholder.php b/admin/models/placeholder.php new file mode 100644 index 000000000..06ac6eb57 --- /dev/null +++ b/admin/models/placeholder.php @@ -0,0 +1,889 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +use Joomla\Registry\Registry; + +/** + * Componentbuilder Placeholder Model + */ +class ComponentbuilderModelPlaceholder extends JModelAdmin +{ + /** + * @var string The prefix to use with controller messages. + * @since 1.6 + */ + protected $text_prefix = 'COM_COMPONENTBUILDER'; + + /** + * The type alias for this content type. + * + * @var string + * @since 3.2 + */ + public $typeAlias = 'com_componentbuilder.placeholder'; + + /** + * Returns a Table object, always creating it + * + * @param type $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'placeholder', $prefix = 'ComponentbuilderTable', $config = array()) + { + // add table path for when model gets used from other component + $this->addTablePath(JPATH_ADMINISTRATOR . '/components/com_componentbuilder/tables'); + // get instance of the table + return JTable::getInstance($type, $prefix, $config); + } + + public function getVDM() + { + return $this->vastDevMod; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + if (!empty($item->params) && !is_array($item->params)) + { + // Convert the params field to an array. + $registry = new Registry; + $registry->loadString($item->params); + $item->params = $registry->toArray(); + } + + if (!empty($item->metadata)) + { + // Convert the metadata field to an array. + $registry = new Registry; + $registry->loadString($item->metadata); + $item->metadata = $registry->toArray(); + } + + if (!empty($item->value)) + { + // base64 Decode value. + $item->value = base64_decode($item->value); + } + + + if (empty($item->id)) + { + $id = 0; + } + else + { + $id = $item->id; + } + // set the id and view name to session + if ($vdm = ComponentbuilderHelper::get('placeholder__'.$id)) + { + $this->vastDevMod = $vdm; + } + else + { + // set the vast development method key + $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + ComponentbuilderHelper::set($this->vastDevMod, 'placeholder__'.$id); + ComponentbuilderHelper::set('placeholder__'.$id, $this->vastDevMod); + // set a return value if found + $jinput = JFactory::getApplication()->input; + $return = $jinput->get('return', null, 'base64'); + ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); + } + + if (!empty($item->id)) + { + $item->tags = new JHelperTags; + $item->tags->getTagIds($item->id, 'com_componentbuilder.placeholder'); + } + } + + return $item; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * @param array $options Optional array of options for the form creation. + * + * @return mixed A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true, $options = array('control' => 'jform')) + { + // set load data option + $options['load_data'] = $loadData; + // Get the form. + $form = $this->loadForm('com_componentbuilder.placeholder', 'placeholder', $options); + + if (empty($form)) + { + return false; + } + + $jinput = JFactory::getApplication()->input; + + // The front end calls this model and uses a_id to avoid id clashes so we need to check for that first. + if ($jinput->get('a_id')) + { + $id = $jinput->get('a_id', 0, 'INT'); + } + // The back end uses id so we use that the rest of the time and set it to 0 by default. + else + { + $id = $jinput->get('id', 0, 'INT'); + } + + $user = JFactory::getUser(); + + // Check for existing item. + // Modify the form based on Edit State access controls. + if ($id != 0 && (!$user->authorise('placeholder.edit.state', 'com_componentbuilder.placeholder.' . (int) $id)) + || ($id == 0 && !$user->authorise('placeholder.edit.state', 'com_componentbuilder'))) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + // Disable fields while saving. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + } + // If this is a new item insure the greated by is set. + if (0 == $id) + { + // Set the created_by to this user + $form->setValue('created_by', null, $user->id); + } + // Modify the form based on Edit Creaded By access controls. + if (!$user->authorise('core.edit.created_by', 'com_componentbuilder')) + { + // Disable fields for display. + $form->setFieldAttribute('created_by', 'disabled', 'true'); + // Disable fields for display. + $form->setFieldAttribute('created_by', 'readonly', 'true'); + // Disable fields while saving. + $form->setFieldAttribute('created_by', 'filter', 'unset'); + } + // Modify the form based on Edit Creaded Date access controls. + if (!$user->authorise('core.edit.created', 'com_componentbuilder')) + { + // Disable fields for display. + $form->setFieldAttribute('created', 'disabled', 'true'); + // Disable fields while saving. + $form->setFieldAttribute('created', 'filter', 'unset'); + } + // Only load these values if no id is found + if (0 == $id) + { + // Set redirected view name + $redirectedView = $jinput->get('ref', null, 'STRING'); + // Set field name (or fall back to view name) + $redirectedField = $jinput->get('field', $redirectedView, 'STRING'); + // Set redirected view id + $redirectedId = $jinput->get('refid', 0, 'INT'); + // Set field id (or fall back to redirected view id) + $redirectedValue = $jinput->get('field_id', $redirectedId, 'INT'); + if (0 != $redirectedValue && $redirectedField) + { + // Now set the local-redirected field default value + $form->setValue($redirectedField, null, $redirectedValue); + } + } + return $form; + } + + /** + * Method to get the script that have to be included on the form + * + * @return string script files + */ + public function getScript() + { + return 'administrator/components/com_componentbuilder/models/forms/placeholder.js'; + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canDelete($record) + { + if (!empty($record->id)) + { + if ($record->published != -2) + { + return; + } + + $user = JFactory::getUser(); + // The record has been set. Check the record permissions. + return $user->authorise('placeholder.delete', 'com_componentbuilder.placeholder.' . (int) $record->id); + } + return false; + } + + /** + * Method to test whether a record can have its state edited. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canEditState($record) + { + $user = JFactory::getUser(); + $recordId = (!empty($record->id)) ? $record->id : 0; + + if ($recordId) + { + // The record has been set. Check the record permissions. + $permission = $user->authorise('placeholder.edit.state', 'com_componentbuilder.placeholder.' . (int) $recordId); + if (!$permission && !is_null($permission)) + { + return false; + } + } + // In the absense of better information, revert to the component permissions. + return $user->authorise('placeholder.edit.state', 'com_componentbuilder'); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * @since 2.5 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Check specific edit permission then general edit permission. + $user = JFactory::getUser(); + + return $user->authorise('placeholder.edit', 'com_componentbuilder.placeholder.'. ((int) isset($data[$key]) ? $data[$key] : 0)) or $user->authorise('placeholder.edit', 'com_componentbuilder'); + } + + /** + * Prepare and sanitise the table data prior to saving. + * + * @param JTable $table A JTable object. + * + * @return void + * + * @since 1.6 + */ + protected function prepareTable($table) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + if (isset($table->name)) + { + $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); + } + + if (isset($table->alias) && empty($table->alias)) + { + $table->generateAlias(); + } + + if (empty($table->id)) + { + $table->created = $date->toSql(); + // set the user + if ($table->created_by == 0 || empty($table->created_by)) + { + $table->created_by = $user->id; + } + // Set ordering to the last item if not set + if (empty($table->ordering)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering)') + ->from($db->quoteName('#__componentbuilder_placeholder')); + $db->setQuery($query); + $max = $db->loadResult(); + + $table->ordering = $max + 1; + } + } + else + { + $table->modified = $date->toSql(); + $table->modified_by = $user->id; + } + + if (!empty($table->id)) + { + // Increment the items version number. + $table->version++; + } + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_componentbuilder.edit.placeholder.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Method to get the unique fields of this table. + * + * @return mixed An array of field names, boolean false if none is set. + * + * @since 3.0 + */ + protected function getUniqeFields() + { + return false; + } + + /** + * 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) + { + if (!parent::delete($pks)) + { + return false; + } + + 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) + { + if (!parent::publish($pks, $value)) + { + return false; + } + + return true; + } + + /** + * Method to perform batch operations on an item or a set of items. + * + * @param array $commands An array of commands to perform. + * @param array $pks An array of item ids. + * @param array $contexts An array of item contexts. + * + * @return boolean Returns true on success, false on failure. + * + * @since 12.2 + */ + public function batch($commands, $pks, $contexts) + { + // Sanitize ids. + $pks = array_unique($pks); + JArrayHelper::toInteger($pks); + + // Remove any values of zero. + if (array_search(0, $pks, true)) + { + unset($pks[array_search(0, $pks, true)]); + } + + if (empty($pks)) + { + $this->setError(JText::_('JGLOBAL_NO_ITEM_SELECTED')); + return false; + } + + $done = false; + + // Set some needed variables. + $this->user = JFactory::getUser(); + $this->table = $this->getTable(); + $this->tableClassName = get_class($this->table); + $this->contentType = new JUcmType; + $this->type = $this->contentType->getTypeByTable($this->tableClassName); + $this->canDo = ComponentbuilderHelper::getActions('placeholder'); + $this->batchSet = true; + + if (!$this->canDo->get('core.batch')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + return false; + } + + if ($this->type == false) + { + $type = new JUcmType; + $this->type = $type->getTypeByAlias($this->typeAlias); + } + + $this->tagsObserver = $this->table->getObserverOfClass('JTableObserverTags'); + + if (!empty($commands['move_copy'])) + { + $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); + + if ($cmd == 'c') + { + $result = $this->batchCopy($commands, $pks, $contexts); + + if (is_array($result)) + { + foreach ($result as $old => $new) + { + $contexts[$new] = $contexts[$old]; + } + $pks = array_values($result); + } + else + { + return false; + } + } + elseif ($cmd == 'm' && !$this->batchMove($commands, $pks, $contexts)) + { + return false; + } + + $done = true; + } + + if (!$done) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Batch copy items to a new category or current. + * + * @param integer $values The new values. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return mixed An array of new IDs on success, boolean false on failure. + * + * @since 12.2 + */ + protected function batchCopy($values, $pks, $contexts) + { + if (empty($this->batchSet)) + { + // Set some needed variables. + $this->user = JFactory::getUser(); + $this->table = $this->getTable(); + $this->tableClassName = get_class($this->table); + $this->canDo = ComponentbuilderHelper::getActions('placeholder'); + } + + if (!$this->canDo->get('placeholder.create') && !$this->canDo->get('placeholder.batch')) + { + return false; + } + + // get list of uniqe fields + $uniqeFields = $this->getUniqeFields(); + // remove move_copy from array + unset($values['move_copy']); + + // make sure published is set + if (!isset($values['published'])) + { + $values['published'] = 0; + } + elseif (isset($values['published']) && !$this->canDo->get('placeholder.edit.state')) + { + $values['published'] = 0; + } + + $newIds = array(); + // Parent exists so let's proceed + while (!empty($pks)) + { + // Pop the first ID off the stack + $pk = array_shift($pks); + + $this->table->reset(); + + // only allow copy if user may edit this item. + if (!$this->user->authorise('placeholder.edit', $contexts[$pk])) + { + // Not fatal error + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + + // Check that the row actually exists + if (!$this->table->load($pk)) + { + if ($error = $this->table->getError()) + { + // Fatal error + $this->setError($error); + return false; + } + else + { + // Not fatal error + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // Only for strings + if (ComponentbuilderHelper::checkString($this->table->target) && !is_numeric($this->table->target)) + { + $this->table->target = $this->generateUniqe('target',$this->table->target); + } + + // insert all set values + if (ComponentbuilderHelper::checkArray($values)) + { + foreach ($values as $key => $value) + { + if (strlen($value) > 0 && isset($this->table->$key)) + { + $this->table->$key = $value; + } + } + } + + // update all uniqe fields + if (ComponentbuilderHelper::checkArray($uniqeFields)) + { + foreach ($uniqeFields as $uniqeField) + { + $this->table->$uniqeField = $this->generateUniqe($uniqeField,$this->table->$uniqeField); + } + } + + // Reset the ID because we are making a copy + $this->table->id = 0; + + // TODO: Deal with ordering? + // $this->table->ordering = 1; + + // Check the row. + if (!$this->table->check()) + { + $this->setError($this->table->getError()); + + return false; + } + + if (!empty($this->type)) + { + $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); + } + + // Store the row. + if (!$this->table->store()) + { + $this->setError($this->table->getError()); + + return false; + } + + // Get the new item ID + $newId = $this->table->get('id'); + + // Add the new ID to the array + $newIds[$pk] = $newId; + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + + /** + * Batch move items to a new category + * + * @param integer $value The new category ID. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 12.2 + */ + protected function batchMove($values, $pks, $contexts) + { + if (empty($this->batchSet)) + { + // Set some needed variables. + $this->user = JFactory::getUser(); + $this->table = $this->getTable(); + $this->tableClassName = get_class($this->table); + $this->canDo = ComponentbuilderHelper::getActions('placeholder'); + } + + if (!$this->canDo->get('placeholder.edit') && !$this->canDo->get('placeholder.batch')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + return false; + } + + // make sure published only updates if user has the permission. + if (isset($values['published']) && !$this->canDo->get('placeholder.edit.state')) + { + unset($values['published']); + } + // remove move_copy from array + unset($values['move_copy']); + + // Parent exists so we proceed + foreach ($pks as $pk) + { + if (!$this->user->authorise('placeholder.edit', $contexts[$pk])) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + return false; + } + + // Check that the row actually exists + if (!$this->table->load($pk)) + { + if ($error = $this->table->getError()) + { + // Fatal error + $this->setError($error); + return false; + } + else + { + // Not fatal error + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // insert all set values. + if (ComponentbuilderHelper::checkArray($values)) + { + foreach ($values as $key => $value) + { + // Do special action for access. + if ('access' === $key && strlen($value) > 0) + { + $this->table->$key = $value; + } + elseif (strlen($value) > 0 && isset($this->table->$key)) + { + $this->table->$key = $value; + } + } + } + + + // Check the row. + if (!$this->table->check()) + { + $this->setError($this->table->getError()); + + return false; + } + + if (!empty($this->type)) + { + $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); + } + + // Store the row. + if (!$this->table->store()) + { + $this->setError($this->table->getError()); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $input = JFactory::getApplication()->input; + $filter = JFilterInput::getInstance(); + + // set the metadata to the Item Data + if (isset($data['metadata']) && isset($data['metadata']['author'])) + { + $data['metadata']['author'] = $filter->clean($data['metadata']['author'], 'TRIM'); + + $metadata = new JRegistry; + $metadata->loadArray($data['metadata']); + $data['metadata'] = (string) $metadata; + } + + // make sure no padding is set + $data['target'] = str_replace(array('[', ']', '#'), '', $data['target']); + // add the padding (needed) + $data['target'] = '[[[' . trim($data['target']) . ']]]'; + + // Set the value string to base64 string. + if (isset($data['value'])) + { + $data['value'] = base64_encode($data['value']); + } + + // Set the Params Items to data + if (isset($data['params']) && is_array($data['params'])) + { + $params = new JRegistry; + $params->loadArray($data['params']); + $data['params'] = (string) $params; + } + + // Alter the uniqe field for save as copy + if ($input->get('task') === 'save2copy') + { + // Automatic handling of other uniqe fields + $uniqeFields = $this->getUniqeFields(); + if (ComponentbuilderHelper::checkArray($uniqeFields)) + { + foreach ($uniqeFields as $uniqeField) + { + $data[$uniqeField] = $this->generateUniqe($uniqeField,$data[$uniqeField]); + } + } + } + + if (parent::save($data)) + { + return true; + } + return false; + } + + /** + * Method to generate a uniqe value. + * + * @param string $field name. + * @param string $value data. + * + * @return string New value. + * + * @since 3.0 + */ + protected function generateUniqe($field,$value) + { + + // set field value uniqe + $table = $this->getTable(); + + while ($table->load(array($field => $value))) + { + $value = JString::increment($value); + } + + return $value; + } + + /** + * Method to change the title + * + * @param string $title The title. + * + * @return array Contains the modified title and alias. + * + */ + protected function _generateNewTitle($title) + { + + // Alter the title + $table = $this->getTable(); + + while ($table->load(array('title' => $title))) + { + $title = JString::increment($title); + } + + return $title; + } +} diff --git a/admin/models/placeholders.php b/admin/models/placeholders.php new file mode 100644 index 000000000..8deb3cb00 --- /dev/null +++ b/admin/models/placeholders.php @@ -0,0 +1,358 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Placeholders Model + */ +class ComponentbuilderModelPlaceholders extends JModelList +{ + public function __construct($config = array()) + { + if (empty($config['filter_fields'])) + { + $config['filter_fields'] = array( + 'a.id','id', + 'a.published','published', + 'a.ordering','ordering', + 'a.created_by','created_by', + 'a.modified_by','modified_by', + 'a.target','target', + 'a.value','value' + ); + } + + parent::__construct($config); + } + + /** + * Method to auto-populate the model state. + * + * @return void + */ + protected function populateState($ordering = null, $direction = null) + { + $app = JFactory::getApplication(); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + $target = $this->getUserStateFromRequest($this->context . '.filter.target', 'filter_target'); + $this->setState('filter.target', $target); + + $value = $this->getUserStateFromRequest($this->context . '.filter.value', 'filter_value'); + $this->setState('filter.value', $value); + + $sorting = $this->getUserStateFromRequest($this->context . '.filter.sorting', 'filter_sorting', 0, 'int'); + $this->setState('filter.sorting', $sorting); + + $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', 0, 'int'); + $this->setState('filter.access', $access); + + $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $published = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', ''); + $this->setState('filter.published', $published); + + $created_by = $this->getUserStateFromRequest($this->context . '.filter.created_by', 'filter_created_by', ''); + $this->setState('filter.created_by', $created_by); + + $created = $this->getUserStateFromRequest($this->context . '.filter.created', 'filter_created'); + $this->setState('filter.created', $created); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + */ + public function getItems() + { + // check in items + $this->checkInNow(); + + // load parent items + $items = parent::getItems(); + + // set values to display correctly. + if (ComponentbuilderHelper::checkArray($items)) + { + foreach ($items as $nr => &$item) + { + $access = (JFactory::getUser()->authorise('placeholder.access', 'com_componentbuilder.placeholder.' . (int) $item->id) && JFactory::getUser()->authorise('placeholder.access', 'com_componentbuilder')); + if (!$access) + { + unset($items[$nr]); + continue; + } + + // decode value + $item->value = base64_decode($item->value); + } + } + + // return items + return $items; + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + */ + protected function getListQuery() + { + // Get the user object. + $user = JFactory::getUser(); + // Create a new query object. + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + + // Select some fields + $query->select('a.*'); + + // From the componentbuilder_item table + $query->from($db->quoteName('#__componentbuilder_placeholder', 'a')); + + // Filter by published state + $published = $this->getState('filter.published'); + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.published = 0 OR a.published = 1)'); + } + + // Join over the asset groups. + $query->select('ag.title AS access_level'); + $query->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + // Implement View Level Access + if (!$user->authorise('core.options', 'com_componentbuilder')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + // Filter by search. + $search = $this->getState('filter.search'); + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . $db->escape($search) . '%'); + $query->where('(a.target LIKE '.$search.' OR a.value LIKE '.$search.')'); + } + } + + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering', 'a.id'); + $orderDirn = $this->state->get('list.direction', 'asc'); + if ($orderCol != '') + { + $query->order($db->escape($orderCol . ' ' . $orderDirn)); + } + + return $query; + } + + /** + * Method to get list export data. + * + * @return mixed An array of data items on success, false on failure. + */ + public function getExportData($pks) + { + // setup the query + if (ComponentbuilderHelper::checkArray($pks)) + { + // Set a value to know this is exporting method. + $_export = true; + // Get the user object. + $user = JFactory::getUser(); + // Create a new query object. + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + + // Select some fields + $query->select('a.*'); + + // From the componentbuilder_placeholder table + $query->from($db->quoteName('#__componentbuilder_placeholder', 'a')); + $query->where('a.id IN (' . implode(',',$pks) . ')'); + // Implement View Level Access + if (!$user->authorise('core.options', 'com_componentbuilder')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + + // Order the results by ordering + $query->order('a.ordering ASC'); + + // Load the items + $db->setQuery($query); + $db->execute(); + if ($db->getNumRows()) + { + $items = $db->loadObjectList(); + + // set values to display correctly. + if (ComponentbuilderHelper::checkArray($items)) + { + foreach ($items as $nr => &$item) + { + $access = (JFactory::getUser()->authorise('placeholder.access', 'com_componentbuilder.placeholder.' . (int) $item->id) && JFactory::getUser()->authorise('placeholder.access', 'com_componentbuilder')); + if (!$access) + { + unset($items[$nr]); + continue; + } + + // decode value + $item->value = base64_decode($item->value); + // unset the values we don't want exported. + unset($item->asset_id); + unset($item->checked_out); + unset($item->checked_out_time); + } + } + // Add headers to items array. + $headers = $this->getExImPortHeaders(); + if (ComponentbuilderHelper::checkObject($headers)) + { + array_unshift($items,$headers); + } + return $items; + } + } + return false; + } + + /** + * Method to get header. + * + * @return mixed An array of data items on success, false on failure. + */ + public function getExImPortHeaders() + { + // Get a db connection. + $db = JFactory::getDbo(); + // get the columns + $columns = $db->getTableColumns("#__componentbuilder_placeholder"); + if (ComponentbuilderHelper::checkArray($columns)) + { + // remove the headers you don't import/export. + unset($columns['asset_id']); + unset($columns['checked_out']); + unset($columns['checked_out_time']); + $headers = new stdClass(); + foreach ($columns as $column => $type) + { + $headers->{$column} = $column; + } + return $headers; + } + return false; + } + + /** + * Method to get a store id based on model configuration state. + * + * @return string A store id. + * + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.ordering'); + $id .= ':' . $this->getState('filter.created_by'); + $id .= ':' . $this->getState('filter.modified_by'); + $id .= ':' . $this->getState('filter.target'); + $id .= ':' . $this->getState('filter.value'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to checkin all items left checked out longer then a set time. + * + * @return a bool + * + */ + protected function checkInNow() + { + // Get set check in time + $time = JComponentHelper::getParams('com_componentbuilder')->get('check_in'); + + if ($time) + { + + // Get a db connection. + $db = JFactory::getDbo(); + // reset query + $query = $db->getQuery(true); + $query->select('*'); + $query->from($db->quoteName('#__componentbuilder_placeholder')); + $db->setQuery($query); + $db->execute(); + if ($db->getNumRows()) + { + // Get Yesterdays date + $date = JFactory::getDate()->modify($time)->toSql(); + // reset query + $query = $db->getQuery(true); + + // Fields to update. + $fields = array( + $db->quoteName('checked_out_time') . '=\'0000-00-00 00:00:00\'', + $db->quoteName('checked_out') . '=0' + ); + + // Conditions for which records should be updated. + $conditions = array( + $db->quoteName('checked_out') . '!=0', + $db->quoteName('checked_out_time') . '<\''.$date.'\'' + ); + + // Check table + $query->update($db->quoteName('#__componentbuilder_placeholder'))->set($fields)->where($conditions); + + $db->setQuery($query); + + $db->execute(); + } + } + + return false; + } +} diff --git a/admin/models/rules/uniqueplaceholder.php b/admin/models/rules/uniqueplaceholder.php new file mode 100644 index 000000000..9b478f680 --- /dev/null +++ b/admin/models/rules/uniqueplaceholder.php @@ -0,0 +1,87 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('JPATH_PLATFORM') or die; + +use Joomla\CMS\Form\Form; +use Joomla\CMS\Form\FormRule; +use Joomla\Registry\Registry; + +/** + * Form Rule (Uniqueplaceholder) class for the Joomla Platform. + */ +class JFormRuleUniqueplaceholder extends FormRule +{ + /** + * Method to test the field value for uniqueness. + * + * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * @param Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param Form $form The form object for which the field is being tested. + * + * @return boolean True if the value is valid, false otherwise. + * + * @since 11.1 + */ + public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) + { + // Get the database object and a new query object. + $db = \JFactory::getDbo(); + $query = $db->getQuery(true); + + // Get the extra field check attribute. + $id = ($input instanceof Registry) ? $input->get('id', null) : null; + + // get the component & table name + $table = ($form instanceof Form) ? $form->getName() : ''; + + // get the column name + $name = (array) $element->attributes()->{'name'}; + $column = (string) trim($name[0]); + + // check that we have a value + if (strlen($table) > 3 && strpos($table, 'componentbuilder.') !== false) + { + // now get the table name + $tableArray = explode('.', $table); + // do we have two values + if (count( (array) $tableArray) == 2) + { + // Build the query. + $query->select('COUNT(*)') + ->from('#__componentbuilder_' . (string) $tableArray[1]) + ->where($db->quoteName($column) . ' = ' . $db->quote($value)); + + // remove this item from the list + if ($id > 0) + { + $query->where($db->quoteName('id') . ' <> ' . (int) $id); + } + + // Set and query the database. + $db->setQuery($query); + $duplicate = (bool) $db->loadResult(); + + if ($duplicate) + { + return false; + } + } + } + // now test against all the placeholders in the compiler + return ComponentbuilderHelper::validateUniquePlaceholder($value); + } +} diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index 4841f15ba..aa4ee5f93 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -611,6 +611,32 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_custom_code` ( KEY `idx_from_line` (`from_line`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +CREATE TABLE IF NOT EXISTS `#__componentbuilder_placeholder` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', + `target` VARCHAR(255) NOT NULL DEFAULT '', + `value` TEXT NOT NULL, + `params` text NOT NULL DEFAULT '', + `published` TINYINT(3) NOT NULL DEFAULT 1, + `created_by` INT(10) unsigned NOT NULL DEFAULT 0, + `modified_by` INT(10) unsigned NOT NULL DEFAULT 0, + `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `checked_out` int(11) unsigned NOT NULL DEFAULT 0, + `checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `version` INT(10) unsigned NOT NULL DEFAULT 1, + `hits` INT(10) unsigned NOT NULL DEFAULT 0, + `access` INT(10) unsigned NOT NULL DEFAULT 0, + `ordering` INT(11) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_access` (`access`), + KEY `idx_checkout` (`checked_out`), + KEY `idx_createdby` (`created_by`), + KEY `idx_modifiedby` (`modified_by`), + KEY `idx_state` (`published`), + KEY `idx_target` (`target`) +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC; + CREATE TABLE IF NOT EXISTS `#__componentbuilder_library` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', @@ -1268,6 +1294,32 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_component_files_folders` ( KEY `idx_joomla_component` (`joomla_component`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +CREATE TABLE IF NOT EXISTS `#__componentbuilder_component_placeholders` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', + `addplaceholders` TEXT NOT NULL, + `joomla_component` INT(11) NOT NULL DEFAULT 0, + `params` text NOT NULL DEFAULT '', + `published` TINYINT(3) NOT NULL DEFAULT 1, + `created_by` INT(10) unsigned NOT NULL DEFAULT 0, + `modified_by` INT(10) unsigned NOT NULL DEFAULT 0, + `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `checked_out` int(11) unsigned NOT NULL DEFAULT 0, + `checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `version` INT(10) unsigned NOT NULL DEFAULT 1, + `hits` INT(10) unsigned NOT NULL DEFAULT 0, + `access` INT(10) unsigned NOT NULL DEFAULT 0, + `ordering` INT(11) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_access` (`access`), + KEY `idx_checkout` (`checked_out`), + KEY `idx_createdby` (`created_by`), + KEY `idx_modifiedby` (`modified_by`), + KEY `idx_state` (`published`), + KEY `idx_joomla_component` (`joomla_component`) +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; + CREATE TABLE IF NOT EXISTS `#__componentbuilder_snippet_type` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', diff --git a/admin/sql/uninstall.mysql.utf8.sql b/admin/sql/uninstall.mysql.utf8.sql index d69e8c43d..6dbe36b9e 100644 --- a/admin/sql/uninstall.mysql.utf8.sql +++ b/admin/sql/uninstall.mysql.utf8.sql @@ -6,6 +6,7 @@ DROP TABLE IF EXISTS `#__componentbuilder_template`; DROP TABLE IF EXISTS `#__componentbuilder_layout`; DROP TABLE IF EXISTS `#__componentbuilder_dynamic_get`; DROP TABLE IF EXISTS `#__componentbuilder_custom_code`; +DROP TABLE IF EXISTS `#__componentbuilder_placeholder`; DROP TABLE IF EXISTS `#__componentbuilder_library`; DROP TABLE IF EXISTS `#__componentbuilder_snippet`; DROP TABLE IF EXISTS `#__componentbuilder_validation_rule`; @@ -28,6 +29,7 @@ DROP TABLE IF EXISTS `#__componentbuilder_component_custom_admin_menus`; DROP TABLE IF EXISTS `#__componentbuilder_component_config`; DROP TABLE IF EXISTS `#__componentbuilder_component_dashboard`; DROP TABLE IF EXISTS `#__componentbuilder_component_files_folders`; +DROP TABLE IF EXISTS `#__componentbuilder_component_placeholders`; DROP TABLE IF EXISTS `#__componentbuilder_snippet_type`; DROP TABLE IF EXISTS `#__componentbuilder_library_config`; DROP TABLE IF EXISTS `#__componentbuilder_library_files_folders_urls`; diff --git a/admin/sql/updates/mysql/2.9.11.sql b/admin/sql/updates/mysql/2.9.11.sql new file mode 100644 index 000000000..05b838cc6 --- /dev/null +++ b/admin/sql/updates/mysql/2.9.11.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS `#__componentbuilder_component_placeholders` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', + `addplaceholders` TEXT NOT NULL, + `joomla_component` INT(11) NOT NULL DEFAULT 0, + `params` text NOT NULL DEFAULT '', + `published` TINYINT(3) NOT NULL DEFAULT 1, + `created_by` INT(10) unsigned NOT NULL DEFAULT 0, + `modified_by` INT(10) unsigned NOT NULL DEFAULT 0, + `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `checked_out` int(11) unsigned NOT NULL DEFAULT 0, + `checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `version` INT(10) unsigned NOT NULL DEFAULT 1, + `hits` INT(10) unsigned NOT NULL DEFAULT 0, + `access` INT(10) unsigned NOT NULL DEFAULT 0, + `ordering` INT(11) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_access` (`access`), + KEY `idx_checkout` (`checked_out`), + KEY `idx_createdby` (`created_by`), + KEY `idx_modifiedby` (`modified_by`), + KEY `idx_state` (`published`), + KEY `idx_joomla_component` (`joomla_component`) +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; diff --git a/admin/sql/updates/mysql/2.9.12.sql b/admin/sql/updates/mysql/2.9.12.sql new file mode 100644 index 000000000..1f1683461 --- /dev/null +++ b/admin/sql/updates/mysql/2.9.12.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS `#__componentbuilder_placeholder` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', + `target` VARCHAR(255) NOT NULL DEFAULT '', + `value` TEXT NOT NULL, + `params` text NOT NULL DEFAULT '', + `published` TINYINT(3) NOT NULL DEFAULT 1, + `created_by` INT(10) unsigned NOT NULL DEFAULT 0, + `modified_by` INT(10) unsigned NOT NULL DEFAULT 0, + `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `checked_out` int(11) unsigned NOT NULL DEFAULT 0, + `checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `version` INT(10) unsigned NOT NULL DEFAULT 1, + `hits` INT(10) unsigned NOT NULL DEFAULT 0, + `access` INT(10) unsigned NOT NULL DEFAULT 0, + `ordering` INT(11) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_access` (`access`), + KEY `idx_checkout` (`checked_out`), + KEY `idx_createdby` (`created_by`), + KEY `idx_modifiedby` (`modified_by`), + KEY `idx_state` (`published`), + KEY `idx_target` (`target`) +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC; diff --git a/admin/tables/component_placeholders.php b/admin/tables/component_placeholders.php new file mode 100644 index 000000000..88a89a9c4 --- /dev/null +++ b/admin/tables/component_placeholders.php @@ -0,0 +1,321 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +use Joomla\Registry\Registry; + +/** + * Components_placeholders Table class + */ +class ComponentbuilderTableComponent_placeholders extends JTable +{ + /** + * Ensure the params and metadata in json encoded in the bind method + * + * @var array + * @since 3.3 + */ + protected $_jsonEncode = array('params', 'metadata'); + + /** + * Constructor + * + * @param object Database connector object + */ + function __construct(&$db) + { + parent::__construct('#__componentbuilder_component_placeholders', 'id', $db); + + // Adding History Options + JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_componentbuilder.component_placeholders')); + } + + public function bind($array, $ignore = '') + { + + if (isset($array['params']) && is_array($array['params'])) + { + $registry = new JRegistry; + $registry->loadArray($array['params']); + $array['params'] = (string) $registry; + } + + if (isset($array['metadata']) && is_array($array['metadata'])) + { + $registry = new JRegistry; + $registry->loadArray($array['metadata']); + $array['metadata'] = (string) $registry; + } + + // Bind the rules. + if (isset($array['rules']) && is_array($array['rules'])) + { + $rules = new JAccessRules($array['rules']); + $this->setRules($rules); + } + return parent::bind($array, $ignore); + } + + /** + * Overload the store method for the Component_placeholders table. + * + * @param boolean Toggle whether null values should be updated. + * @return boolean True on success, false on failure. + * @since 1.6 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + if ($this->id) + { + // Existing item + $this->modified = $date->toSql(); + $this->modified_by = $user->get('id'); + } + else + { + // New component_placeholders. A component_placeholders created and created_by field can be set by the user, + // so we don't touch either of these if they are set. + if (!(int) $this->created) + { + $this->created = $date->toSql(); + } + if (empty($this->created_by)) + { + $this->created_by = $user->get('id'); + } + } + + if (isset($this->alias)) + { + // Verify that the alias is unique + $table = JTable::getInstance('component_placeholders', 'ComponentbuilderTable'); + + if ($table->load(array('alias' => $this->alias)) && ($table->id != $this->id || $this->id == 0)) + { + $this->setError(JText::_('COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_ERROR_UNIQUE_ALIAS')); + return false; + } + } + + if (isset($this->url)) + { + // Convert IDN urls to punycode + $this->url = JStringPunycode::urlToPunycode($this->url); + } + if (isset($this->website)) + { + // Convert IDN urls to punycode + $this->website = JStringPunycode::urlToPunycode($this->website); + } + + return parent::store($updateNulls); + } + + /** + * Overloaded check method to ensure data integrity. + * + * @return boolean True on success. + */ + public function check() + { + if (isset($this->alias)) + { + // Generate a valid alias + $this->generateAlias(); + + $table = JTable::getInstance('component_placeholders', 'componentbuilderTable'); + + while ($table->load(array('alias' => $this->alias)) && ($table->id != $this->id || $this->id == 0)) + { + $this->alias = JString::increment($this->alias, 'dash'); + } + } + + /* + * Clean up keywords -- eliminate extra spaces between phrases + * and cr (\r) and lf (\n) characters from string. + * Only process if not empty. + */ + if (!empty($this->metakey)) + { + // Array of characters to remove. + $bad_characters = array("\n", "\r", "\"", "<", ">"); + + // Remove bad characters. + $after_clean = JString::str_ireplace($bad_characters, "", $this->metakey); + + // Create array using commas as delimiter. + $keys = explode(',', $after_clean); + $clean_keys = array(); + + foreach ($keys as $key) + { + // Ignore blank keywords. + if (trim($key)) + { + $clean_keys[] = trim($key); + } + } + + // Put array back together delimited by ", " + $this->metakey = implode(", ", $clean_keys); + } + + // Clean up description -- eliminate quotes and <> brackets + if (!empty($this->metadesc)) + { + // Only process if not empty + $bad_characters = array("\"", "<", ">"); + $this->metadesc = JString::str_ireplace($bad_characters, "", $this->metadesc); + } + + // If we don't have any access rules set at this point just use an empty JAccessRules class + if (!$this->getRules()) + { + $rules = $this->getDefaultAssetValues('com_componentbuilder.component_placeholders.'.$this->id); + $this->setRules($rules); + } + + // Set ordering + if ($this->published < 0) + { + // Set ordering to 0 if state is archived or trashed + $this->ordering = 0; + } + + return true; + } + + /** + * Gets the default asset values for a component. + * + * @param $string $component The component asset name to search for + * + * @return JAccessRules The JAccessRules object for the asset + */ + protected function getDefaultAssetValues($component, $try = true) + { + // Need to find the asset id by the name of the component. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__assets')) + ->where($db->quoteName('name') . ' = ' . $db->quote($component)); + $db->setQuery($query); + $db->execute(); + if ($db->loadRowList()) + { + // asset alread set so use saved rules + $assetId = (int) $db->loadResult(); + return JAccess::getAssetRules($assetId); // (TODO) instead of keeping inherited Allowed it becomes Allowed. + } + // try again + elseif ($try) + { + $try = explode('.',$component); + $result = $this->getDefaultAssetValues($try[0], false); + if ($result instanceof JAccessRules) + { + if (isset($try[1])) + { + $_result = (string) $result; + $_result = json_decode($_result); + foreach ($_result as $name => &$rule) + { + $v = explode('.', $name); + if ($try[1] !== $v[0]) + { + // remove since it is not part of this view + unset($_result->$name); + } + else + { + // clear the value since we inherit + $rule = array(); + } + } + // check if there are any view values remaining + if (count( (array) $_result)) + { + $_result = json_encode($_result); + $_result = array($_result); + // Instantiate and return the JAccessRules object for the asset rules. + $rules = new JAccessRules; + $rules->mergeCollection($_result); + + return $rules; + } + } + return $result; + } + } + return JAccess::getAssetRules(0); + } + + /** + * Method to compute the default name of the asset. + * The default name is in the form 'table_name.id' + * where id is the value of the primary key of the table. + * + * @return string + * @since 2.5 + */ + protected function _getAssetName() + { + $k = $this->_tbl_key; + return 'com_componentbuilder.component_placeholders.'.(int) $this->$k; + } + + /** + * Method to return the title to use for the asset table. + * + * @return string + * @since 2.5 + */ + protected function _getAssetTitle() + { + if (isset($this->title)) + { + return $this->title; + } + return ''; + } + + /** + * Get the parent asset id for the record + * + * @return int + * @since 2.5 + */ + protected function _getAssetParentId(JTable $table = NULL, $id = NULL) + { + $asset = JTable::getInstance('Asset'); + $asset->loadByName('com_componentbuilder'); + + return $asset->id; + } + + /** + * This view does not actually have an alias + * + * @return bool + */ + public function generateAlias() + { + return false; + } + +} diff --git a/admin/tables/placeholder.php b/admin/tables/placeholder.php new file mode 100644 index 000000000..af2d955f1 --- /dev/null +++ b/admin/tables/placeholder.php @@ -0,0 +1,321 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +use Joomla\Registry\Registry; + +/** + * Placeholders Table class + */ +class ComponentbuilderTablePlaceholder extends JTable +{ + /** + * Ensure the params and metadata in json encoded in the bind method + * + * @var array + * @since 3.3 + */ + protected $_jsonEncode = array('params', 'metadata'); + + /** + * Constructor + * + * @param object Database connector object + */ + function __construct(&$db) + { + parent::__construct('#__componentbuilder_placeholder', 'id', $db); + + // Adding History Options + JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_componentbuilder.placeholder')); + } + + public function bind($array, $ignore = '') + { + + if (isset($array['params']) && is_array($array['params'])) + { + $registry = new JRegistry; + $registry->loadArray($array['params']); + $array['params'] = (string) $registry; + } + + if (isset($array['metadata']) && is_array($array['metadata'])) + { + $registry = new JRegistry; + $registry->loadArray($array['metadata']); + $array['metadata'] = (string) $registry; + } + + // Bind the rules. + if (isset($array['rules']) && is_array($array['rules'])) + { + $rules = new JAccessRules($array['rules']); + $this->setRules($rules); + } + return parent::bind($array, $ignore); + } + + /** + * Overload the store method for the Placeholder table. + * + * @param boolean Toggle whether null values should be updated. + * @return boolean True on success, false on failure. + * @since 1.6 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + if ($this->id) + { + // Existing item + $this->modified = $date->toSql(); + $this->modified_by = $user->get('id'); + } + else + { + // New placeholder. A placeholder created and created_by field can be set by the user, + // so we don't touch either of these if they are set. + if (!(int) $this->created) + { + $this->created = $date->toSql(); + } + if (empty($this->created_by)) + { + $this->created_by = $user->get('id'); + } + } + + if (isset($this->alias)) + { + // Verify that the alias is unique + $table = JTable::getInstance('placeholder', 'ComponentbuilderTable'); + + if ($table->load(array('alias' => $this->alias)) && ($table->id != $this->id || $this->id == 0)) + { + $this->setError(JText::_('COM_COMPONENTBUILDER_PLACEHOLDER_ERROR_UNIQUE_ALIAS')); + return false; + } + } + + if (isset($this->url)) + { + // Convert IDN urls to punycode + $this->url = JStringPunycode::urlToPunycode($this->url); + } + if (isset($this->website)) + { + // Convert IDN urls to punycode + $this->website = JStringPunycode::urlToPunycode($this->website); + } + + return parent::store($updateNulls); + } + + /** + * Overloaded check method to ensure data integrity. + * + * @return boolean True on success. + */ + public function check() + { + if (isset($this->alias)) + { + // Generate a valid alias + $this->generateAlias(); + + $table = JTable::getInstance('placeholder', 'componentbuilderTable'); + + while ($table->load(array('alias' => $this->alias)) && ($table->id != $this->id || $this->id == 0)) + { + $this->alias = JString::increment($this->alias, 'dash'); + } + } + + /* + * Clean up keywords -- eliminate extra spaces between phrases + * and cr (\r) and lf (\n) characters from string. + * Only process if not empty. + */ + if (!empty($this->metakey)) + { + // Array of characters to remove. + $bad_characters = array("\n", "\r", "\"", "<", ">"); + + // Remove bad characters. + $after_clean = JString::str_ireplace($bad_characters, "", $this->metakey); + + // Create array using commas as delimiter. + $keys = explode(',', $after_clean); + $clean_keys = array(); + + foreach ($keys as $key) + { + // Ignore blank keywords. + if (trim($key)) + { + $clean_keys[] = trim($key); + } + } + + // Put array back together delimited by ", " + $this->metakey = implode(", ", $clean_keys); + } + + // Clean up description -- eliminate quotes and <> brackets + if (!empty($this->metadesc)) + { + // Only process if not empty + $bad_characters = array("\"", "<", ">"); + $this->metadesc = JString::str_ireplace($bad_characters, "", $this->metadesc); + } + + // If we don't have any access rules set at this point just use an empty JAccessRules class + if (!$this->getRules()) + { + $rules = $this->getDefaultAssetValues('com_componentbuilder.placeholder.'.$this->id); + $this->setRules($rules); + } + + // Set ordering + if ($this->published < 0) + { + // Set ordering to 0 if state is archived or trashed + $this->ordering = 0; + } + + return true; + } + + /** + * Gets the default asset values for a component. + * + * @param $string $component The component asset name to search for + * + * @return JAccessRules The JAccessRules object for the asset + */ + protected function getDefaultAssetValues($component, $try = true) + { + // Need to find the asset id by the name of the component. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__assets')) + ->where($db->quoteName('name') . ' = ' . $db->quote($component)); + $db->setQuery($query); + $db->execute(); + if ($db->loadRowList()) + { + // asset alread set so use saved rules + $assetId = (int) $db->loadResult(); + return JAccess::getAssetRules($assetId); // (TODO) instead of keeping inherited Allowed it becomes Allowed. + } + // try again + elseif ($try) + { + $try = explode('.',$component); + $result = $this->getDefaultAssetValues($try[0], false); + if ($result instanceof JAccessRules) + { + if (isset($try[1])) + { + $_result = (string) $result; + $_result = json_decode($_result); + foreach ($_result as $name => &$rule) + { + $v = explode('.', $name); + if ($try[1] !== $v[0]) + { + // remove since it is not part of this view + unset($_result->$name); + } + else + { + // clear the value since we inherit + $rule = array(); + } + } + // check if there are any view values remaining + if (count( (array) $_result)) + { + $_result = json_encode($_result); + $_result = array($_result); + // Instantiate and return the JAccessRules object for the asset rules. + $rules = new JAccessRules; + $rules->mergeCollection($_result); + + return $rules; + } + } + return $result; + } + } + return JAccess::getAssetRules(0); + } + + /** + * Method to compute the default name of the asset. + * The default name is in the form 'table_name.id' + * where id is the value of the primary key of the table. + * + * @return string + * @since 2.5 + */ + protected function _getAssetName() + { + $k = $this->_tbl_key; + return 'com_componentbuilder.placeholder.'.(int) $this->$k; + } + + /** + * Method to return the title to use for the asset table. + * + * @return string + * @since 2.5 + */ + protected function _getAssetTitle() + { + if (isset($this->title)) + { + return $this->title; + } + return ''; + } + + /** + * Get the parent asset id for the record + * + * @return int + * @since 2.5 + */ + protected function _getAssetParentId(JTable $table = NULL, $id = NULL) + { + $asset = JTable::getInstance('Asset'); + $asset->loadByName('com_componentbuilder'); + + return $asset->id; + } + + /** + * This view does not actually have an alias + * + * @return bool + */ + public function generateAlias() + { + return false; + } + +} diff --git a/admin/views/component_placeholders/submitbutton.js b/admin/views/component_placeholders/submitbutton.js new file mode 100644 index 000000000..f7e80b88f --- /dev/null +++ b/admin/views/component_placeholders/submitbutton.js @@ -0,0 +1,25 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +Joomla.submitbutton = function(task) +{ + if (task == ''){ + return false; + } else { + var action = task.split('.'); + if (action[1] == 'cancel' || action[1] == 'close' || document.formvalidator.isValid(document.getElementById("adminForm"))){ + Joomla.submitform(task, document.getElementById("adminForm")); + return true; + } else { + alert(Joomla.JText._('component_placeholders, some values are not acceptable.','Some values are unacceptable')); + return false; + } + } +} \ No newline at end of file diff --git a/admin/views/component_placeholders/tmpl/edit.php b/admin/views/component_placeholders/tmpl/edit.php new file mode 100644 index 000000000..fec03bfd1 --- /dev/null +++ b/admin/views/component_placeholders/tmpl/edit.php @@ -0,0 +1,107 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); +JHtml::_('behavior.tooltip'); +JHtml::_('behavior.formvalidation'); +JHtml::_('formbehavior.chosen', 'select'); +JHtml::_('behavior.keepalive'); +$componentParams = $this->params; // will be removed just use $this->params instead +?> + + + + diff --git a/admin/views/component_placeholders/tmpl/index.html b/admin/views/component_placeholders/tmpl/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/admin/views/component_placeholders/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/views/component_placeholders/view.html.php b/admin/views/component_placeholders/view.html.php new file mode 100644 index 000000000..5eef5d1c9 --- /dev/null +++ b/admin/views/component_placeholders/view.html.php @@ -0,0 +1,195 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Component_placeholders View class + */ +class ComponentbuilderViewComponent_placeholders extends JViewLegacy +{ + /** + * display method of View + * @return void + */ + public function display($tpl = null) + { + // set params + $this->params = JComponentHelper::getParams('com_componentbuilder'); + // Assign the variables + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->script = $this->get('Script'); + $this->state = $this->get('State'); + // get action permissions + $this->canDo = ComponentbuilderHelper::getActions('component_placeholders', $this->item); + // get input + $jinput = JFactory::getApplication()->input; + $this->ref = $jinput->get('ref', 0, 'word'); + $this->refid = $jinput->get('refid', 0, 'int'); + $return = $jinput->get('return', null, 'base64'); + // set the referral string + $this->referral = ''; + if ($this->refid && $this->ref) + { + // return to the item that referred to this item + $this->referral = '&ref=' . (string)$this->ref . '&refid=' . (int)$this->refid; + } + elseif($this->ref) + { + // return to the list view that referred to this item + $this->referral = '&ref=' . (string)$this->ref; + } + // check return value + if (!is_null($return)) + { + // add the return value + $this->referral .= '&return=' . (string)$return; + } + + // Set the toolbar + $this->addToolBar(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Display the template + parent::display($tpl); + + // Set the document + $this->setDocument(); + } + + + /** + * Setting the toolbar + */ + protected function addToolBar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + $user = JFactory::getUser(); + $userId = $user->id; + $isNew = $this->item->id == 0; + + JToolbarHelper::title( JText::_($isNew ? 'COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_NEW' : 'COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_EDIT'), 'pencil-2 article-add'); + // Built the actions for new and existing records. + if (ComponentbuilderHelper::checkString($this->referral)) + { + if ($this->canDo->get('component_placeholders.create') && $isNew) + { + // We can create the record. + JToolBarHelper::save('component_placeholders.save', 'JTOOLBAR_SAVE'); + } + elseif ($this->canDo->get('component_placeholders.edit')) + { + // We can save the record. + JToolBarHelper::save('component_placeholders.save', 'JTOOLBAR_SAVE'); + } + if ($isNew) + { + // Do not creat but cancel. + JToolBarHelper::cancel('component_placeholders.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + // We can close it. + JToolBarHelper::cancel('component_placeholders.cancel', 'JTOOLBAR_CLOSE'); + } + } + else + { + if ($isNew) + { + // For new records, check the create permission. + if ($this->canDo->get('component_placeholders.create')) + { + JToolBarHelper::apply('component_placeholders.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('component_placeholders.save', 'JTOOLBAR_SAVE'); + JToolBarHelper::custom('component_placeholders.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + }; + JToolBarHelper::cancel('component_placeholders.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + if ($this->canDo->get('component_placeholders.edit')) + { + // We can save the new record + JToolBarHelper::apply('component_placeholders.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('component_placeholders.save', 'JTOOLBAR_SAVE'); + // We can save this record, but check the create permission to see + // if we can return to make a new one. + if ($this->canDo->get('component_placeholders.create')) + { + JToolBarHelper::custom('component_placeholders.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + } + $canVersion = ($this->canDo->get('core.version') && $this->canDo->get('component_placeholders.version')); + if ($this->state->params->get('save_history', 1) && $this->canDo->get('component_placeholders.edit') && $canVersion) + { + JToolbarHelper::versions('com_componentbuilder.component_placeholders', $this->item->id); + } + if ($this->canDo->get('component_placeholders.create')) + { + JToolBarHelper::custom('component_placeholders.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + } + JToolBarHelper::cancel('component_placeholders.cancel', 'JTOOLBAR_CLOSE'); + } + } + JToolbarHelper::divider(); + // set help url for this view if found + $help_url = ComponentbuilderHelper::getHelpUrl('component_placeholders'); + if (ComponentbuilderHelper::checkString($help_url)) + { + JToolbarHelper::help('COM_COMPONENTBUILDER_HELP_MANAGER', false, $help_url); + } + } + + /** + * Escapes a value for output in a view script. + * + * @param mixed $var The output to escape. + * + * @return mixed The escaped value. + */ + public function escape($var) + { + if(strlen($var) > 30) + { + // use the helper htmlEscape method instead and shorten the string + return ComponentbuilderHelper::htmlEscape($var, $this->_charset, true, 30); + } + // use the helper htmlEscape method instead. + return ComponentbuilderHelper::htmlEscape($var, $this->_charset); + } + + /** + * Method to set up the document properties + * + * @return void + */ + protected function setDocument() + { + $isNew = ($this->item->id < 1); + if (!isset($this->document)) + { + $this->document = JFactory::getDocument(); + } + $this->document->setTitle(JText::_($isNew ? 'COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_NEW' : 'COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_EDIT')); + $this->document->addStyleSheet(JURI::root() . "administrator/components/com_componentbuilder/assets/css/component_placeholders.css", (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); + $this->document->addScript(JURI::root() . $this->script, (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript'); + $this->document->addScript(JURI::root() . "administrator/components/com_componentbuilder/views/component_placeholders/submitbutton.js", (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript'); + JText::script('view not acceptable. Error'); + } +} diff --git a/admin/views/components_placeholders/index.html b/admin/views/components_placeholders/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/admin/views/components_placeholders/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/views/components_placeholders/tmpl/default.php b/admin/views/components_placeholders/tmpl/default.php new file mode 100644 index 000000000..fbf511bf4 --- /dev/null +++ b/admin/views/components_placeholders/tmpl/default.php @@ -0,0 +1,85 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// load tooltip behavior +JHtml::_('behavior.tooltip'); +JHtml::_('behavior.multiselect'); +JHtml::_('dropdown.init'); +JHtml::_('formbehavior.chosen', 'select'); + +if ($this->saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_componentbuilder&task=components_placeholders.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'component_placeholdersList', 'adminForm', strtolower($this->listDirn), $saveOrderingUrl); +} + +?> + +
+sidebar)): ?> +
+ sidebar; ?> +
+
+ +
+ +items)): ?> + loadTemplate('toolbar');?> +
+ +
+ + loadTemplate('toolbar');?> + + loadTemplate('head');?> + loadTemplate('foot');?> + loadTemplate('body');?> +
+ + canCreate && $this->canEdit) : ?> + JText::_('COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + + +
+ + + + \ No newline at end of file diff --git a/admin/views/components_placeholders/tmpl/default_batch_body.php b/admin/views/components_placeholders/tmpl/default_batch_body.php new file mode 100644 index 000000000..cd9ecb2e4 --- /dev/null +++ b/admin/views/components_placeholders/tmpl/default_batch_body.php @@ -0,0 +1,18 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> + +

+batchDisplay; ?> \ No newline at end of file diff --git a/admin/views/components_placeholders/tmpl/default_batch_footer.php b/admin/views/components_placeholders/tmpl/default_batch_footer.php new file mode 100644 index 000000000..4c9d880be --- /dev/null +++ b/admin/views/components_placeholders/tmpl/default_batch_footer.php @@ -0,0 +1,23 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> + + + + \ No newline at end of file diff --git a/admin/views/components_placeholders/tmpl/default_body.php b/admin/views/components_placeholders/tmpl/default_body.php new file mode 100644 index 000000000..f83164b68 --- /dev/null +++ b/admin/views/components_placeholders/tmpl/default_body.php @@ -0,0 +1,94 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$edit = "index.php?option=com_componentbuilder&view=components_placeholders&task=component_placeholders.edit"; + +?> +items as $i => $item): ?> + user->authorise('core.manage', 'com_checkin') || $item->checked_out == $this->user->id || $item->checked_out == 0; + $userChkOut = JFactory::getUser($item->checked_out); + $canDo = ComponentbuilderHelper::getActions('component_placeholders',$item,'components_placeholders'); + ?> + + + get('component_placeholders.edit.state')): ?> + saveOrder) + { + $iconClass = ' inactive'; + } + else + { + $iconClass = ' inactive tip-top" hasTooltip" title="' . JHtml::tooltipText('JORDERINGDISABLED'); + } + ?> + + + + saveOrder) : ?> + + + + ⋮ + + + + get('component_placeholders.edit')): ?> + checked_out) : ?> + + id); ?> + + □ + + + id); ?> + + + □ + + + +
+ get('component_placeholders.edit')): ?> + escape($item->joomla_component_system_name); ?> + checked_out): ?> + name, $item->checked_out_time, 'components_placeholders.', $canCheckin); ?> + + + escape($item->joomla_component_system_name); ?> + +
+ + + get('component_placeholders.edit.state')) : ?> + checked_out) : ?> + + published, $i, 'components_placeholders.', true, 'cb'); ?> + + published, $i, 'components_placeholders.', false, 'cb'); ?> + + + published, $i, 'components_placeholders.', true, 'cb'); ?> + + + published, $i, 'components_placeholders.', false, 'cb'); ?> + + + + id; ?> + + + \ No newline at end of file diff --git a/admin/views/components_placeholders/tmpl/default_foot.php b/admin/views/components_placeholders/tmpl/default_foot.php new file mode 100644 index 000000000..297242b41 --- /dev/null +++ b/admin/views/components_placeholders/tmpl/default_foot.php @@ -0,0 +1,18 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> + + pagination->getListFooter(); ?> + \ No newline at end of file diff --git a/admin/views/components_placeholders/tmpl/default_head.php b/admin/views/components_placeholders/tmpl/default_head.php new file mode 100644 index 000000000..96dfd9341 --- /dev/null +++ b/admin/views/components_placeholders/tmpl/default_head.php @@ -0,0 +1,47 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> + + canEdit&& $this->canState): ?> + + ', 'ordering', $this->listDirn, $this->listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?> + + + + + + + ▾ + + + ■ + + + + + + canState): ?> + + listDirn, $this->listOrder); ?> + + + + + + + + listDirn, $this->listOrder); ?> + + \ No newline at end of file diff --git a/admin/views/components_placeholders/tmpl/default_toolbar.php b/admin/views/components_placeholders/tmpl/default_toolbar.php new file mode 100644 index 000000000..0090ad08c --- /dev/null +++ b/admin/views/components_placeholders/tmpl/default_toolbar.php @@ -0,0 +1,45 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> +
+ +
+ + +
+
+ + pagination->getLimitBox(); ?> +
+
+ + +
+
+ + +
+
+
\ No newline at end of file diff --git a/admin/views/components_placeholders/tmpl/index.html b/admin/views/components_placeholders/tmpl/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/admin/views/components_placeholders/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/views/components_placeholders/view.html.php b/admin/views/components_placeholders/view.html.php new file mode 100644 index 000000000..f0f076420 --- /dev/null +++ b/admin/views/components_placeholders/view.html.php @@ -0,0 +1,226 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Componentbuilder View class for the Components_placeholders + */ +class ComponentbuilderViewComponents_placeholders extends JViewLegacy +{ + /** + * Components_placeholders view display method + * @return void + */ + function display($tpl = null) + { + if ($this->getLayout() !== 'modal') + { + // Include helper submenu + ComponentbuilderHelper::addSubmenu('components_placeholders'); + } + + // Assign data to the view + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->user = JFactory::getUser(); + $this->listOrder = $this->escape($this->state->get('list.ordering')); + $this->listDirn = $this->escape($this->state->get('list.direction')); + $this->saveOrder = $this->listOrder == 'ordering'; + // set the return here value + $this->return_here = urlencode(base64_encode((string) JUri::getInstance())); + // get global action permissions + $this->canDo = ComponentbuilderHelper::getActions('component_placeholders'); + $this->canEdit = $this->canDo->get('component_placeholders.edit'); + $this->canState = $this->canDo->get('component_placeholders.edit.state'); + $this->canCreate = $this->canDo->get('component_placeholders.create'); + $this->canDelete = $this->canDo->get('component_placeholders.delete'); + $this->canBatch = $this->canDo->get('core.batch'); + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + // load the batch html + if ($this->canCreate && $this->canEdit && $this->canState) + { + $this->batchDisplay = JHtmlBatch_::render(); + } + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Display the template + parent::display($tpl); + + // Set the document + $this->setDocument(); + } + + /** + * Setting the toolbar + */ + protected function addToolBar() + { + JToolBarHelper::title(JText::_('COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS'), 'joomla'); + JHtmlSidebar::setAction('index.php?option=com_componentbuilder&view=components_placeholders'); + JFormHelper::addFieldPath(JPATH_COMPONENT . '/models/fields'); + + if ($this->canCreate) + { + JToolBarHelper::addNew('component_placeholders.add'); + } + + // Only load if there are items + if (ComponentbuilderHelper::checkArray($this->items)) + { + if ($this->canEdit) + { + JToolBarHelper::editList('component_placeholders.edit'); + } + + if ($this->canState) + { + JToolBarHelper::publishList('components_placeholders.publish'); + JToolBarHelper::unpublishList('components_placeholders.unpublish'); + JToolBarHelper::archiveList('components_placeholders.archive'); + + if ($this->canDo->get('core.admin')) + { + JToolBarHelper::checkin('components_placeholders.checkin'); + } + } + + // Add a batch button + if ($this->canBatch && $this->canCreate && $this->canEdit && $this->canState) + { + // Get the toolbar object instance + $bar = JToolBar::getInstance('toolbar'); + // set the batch button name + $title = JText::_('JTOOLBAR_BATCH'); + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('joomla.toolbar.batch'); + // add the button to the page + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($this->state->get('filter.published') == -2 && ($this->canState && $this->canDelete)) + { + JToolbarHelper::deleteList('', 'components_placeholders.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($this->canState && $this->canDelete) + { + JToolbarHelper::trash('components_placeholders.trash'); + } + } + + // set help url for this view if found + $help_url = ComponentbuilderHelper::getHelpUrl('components_placeholders'); + if (ComponentbuilderHelper::checkString($help_url)) + { + JToolbarHelper::help('COM_COMPONENTBUILDER_HELP_MANAGER', false, $help_url); + } + + // add the options comp button + if ($this->canDo->get('core.admin') || $this->canDo->get('core.options')) + { + JToolBarHelper::preferences('com_componentbuilder'); + } + + if ($this->canState) + { + JHtmlSidebar::addFilter( + JText::_('JOPTION_SELECT_PUBLISHED'), + 'filter_published', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.published'), true) + ); + // only load if batch allowed + if ($this->canBatch) + { + JHtmlBatch_::addListSelection( + JText::_('COM_COMPONENTBUILDER_KEEP_ORIGINAL_STATE'), + 'batch[published]', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions', array('all' => false)), 'value', 'text', '', true) + ); + } + } + + JHtmlSidebar::addFilter( + JText::_('JOPTION_SELECT_ACCESS'), + 'filter_access', + JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text', $this->state->get('filter.access')) + ); + + if ($this->canBatch && $this->canCreate && $this->canEdit) + { + JHtmlBatch_::addListSelection( + JText::_('COM_COMPONENTBUILDER_KEEP_ORIGINAL_ACCESS'), + 'batch[access]', + JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text') + ); + } + } + + /** + * Method to set up the document properties + * + * @return void + */ + protected function setDocument() + { + if (!isset($this->document)) + { + $this->document = JFactory::getDocument(); + } + $this->document->setTitle(JText::_('COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS')); + $this->document->addStyleSheet(JURI::root() . "administrator/components/com_componentbuilder/assets/css/components_placeholders.css", (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); + } + + /** + * Escapes a value for output in a view script. + * + * @param mixed $var The output to escape. + * + * @return mixed The escaped value. + */ + public function escape($var) + { + if(strlen($var) > 50) + { + // use the helper htmlEscape method instead and shorten the string + return ComponentbuilderHelper::htmlEscape($var, $this->_charset, true); + } + // use the helper htmlEscape method instead. + return ComponentbuilderHelper::htmlEscape($var, $this->_charset); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + */ + protected function getSortFields() + { + return array( + 'a.sorting' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } +} diff --git a/admin/views/joomla_components/tmpl/default_body.php b/admin/views/joomla_components/tmpl/default_body.php index 95607e7a7..ab944a8d6 100644 --- a/admin/views/joomla_components/tmpl/default_body.php +++ b/admin/views/joomla_components/tmpl/default_body.php @@ -104,6 +104,11 @@ $edit = "index.php?option=com_componentbuilder&view=joomla_components&task=jooml 'icon' => 'options') ); $_buttons[1] = array( + array( + 'view' => 'component_placeholders', + 'views' => 'components_placeholders', + 'title' => JText::_('COM_COMPONENTBUILDER_THE_COMPONENT_PLACEHOLDERS'), + 'icon' => 'search'), array( 'view' => 'component_updates', 'views' => 'components_updates', diff --git a/admin/views/placeholder/submitbutton.js b/admin/views/placeholder/submitbutton.js new file mode 100644 index 000000000..c5286068e --- /dev/null +++ b/admin/views/placeholder/submitbutton.js @@ -0,0 +1,25 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +Joomla.submitbutton = function(task) +{ + if (task == ''){ + return false; + } else { + var action = task.split('.'); + if (action[1] == 'cancel' || action[1] == 'close' || document.formvalidator.isValid(document.getElementById("adminForm"))){ + Joomla.submitform(task, document.getElementById("adminForm")); + return true; + } else { + alert(Joomla.JText._('placeholder, some values are not acceptable.','Some values are unacceptable')); + return false; + } + } +} \ No newline at end of file diff --git a/admin/views/placeholder/tmpl/edit.php b/admin/views/placeholder/tmpl/edit.php new file mode 100644 index 000000000..973df6709 --- /dev/null +++ b/admin/views/placeholder/tmpl/edit.php @@ -0,0 +1,107 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); +JHtml::_('behavior.tooltip'); +JHtml::_('behavior.formvalidation'); +JHtml::_('formbehavior.chosen', 'select'); +JHtml::_('behavior.keepalive'); +$componentParams = $this->params; // will be removed just use $this->params instead +?> + + + +
diff --git a/admin/views/placeholder/tmpl/index.html b/admin/views/placeholder/tmpl/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/admin/views/placeholder/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/views/placeholder/view.html.php b/admin/views/placeholder/view.html.php new file mode 100644 index 000000000..6cf5b2664 --- /dev/null +++ b/admin/views/placeholder/view.html.php @@ -0,0 +1,208 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Placeholder View class + */ +class ComponentbuilderViewPlaceholder extends JViewLegacy +{ + /** + * display method of View + * @return void + */ + public function display($tpl = null) + { + // set params + $this->params = JComponentHelper::getParams('com_componentbuilder'); + // Assign the variables + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->script = $this->get('Script'); + $this->state = $this->get('State'); + // get action permissions + $this->canDo = ComponentbuilderHelper::getActions('placeholder', $this->item); + // get input + $jinput = JFactory::getApplication()->input; + $this->ref = $jinput->get('ref', 0, 'word'); + $this->refid = $jinput->get('refid', 0, 'int'); + $return = $jinput->get('return', null, 'base64'); + // set the referral string + $this->referral = ''; + if ($this->refid && $this->ref) + { + // return to the item that referred to this item + $this->referral = '&ref=' . (string)$this->ref . '&refid=' . (int)$this->refid; + } + elseif($this->ref) + { + // return to the list view that referred to this item + $this->referral = '&ref=' . (string)$this->ref; + } + // check return value + if (!is_null($return)) + { + // add the return value + $this->referral .= '&return=' . (string)$return; + } + + // Set the toolbar + $this->addToolBar(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Display the template + parent::display($tpl); + + // Set the document + $this->setDocument(); + } + + + /** + * Setting the toolbar + */ + protected function addToolBar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + $user = JFactory::getUser(); + $userId = $user->id; + $isNew = $this->item->id == 0; + + JToolbarHelper::title( JText::_($isNew ? 'COM_COMPONENTBUILDER_PLACEHOLDER_NEW' : 'COM_COMPONENTBUILDER_PLACEHOLDER_EDIT'), 'pencil-2 article-add'); + // Built the actions for new and existing records. + if (ComponentbuilderHelper::checkString($this->referral)) + { + if ($this->canDo->get('placeholder.create') && $isNew) + { + // We can create the record. + JToolBarHelper::save('placeholder.save', 'JTOOLBAR_SAVE'); + } + elseif ($this->canDo->get('placeholder.edit')) + { + // We can save the record. + JToolBarHelper::save('placeholder.save', 'JTOOLBAR_SAVE'); + } + if ($isNew) + { + // Do not creat but cancel. + JToolBarHelper::cancel('placeholder.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + // We can close it. + JToolBarHelper::cancel('placeholder.cancel', 'JTOOLBAR_CLOSE'); + } + } + else + { + if ($isNew) + { + // For new records, check the create permission. + if ($this->canDo->get('placeholder.create')) + { + JToolBarHelper::apply('placeholder.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('placeholder.save', 'JTOOLBAR_SAVE'); + JToolBarHelper::custom('placeholder.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + }; + JToolBarHelper::cancel('placeholder.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + if ($this->canDo->get('placeholder.edit')) + { + // We can save the new record + JToolBarHelper::apply('placeholder.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('placeholder.save', 'JTOOLBAR_SAVE'); + // We can save this record, but check the create permission to see + // if we can return to make a new one. + if ($this->canDo->get('placeholder.create')) + { + JToolBarHelper::custom('placeholder.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + } + $canVersion = ($this->canDo->get('core.version') && $this->canDo->get('placeholder.version')); + if ($this->state->params->get('save_history', 1) && $this->canDo->get('placeholder.edit') && $canVersion) + { + JToolbarHelper::versions('com_componentbuilder.placeholder', $this->item->id); + } + if ($this->canDo->get('placeholder.create')) + { + JToolBarHelper::custom('placeholder.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + } + JToolBarHelper::cancel('placeholder.cancel', 'JTOOLBAR_CLOSE'); + } + } + JToolbarHelper::divider(); + // set help url for this view if found + $help_url = ComponentbuilderHelper::getHelpUrl('placeholder'); + if (ComponentbuilderHelper::checkString($help_url)) + { + JToolbarHelper::help('COM_COMPONENTBUILDER_HELP_MANAGER', false, $help_url); + } + } + + /** + * Escapes a value for output in a view script. + * + * @param mixed $var The output to escape. + * + * @return mixed The escaped value. + */ + public function escape($var) + { + if(strlen($var) > 30) + { + // use the helper htmlEscape method instead and shorten the string + return ComponentbuilderHelper::htmlEscape($var, $this->_charset, true, 30); + } + // use the helper htmlEscape method instead. + return ComponentbuilderHelper::htmlEscape($var, $this->_charset); + } + + /** + * Method to set up the document properties + * + * @return void + */ + protected function setDocument() + { + $isNew = ($this->item->id < 1); + if (!isset($this->document)) + { + $this->document = JFactory::getDocument(); + } + $this->document->setTitle(JText::_($isNew ? 'COM_COMPONENTBUILDER_PLACEHOLDER_NEW' : 'COM_COMPONENTBUILDER_PLACEHOLDER_EDIT')); + $this->document->addStyleSheet(JURI::root() . "administrator/components/com_componentbuilder/assets/css/placeholder.css", (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); + $this->document->addScript(JURI::root() . $this->script, (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript'); + $this->document->addScript(JURI::root() . "administrator/components/com_componentbuilder/views/placeholder/submitbutton.js", (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript'); + + // add the Uikit v2 style sheets + $this->document->addStyleSheet( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/css/uikit.gradient.min.css' , (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); + $this->document->addStyleSheet( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/css/components/notify.gradient.min.css' , (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); + + // add Uikit v2 JavaScripts + $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/uikit.min.js' , (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript'); + $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/components/lightbox.min.js', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('type' => 'text/javascript', 'async' => 'async') : true); + $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/components/notify.min.js', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('type' => 'text/javascript', 'async' => 'async') : true); + // add var key + $this->document->addScriptDeclaration("var vastDevMod = '" . $this->get('VDM') . "';"); + // add return_here + $this->document->addScriptDeclaration("var return_here = '" . urlencode(base64_encode((string) JUri::getInstance())) . "';"); + JText::script('view not acceptable. Error'); + } +} diff --git a/admin/views/placeholders/index.html b/admin/views/placeholders/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/admin/views/placeholders/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/views/placeholders/tmpl/default.php b/admin/views/placeholders/tmpl/default.php new file mode 100644 index 000000000..302bc91b0 --- /dev/null +++ b/admin/views/placeholders/tmpl/default.php @@ -0,0 +1,85 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// load tooltip behavior +JHtml::_('behavior.tooltip'); +JHtml::_('behavior.multiselect'); +JHtml::_('dropdown.init'); +JHtml::_('formbehavior.chosen', 'select'); + +if ($this->saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_componentbuilder&task=placeholders.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'placeholderList', 'adminForm', strtolower($this->listDirn), $saveOrderingUrl); +} + +?> + +
+sidebar)): ?> +
+ sidebar; ?> +
+
+ +
+ +items)): ?> + loadTemplate('toolbar');?> +
+ +
+ + loadTemplate('toolbar');?> + + loadTemplate('head');?> + loadTemplate('foot');?> + loadTemplate('body');?> +
+ + canCreate && $this->canEdit) : ?> + JText::_('COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + + +
+ + + + \ No newline at end of file diff --git a/admin/views/placeholders/tmpl/default_batch_body.php b/admin/views/placeholders/tmpl/default_batch_body.php new file mode 100644 index 000000000..c99931aaa --- /dev/null +++ b/admin/views/placeholders/tmpl/default_batch_body.php @@ -0,0 +1,18 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> + +

+batchDisplay; ?> \ No newline at end of file diff --git a/admin/views/placeholders/tmpl/default_batch_footer.php b/admin/views/placeholders/tmpl/default_batch_footer.php new file mode 100644 index 000000000..43d4ffea1 --- /dev/null +++ b/admin/views/placeholders/tmpl/default_batch_footer.php @@ -0,0 +1,23 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> + + + + \ No newline at end of file diff --git a/admin/views/placeholders/tmpl/default_body.php b/admin/views/placeholders/tmpl/default_body.php new file mode 100644 index 000000000..cb71e094c --- /dev/null +++ b/admin/views/placeholders/tmpl/default_body.php @@ -0,0 +1,97 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +$edit = "index.php?option=com_componentbuilder&view=placeholders&task=placeholder.edit"; + +?> +items as $i => $item): ?> + user->authorise('core.manage', 'com_checkin') || $item->checked_out == $this->user->id || $item->checked_out == 0; + $userChkOut = JFactory::getUser($item->checked_out); + $canDo = ComponentbuilderHelper::getActions('placeholder',$item,'placeholders'); + ?> + + + get('placeholder.edit.state')): ?> + saveOrder) + { + $iconClass = ' inactive'; + } + else + { + $iconClass = ' inactive tip-top" hasTooltip" title="' . JHtml::tooltipText('JORDERINGDISABLED'); + } + ?> + + + + saveOrder) : ?> + + + + ⋮ + + + + get('placeholder.edit')): ?> + checked_out) : ?> + + id); ?> + + □ + + + id); ?> + + + □ + + + +
+ get('placeholder.edit')): ?> + escape($item->target); ?> + checked_out): ?> + name, $item->checked_out_time, 'placeholders.', $canCheckin); ?> + + + escape($item->target); ?> + +
+ + + escape($item->value); ?> + + + get('placeholder.edit.state')) : ?> + checked_out) : ?> + + published, $i, 'placeholders.', true, 'cb'); ?> + + published, $i, 'placeholders.', false, 'cb'); ?> + + + published, $i, 'placeholders.', true, 'cb'); ?> + + + published, $i, 'placeholders.', false, 'cb'); ?> + + + + id; ?> + + + \ No newline at end of file diff --git a/admin/views/placeholders/tmpl/default_foot.php b/admin/views/placeholders/tmpl/default_foot.php new file mode 100644 index 000000000..db893039b --- /dev/null +++ b/admin/views/placeholders/tmpl/default_foot.php @@ -0,0 +1,18 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> + + pagination->getListFooter(); ?> + \ No newline at end of file diff --git a/admin/views/placeholders/tmpl/default_head.php b/admin/views/placeholders/tmpl/default_head.php new file mode 100644 index 000000000..854979239 --- /dev/null +++ b/admin/views/placeholders/tmpl/default_head.php @@ -0,0 +1,50 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> + + canEdit&& $this->canState): ?> + + ', 'ordering', $this->listDirn, $this->listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?> + + + + + + + ▾ + + + ■ + + + + listDirn, $this->listOrder); ?> + + + listDirn, $this->listOrder); ?> + + canState): ?> + + listDirn, $this->listOrder); ?> + + + + + + + + listDirn, $this->listOrder); ?> + + \ No newline at end of file diff --git a/admin/views/placeholders/tmpl/default_toolbar.php b/admin/views/placeholders/tmpl/default_toolbar.php new file mode 100644 index 000000000..6e9b61a9b --- /dev/null +++ b/admin/views/placeholders/tmpl/default_toolbar.php @@ -0,0 +1,45 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +?> +
+ +
+ + +
+
+ + pagination->getLimitBox(); ?> +
+
+ + +
+
+ + +
+
+
\ No newline at end of file diff --git a/admin/views/placeholders/tmpl/index.html b/admin/views/placeholders/tmpl/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/admin/views/placeholders/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/views/placeholders/view.html.php b/admin/views/placeholders/view.html.php new file mode 100644 index 000000000..72b6f85a0 --- /dev/null +++ b/admin/views/placeholders/view.html.php @@ -0,0 +1,238 @@ + + * @github Joomla Component Builder + * @copyright Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +/** + * Componentbuilder View class for the Placeholders + */ +class ComponentbuilderViewPlaceholders extends JViewLegacy +{ + /** + * Placeholders view display method + * @return void + */ + function display($tpl = null) + { + if ($this->getLayout() !== 'modal') + { + // Include helper submenu + ComponentbuilderHelper::addSubmenu('placeholders'); + } + + // Assign data to the view + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->user = JFactory::getUser(); + $this->listOrder = $this->escape($this->state->get('list.ordering')); + $this->listDirn = $this->escape($this->state->get('list.direction')); + $this->saveOrder = $this->listOrder == 'ordering'; + // set the return here value + $this->return_here = urlencode(base64_encode((string) JUri::getInstance())); + // get global action permissions + $this->canDo = ComponentbuilderHelper::getActions('placeholder'); + $this->canEdit = $this->canDo->get('placeholder.edit'); + $this->canState = $this->canDo->get('placeholder.edit.state'); + $this->canCreate = $this->canDo->get('placeholder.create'); + $this->canDelete = $this->canDo->get('placeholder.delete'); + $this->canBatch = $this->canDo->get('core.batch'); + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + // load the batch html + if ($this->canCreate && $this->canEdit && $this->canState) + { + $this->batchDisplay = JHtmlBatch_::render(); + } + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Display the template + parent::display($tpl); + + // Set the document + $this->setDocument(); + } + + /** + * Setting the toolbar + */ + protected function addToolBar() + { + JToolBarHelper::title(JText::_('COM_COMPONENTBUILDER_PLACEHOLDERS'), 'search'); + JHtmlSidebar::setAction('index.php?option=com_componentbuilder&view=placeholders'); + JFormHelper::addFieldPath(JPATH_COMPONENT . '/models/fields'); + + if ($this->canCreate) + { + JToolBarHelper::addNew('placeholder.add'); + } + + // Only load if there are items + if (ComponentbuilderHelper::checkArray($this->items)) + { + if ($this->canEdit) + { + JToolBarHelper::editList('placeholder.edit'); + } + + if ($this->canState) + { + JToolBarHelper::publishList('placeholders.publish'); + JToolBarHelper::unpublishList('placeholders.unpublish'); + JToolBarHelper::archiveList('placeholders.archive'); + + if ($this->canDo->get('core.admin')) + { + JToolBarHelper::checkin('placeholders.checkin'); + } + } + + // Add a batch button + if ($this->canBatch && $this->canCreate && $this->canEdit && $this->canState) + { + // Get the toolbar object instance + $bar = JToolBar::getInstance('toolbar'); + // set the batch button name + $title = JText::_('JTOOLBAR_BATCH'); + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('joomla.toolbar.batch'); + // add the button to the page + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($this->state->get('filter.published') == -2 && ($this->canState && $this->canDelete)) + { + JToolbarHelper::deleteList('', 'placeholders.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($this->canState && $this->canDelete) + { + JToolbarHelper::trash('placeholders.trash'); + } + + if ($this->canDo->get('core.export') && $this->canDo->get('placeholder.export')) + { + JToolBarHelper::custom('placeholders.exportData', 'download', '', 'COM_COMPONENTBUILDER_EXPORT_DATA', true); + } + } + + if ($this->canDo->get('core.import') && $this->canDo->get('placeholder.import')) + { + JToolBarHelper::custom('placeholders.importData', 'upload', '', 'COM_COMPONENTBUILDER_IMPORT_DATA', false); + } + + // set help url for this view if found + $help_url = ComponentbuilderHelper::getHelpUrl('placeholders'); + if (ComponentbuilderHelper::checkString($help_url)) + { + JToolbarHelper::help('COM_COMPONENTBUILDER_HELP_MANAGER', false, $help_url); + } + + // add the options comp button + if ($this->canDo->get('core.admin') || $this->canDo->get('core.options')) + { + JToolBarHelper::preferences('com_componentbuilder'); + } + + if ($this->canState) + { + JHtmlSidebar::addFilter( + JText::_('JOPTION_SELECT_PUBLISHED'), + 'filter_published', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.published'), true) + ); + // only load if batch allowed + if ($this->canBatch) + { + JHtmlBatch_::addListSelection( + JText::_('COM_COMPONENTBUILDER_KEEP_ORIGINAL_STATE'), + 'batch[published]', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions', array('all' => false)), 'value', 'text', '', true) + ); + } + } + + JHtmlSidebar::addFilter( + JText::_('JOPTION_SELECT_ACCESS'), + 'filter_access', + JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text', $this->state->get('filter.access')) + ); + + if ($this->canBatch && $this->canCreate && $this->canEdit) + { + JHtmlBatch_::addListSelection( + JText::_('COM_COMPONENTBUILDER_KEEP_ORIGINAL_ACCESS'), + 'batch[access]', + JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text') + ); + } + } + + /** + * Method to set up the document properties + * + * @return void + */ + protected function setDocument() + { + if (!isset($this->document)) + { + $this->document = JFactory::getDocument(); + } + $this->document->setTitle(JText::_('COM_COMPONENTBUILDER_PLACEHOLDERS')); + $this->document->addStyleSheet(JURI::root() . "administrator/components/com_componentbuilder/assets/css/placeholders.css", (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); + } + + /** + * Escapes a value for output in a view script. + * + * @param mixed $var The output to escape. + * + * @return mixed The escaped value. + */ + public function escape($var) + { + if(strlen($var) > 50) + { + // use the helper htmlEscape method instead and shorten the string + return ComponentbuilderHelper::htmlEscape($var, $this->_charset, true); + } + // use the helper htmlEscape method instead. + return ComponentbuilderHelper::htmlEscape($var, $this->_charset); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + */ + protected function getSortFields() + { + return array( + 'a.sorting' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.target' => JText::_('COM_COMPONENTBUILDER_PLACEHOLDER_TARGET_LABEL'), + 'a.value' => JText::_('COM_COMPONENTBUILDER_PLACEHOLDER_VALUE_LABEL'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } +} diff --git a/componentbuilder.xml b/componentbuilder.xml index 7c1c0cbea..367da45e0 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,15 +1,15 @@ COM_COMPONENTBUILDER - 12th February, 2019 + 15th February, 2019 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com http://www.joomlacomponentbuilder.com Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt - 2.9.11 + 2.9.13 Component Builder (v.2.9.11) +

Component Builder (v.2.9.13)

The Component Builder for [Joomla](https://extensions.joomla.org/extension/component-builder/) is highly advanced tool that is truly able to build extremely complex components in a fraction of the time. @@ -84,6 +84,7 @@ Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/compo

COM_COMPONENTBUILDER_MENU_LAYOUTS COM_COMPONENTBUILDER_MENU_DYNAMIC_GETS COM_COMPONENTBUILDER_MENU_CUSTOM_CODES + COM_COMPONENTBUILDER_MENU_PLACEHOLDERS COM_COMPONENTBUILDER_MENU_LIBRARIES COM_COMPONENTBUILDER_MENU_SNIPPETS COM_COMPONENTBUILDER_MENU_VALIDATION_RULES diff --git a/componentbuilder_update_server.xml b/componentbuilder_update_server.xml index 872042f9b..e92d17657 100644 --- a/componentbuilder_update_server.xml +++ b/componentbuilder_update_server.xml @@ -594,4 +594,38 @@ http://www.joomlacomponentbuilder.com + + Component Builder + Builds Complex Joomla Components + com_componentbuilder + component + 2.9.12 + http://www.joomlacomponentbuilder.com + + https://github.com/vdm-io/Joomla-Component-Builder/releases/download/v2.9.12/JCB_v2.9.12.zip + + + stable + + Llewellyn van der Merwe + http://www.joomlacomponentbuilder.com + + + + Component Builder + Builds Complex Joomla Components + com_componentbuilder + component + 2.9.13 + http://www.joomlacomponentbuilder.com + + http://domain.com/demo.zip + + + stable + + Llewellyn van der Merwe + http://www.joomlacomponentbuilder.com + + \ No newline at end of file diff --git a/script.php b/script.php index bbc0e6e4a..7dcaa6b61 100644 --- a/script.php +++ b/script.php @@ -730,6 +730,92 @@ class com_componentbuilderInstallerScript } } + // Create a new query object. + $query = $db->getQuery(true); + // Select id from content type table + $query->select($db->quoteName('type_id')); + $query->from($db->quoteName('#__content_types')); + // Where Placeholder alias is found + $query->where( $db->quoteName('type_alias') . ' = '. $db->quote('com_componentbuilder.placeholder') ); + $db->setQuery($query); + // Execute query to see if alias is found + $db->execute(); + $placeholder_found = $db->getNumRows(); + // Now check if there were any rows + if ($placeholder_found) + { + // Since there are load the needed placeholder type ids + $placeholder_ids = $db->loadColumn(); + // Remove Placeholder from the content type table + $placeholder_condition = array( $db->quoteName('type_alias') . ' = '. $db->quote('com_componentbuilder.placeholder') ); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__content_types')); + $query->where($placeholder_condition); + $db->setQuery($query); + // Execute the query to remove Placeholder items + $placeholder_done = $db->execute(); + if ($placeholder_done) + { + // If succesfully remove Placeholder add queued success message. + $app->enqueueMessage(JText::_('The (com_componentbuilder.placeholder) type alias was removed from the #__content_type table')); + } + + // Remove Placeholder items from the contentitem tag map table + $placeholder_condition = array( $db->quoteName('type_alias') . ' = '. $db->quote('com_componentbuilder.placeholder') ); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__contentitem_tag_map')); + $query->where($placeholder_condition); + $db->setQuery($query); + // Execute the query to remove Placeholder items + $placeholder_done = $db->execute(); + if ($placeholder_done) + { + // If succesfully remove Placeholder add queued success message. + $app->enqueueMessage(JText::_('The (com_componentbuilder.placeholder) type alias was removed from the #__contentitem_tag_map table')); + } + + // Remove Placeholder items from the ucm content table + $placeholder_condition = array( $db->quoteName('core_type_alias') . ' = ' . $db->quote('com_componentbuilder.placeholder') ); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__ucm_content')); + $query->where($placeholder_condition); + $db->setQuery($query); + // Execute the query to remove Placeholder items + $placeholder_done = $db->execute(); + if ($placeholder_done) + { + // If succesfully remove Placeholder add queued success message. + $app->enqueueMessage(JText::_('The (com_componentbuilder.placeholder) type alias was removed from the #__ucm_content table')); + } + + // Make sure that all the Placeholder items are cleared from DB + foreach ($placeholder_ids as $placeholder_id) + { + // Remove Placeholder items from the ucm base table + $placeholder_condition = array( $db->quoteName('ucm_type_id') . ' = ' . $placeholder_id); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__ucm_base')); + $query->where($placeholder_condition); + $db->setQuery($query); + // Execute the query to remove Placeholder items + $db->execute(); + + // Remove Placeholder items from the ucm history table + $placeholder_condition = array( $db->quoteName('ucm_type_id') . ' = ' . $placeholder_id); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__ucm_history')); + $query->where($placeholder_condition); + $db->setQuery($query); + // Execute the query to remove Placeholder items + $db->execute(); + } + } + // Create a new query object. $query = $db->getQuery(true); // Select id from content type table @@ -2794,6 +2880,92 @@ class com_componentbuilderInstallerScript } } + // Create a new query object. + $query = $db->getQuery(true); + // Select id from content type table + $query->select($db->quoteName('type_id')); + $query->from($db->quoteName('#__content_types')); + // Where Component_placeholders alias is found + $query->where( $db->quoteName('type_alias') . ' = '. $db->quote('com_componentbuilder.component_placeholders') ); + $db->setQuery($query); + // Execute query to see if alias is found + $db->execute(); + $component_placeholders_found = $db->getNumRows(); + // Now check if there were any rows + if ($component_placeholders_found) + { + // Since there are load the needed component_placeholders type ids + $component_placeholders_ids = $db->loadColumn(); + // Remove Component_placeholders from the content type table + $component_placeholders_condition = array( $db->quoteName('type_alias') . ' = '. $db->quote('com_componentbuilder.component_placeholders') ); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__content_types')); + $query->where($component_placeholders_condition); + $db->setQuery($query); + // Execute the query to remove Component_placeholders items + $component_placeholders_done = $db->execute(); + if ($component_placeholders_done) + { + // If succesfully remove Component_placeholders add queued success message. + $app->enqueueMessage(JText::_('The (com_componentbuilder.component_placeholders) type alias was removed from the #__content_type table')); + } + + // Remove Component_placeholders items from the contentitem tag map table + $component_placeholders_condition = array( $db->quoteName('type_alias') . ' = '. $db->quote('com_componentbuilder.component_placeholders') ); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__contentitem_tag_map')); + $query->where($component_placeholders_condition); + $db->setQuery($query); + // Execute the query to remove Component_placeholders items + $component_placeholders_done = $db->execute(); + if ($component_placeholders_done) + { + // If succesfully remove Component_placeholders add queued success message. + $app->enqueueMessage(JText::_('The (com_componentbuilder.component_placeholders) type alias was removed from the #__contentitem_tag_map table')); + } + + // Remove Component_placeholders items from the ucm content table + $component_placeholders_condition = array( $db->quoteName('core_type_alias') . ' = ' . $db->quote('com_componentbuilder.component_placeholders') ); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__ucm_content')); + $query->where($component_placeholders_condition); + $db->setQuery($query); + // Execute the query to remove Component_placeholders items + $component_placeholders_done = $db->execute(); + if ($component_placeholders_done) + { + // If succesfully remove Component_placeholders add queued success message. + $app->enqueueMessage(JText::_('The (com_componentbuilder.component_placeholders) type alias was removed from the #__ucm_content table')); + } + + // Make sure that all the Component_placeholders items are cleared from DB + foreach ($component_placeholders_ids as $component_placeholders_id) + { + // Remove Component_placeholders items from the ucm base table + $component_placeholders_condition = array( $db->quoteName('ucm_type_id') . ' = ' . $component_placeholders_id); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__ucm_base')); + $query->where($component_placeholders_condition); + $db->setQuery($query); + // Execute the query to remove Component_placeholders items + $db->execute(); + + // Remove Component_placeholders items from the ucm history table + $component_placeholders_condition = array( $db->quoteName('ucm_type_id') . ' = ' . $component_placeholders_id); + // Create a new query object. + $query = $db->getQuery(true); + $query->delete($db->quoteName('#__ucm_history')); + $query->where($component_placeholders_condition); + $db->setQuery($query); + // Execute the query to remove Component_placeholders items + $db->execute(); + } + } + // Create a new query object. $query = $db->getQuery(true); // Select id from content type table @@ -3599,6 +3771,18 @@ class com_componentbuilderInstallerScript // Set the object into the content types table. $custom_code_Inserted = $db->insertObject('#__content_types', $custom_code); + // Create the placeholder content type object. + $placeholder = new stdClass(); + $placeholder->type_title = 'Componentbuilder Placeholder'; + $placeholder->type_alias = 'com_componentbuilder.placeholder'; + $placeholder->table = '{"special": {"dbtable": "#__componentbuilder_placeholder","key": "id","type": "Placeholder","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; + $placeholder->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "target","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "null","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"target":"target","value":"value"}}'; + $placeholder->router = 'ComponentbuilderHelperRoute::getPlaceholderRoute'; + $placeholder->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/placeholder.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"}]}'; + + // Set the object into the content types table. + $placeholder_Inserted = $db->insertObject('#__content_types', $placeholder); + // Create the library content type object. $library = new stdClass(); $library->type_title = 'Componentbuilder Library'; @@ -3887,6 +4071,18 @@ class com_componentbuilderInstallerScript // Set the object into the content types table. $component_files_folders_Inserted = $db->insertObject('#__content_types', $component_files_folders); + // Create the component_placeholders content type object. + $component_placeholders = new stdClass(); + $component_placeholders->type_title = 'Componentbuilder Component_placeholders'; + $component_placeholders->type_alias = 'com_componentbuilder.component_placeholders'; + $component_placeholders->table = '{"special": {"dbtable": "#__componentbuilder_component_placeholders","key": "id","type": "Component_placeholders","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; + $component_placeholders->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "joomla_component","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "null","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"joomla_component":"joomla_component"}}'; + $component_placeholders->router = 'ComponentbuilderHelperRoute::getComponent_placeholdersRoute'; + $component_placeholders->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/component_placeholders.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","joomla_component"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "joomla_component","targetTable": "#__componentbuilder_joomla_component","targetColumn": "id","displayColumn": "system_name"}]}'; + + // Set the object into the content types table. + $component_placeholders_Inserted = $db->insertObject('#__content_types', $component_placeholders); + // Create the snippet_type content type object. $snippet_type = new stdClass(); $snippet_type->type_title = 'Componentbuilder Snippet_type'; @@ -4181,6 +4377,35 @@ class com_componentbuilderInstallerScript $custom_code_Inserted = $db->insertObject('#__content_types', $custom_code); } + // Create the placeholder content type object. + $placeholder = new stdClass(); + $placeholder->type_title = 'Componentbuilder Placeholder'; + $placeholder->type_alias = 'com_componentbuilder.placeholder'; + $placeholder->table = '{"special": {"dbtable": "#__componentbuilder_placeholder","key": "id","type": "Placeholder","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; + $placeholder->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "target","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "null","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"target":"target","value":"value"}}'; + $placeholder->router = 'ComponentbuilderHelperRoute::getPlaceholderRoute'; + $placeholder->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/placeholder.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"}]}'; + + // Check if placeholder type is already in content_type DB. + $placeholder_id = null; + $query = $db->getQuery(true); + $query->select($db->quoteName(array('type_id'))); + $query->from($db->quoteName('#__content_types')); + $query->where($db->quoteName('type_alias') . ' LIKE '. $db->quote($placeholder->type_alias)); + $db->setQuery($query); + $db->execute(); + + // Set the object into the content types table. + if ($db->getNumRows()) + { + $placeholder->type_id = $db->loadResult(); + $placeholder_Updated = $db->updateObject('#__content_types', $placeholder, 'type_id'); + } + else + { + $placeholder_Inserted = $db->insertObject('#__content_types', $placeholder); + } + // Create the library content type object. $library = new stdClass(); $library->type_title = 'Componentbuilder Library'; @@ -4877,6 +5102,35 @@ class com_componentbuilderInstallerScript $component_files_folders_Inserted = $db->insertObject('#__content_types', $component_files_folders); } + // Create the component_placeholders content type object. + $component_placeholders = new stdClass(); + $component_placeholders->type_title = 'Componentbuilder Component_placeholders'; + $component_placeholders->type_alias = 'com_componentbuilder.component_placeholders'; + $component_placeholders->table = '{"special": {"dbtable": "#__componentbuilder_component_placeholders","key": "id","type": "Component_placeholders","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; + $component_placeholders->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "joomla_component","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "null","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"joomla_component":"joomla_component"}}'; + $component_placeholders->router = 'ComponentbuilderHelperRoute::getComponent_placeholdersRoute'; + $component_placeholders->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/component_placeholders.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","joomla_component"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "joomla_component","targetTable": "#__componentbuilder_joomla_component","targetColumn": "id","displayColumn": "system_name"}]}'; + + // Check if component_placeholders type is already in content_type DB. + $component_placeholders_id = null; + $query = $db->getQuery(true); + $query->select($db->quoteName(array('type_id'))); + $query->from($db->quoteName('#__content_types')); + $query->where($db->quoteName('type_alias') . ' LIKE '. $db->quote($component_placeholders->type_alias)); + $db->setQuery($query); + $db->execute(); + + // Set the object into the content types table. + if ($db->getNumRows()) + { + $component_placeholders->type_id = $db->loadResult(); + $component_placeholders_Updated = $db->updateObject('#__content_types', $component_placeholders, 'type_id'); + } + else + { + $component_placeholders_Inserted = $db->insertObject('#__content_types', $component_placeholders); + } + // Create the snippet_type content type object. $snippet_type = new stdClass(); $snippet_type->type_title = 'Componentbuilder Snippet_type'; @@ -5172,7 +5426,7 @@ class com_componentbuilderInstallerScript echo ' -

Upgrade to Version 2.9.11 Was Successful! Let us know if anything is not working as expected.

'; +

Upgrade to Version 2.9.13 Was Successful! Let us know if anything is not working as expected.

'; } } diff --git a/site/helpers/componentbuilder.php b/site/helpers/componentbuilder.php index a2ba3a50c..51bd47f03 100644 --- a/site/helpers/componentbuilder.php +++ b/site/helpers/componentbuilder.php @@ -1179,6 +1179,20 @@ abstract class ComponentbuilderHelper return false; } + /** + * validate that a placeholder is unique + **/ + public static function validateUniquePlaceholder($string) + { + $string = self::safeString($string); + // this list may grow as we find more cases that break the compiler (just open an issue on github) + if (in_array($string, array('component', 'view', 'views'))) + { + return false; + } + return true; + } + /** * The array of dynamic content *