From 37ee9c9b13d11e29fdb9996cf10a0552208e7fa6 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 19 Oct 2011 16:36:09 +0430 Subject: [PATCH 01/40] Add batch processing to com_users --- .../components/com_users/controllers/user.php | 69 ++-- .../com_users/controllers/users.php | 120 ++++--- .../com_users/helpers/html/user.php | 57 ++++ .../components/com_users/models/user.php | 314 +++++++++++------- .../com_users/views/users/tmpl/default.php | 3 + .../views/users/tmpl/default_batch.php | 40 +++ .../language/en-GB/en-GB.com_users.ini | 5 + .../hathor/html/com_users/users/default.php | 3 + 8 files changed, 399 insertions(+), 212 deletions(-) create mode 100644 administrator/components/com_users/helpers/html/user.php create mode 100644 administrator/components/com_users/views/users/tmpl/default_batch.php diff --git a/administrator/components/com_users/controllers/user.php b/administrator/components/com_users/controllers/user.php index 5accd301ab02d..e7e57dea705bf 100644 --- a/administrator/components/com_users/controllers/user.php +++ b/administrator/components/com_users/controllers/user.php @@ -1,10 +1,10 @@ authorise('core.admin')) { + if (!JFactory::getUser()->authorise('core.admin')) + { return false; } } @@ -51,20 +54,46 @@ protected function allowEdit($data = array(), $key = 'id') return parent::allowEdit($data, $key); } + /** + * Method to run batch operations. + * + * @return boolean True on success, false on failure + * + * @since 1.7 + */ + public function batch() + { + JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('User', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_users&view=users'.$this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + /** * Overrides parent save method to check the submitted passwords match. * - * @return mixed Boolean or JError. - * @since 1.6 + * @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 1.6 */ public function save($key = null, $urlVar = null) { $data = JRequest::getVar('jform', array(), 'post', 'array'); // TODO: JForm should really have a validation handler for this. - if (isset($data['password']) && isset($data['password2'])) { + if (isset($data['password']) && isset($data['password2'])) + { // Check the passwords match. - if ($data['password'] != $data['password2']) { + if ($data['password'] != $data['password2']) + { $this->setMessage(JText::_('JLIB_USER_ERROR_PASSWORD_NOT_MATCH'), 'warning'); $this->setRedirect(JRoute::_('index.php?option=com_users&view=user&layout=edit', false)); } diff --git a/administrator/components/com_users/controllers/users.php b/administrator/components/com_users/controllers/users.php index 430a25aabf389..f0532f6c6a551 100644 --- a/administrator/components/com_users/controllers/users.php +++ b/administrator/components/com_users/controllers/users.php @@ -1,8 +1,10 @@ registerTask('block', 'changeBlock'); $this->registerTask('unblock', 'changeBlock'); } + /** * Proxy for getModel. * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + * * @since 1.6 */ public function getModel($name = 'User', $prefix = 'UsersModel', $config = array('ignore_request' => true)) @@ -50,9 +62,11 @@ public function getModel($name = 'User', $prefix = 'UsersModel', $config = array } /** - * Method to remove a record. + * Method to change the block status on a record. * - * @since 1.6 + * @return void + * + * @since 1.6 */ public function changeBlock() { @@ -65,19 +79,28 @@ public function changeBlock() $task = $this->getTask(); $value = JArrayHelper::getValue($values, $task, 0, 'int'); - if (empty($ids)) { + if (empty($ids)) + { JError::raiseWarning(500, JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); - } else { + } + else + { // Get the model. $model = $this->getModel(); // Change the state of the records. - if (!$model->block($ids, $value)) { + if (!$model->block($ids, $value)) + { JError::raiseWarning(500, $model->getError()); - } else { - if ($value == 1){ + } + else + { + if ($value == 1) + { $this->setMessage(JText::plural('COM_USERS_N_USERS_BLOCKED', count($ids))); - } elseif ($value == 0){ + } + elseif ($value == 0) + { $this->setMessage(JText::plural('COM_USERS_N_USERS_UNBLOCKED', count($ids))); } } @@ -87,9 +110,11 @@ public function changeBlock() } /** - * Method to remove a record. + * Method to activate a record. * - * @since 1.6 + * @return void + * + * @since 1.6 */ public function activate() { @@ -99,59 +124,26 @@ public function activate() // Initialise variables. $ids = JRequest::getVar('cid', array(), '', 'array'); - if (empty($ids)) { + if (empty($ids)) + { JError::raiseWarning(500, JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); - } else { + } + else + { // Get the model. $model = $this->getModel(); // Change the state of the records. - if (!$model->activate($ids)) { + if (!$model->activate($ids)) + { JError::raiseWarning(500, $model->getError()); - } else { + } + else + { $this->setMessage(JText::plural('COM_USERS_N_USERS_ACTIVATED', count($ids))); } } $this->setRedirect('index.php?option=com_users&view=users'); } - - /** - * Method to run batch opterations. - * - * @return void - * @since 1.6 - */ - function batch() - { - // Check for request forgeries. - JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Initialise variables. - $app = JFactory::getApplication(); - $model = $this->getModel('User'); - $vars = JRequest::getVar('batch', array(), 'post', 'array'); - $cid = JRequest::getVar('cid', array(), 'post', 'array'); - - // Sanitize user ids. - $cid = array_unique($cid); - JArrayHelper::toInteger($cid); - - // Remove any values of zero. - if (array_search(0, $cid, true)) { - unset($cid[array_search(0, $cid, true)]); - } - - // Attempt to run the batch operation. - if (!$model->batch($vars, $cid)) { - // Batch operation failed, go back to the users list and display a notice. - $message = JText::sprintf('COM_USERS_USER_BATCH_FAILED', $model->getError()); - $this->setRedirect('index.php?option=com_users&view=users', $message, 'error'); - return false; - } - - $message = JText::_('COM_USERS_USER_BATCH_SUCCESS'); - $this->setRedirect('index.php?option=com_users&view=users', $message); - return true; - } } diff --git a/administrator/components/com_users/helpers/html/user.php b/administrator/components/com_users/helpers/html/user.php new file mode 100644 index 0000000000000..09c5156e6d858 --- /dev/null +++ b/administrator/components/com_users/helpers/html/user.php @@ -0,0 +1,57 @@ +getQuery(true); + $query->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level'); + $query->from($db->quoteName('#__usergroups').' AS a'); + $query->join('LEFT', $db->quoteName('#__usergroups').' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); + $query->group('a.id'); + $query->order('a.lft ASC'); + $db->setQuery($query); + $options = $db->loadObjectList(); + + // Check for a database error. + if ($db->getErrorNum()) + { + JError::raiseNotice(500, $db->getErrorMsg()); + return null; + } + + for ($i = 0, $n = count($options); $i < $n; $i++) + { + $options[$i]->text = str_repeat('- ', $options[$i]->level).$options[$i]->text; + $groups[] = JHtml::_('select.option', $options[$i]->value, $options[$i]->text); + } + + return $groups; + } +} diff --git a/administrator/components/com_users/models/user.php b/administrator/components/com_users/models/user.php index 60d43295d9de5..5a57acf0730a6 100644 --- a/administrator/components/com_users/models/user.php +++ b/administrator/components/com_users/models/user.php @@ -1,8 +1,10 @@ loadForm('com_users.user', 'user', array('control' => 'jform', 'load_data' => $loadData)); - if (empty($form)) { + if (empty($form)) + { return false; } @@ -83,15 +90,17 @@ public function getForm($data = array(), $loadData = true) /** * Method to get the data that should be injected in the form. * - * @return mixed The data for the form. - * @since 1.6 + * @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_users.edit.user.data', array()); - if (empty($data)) { + if (empty($data)) + { $data = $this->getItem(); } @@ -104,7 +113,8 @@ protected function loadFormData() $results = $dispatcher->trigger('onContentPrepareData', array('com_users.profile', $data)); // Check for errors encountered while preparing the data. - if (count($results) && in_array(false, $results, true)) { + if (count($results) && in_array(false, $results, true)) + { $this->setError($dispatcher->getError()); } @@ -114,12 +124,14 @@ protected function loadFormData() /** * Override JModelAdmin::preprocessForm to ensure the correct plugin group is loaded. * - * @param object $form A form object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import (defaults to "content"). + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). * - * @throws Exception if there is an error in the form event. - * @since 1.6 + * @return void + * + * @since 1.6 + * @throws Exception if there is an error in the form event. */ protected function preprocessForm(JForm $form, $data, $group = 'user') { @@ -129,10 +141,11 @@ protected function preprocessForm(JForm $form, $data, $group = 'user') /** * Method to save the form data. * - * @param array $data The form data. + * @param array $data The form data. * - * @return boolean True on success. - * @since 1.6 + * @return boolean True on success. + * + * @since 1.6 */ public function save($data) { @@ -142,34 +155,40 @@ public function save($data) $my = JFactory::getUser(); - if ($data['block'] && $pk == $my->id && !$my->block) { + if ($data['block'] && $pk == $my->id && !$my->block) + { $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); return false; } // Make sure that we are not removing ourself from Super Admin group $iAmSuperAdmin = $my->authorise('core.admin'); - if ($iAmSuperAdmin && $my->get('id') == $pk) { + if ($iAmSuperAdmin && $my->get('id') == $pk) + { // Check that at least one of our new groups is Super Admin $stillSuperAdmin = false; $myNewGroups = $data['groups']; - foreach ($myNewGroups as $group) { + foreach ($myNewGroups as $group) + { $stillSuperAdmin = ($stillSuperAdmin) ? ($stillSuperAdmin) : JAccess::checkGroup($group, 'core.admin'); } - if (!$stillSuperAdmin) { + if (!$stillSuperAdmin) + { $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DEMOTE_SELF')); return false; } } // Bind the data. - if (!$user->bind($data)) { + if (!$user->bind($data)) + { $this->setError($user->getError()); return false; } // Store the data. - if (!$user->save()) { + if (!$user->save()) + { $this->setError($user->getError()); return false; } @@ -182,10 +201,11 @@ public function save($data) /** * Method to delete rows. * - * @param array $pks An array of item ids. + * @param array &$pks An array of item ids. * - * @return boolean Returns true on success, false on failure. - * @since 1.6 + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 */ public function delete(&$pks) { @@ -194,14 +214,15 @@ public function delete(&$pks) $table = $this->getTable(); $pks = (array) $pks; - // Check if I am a Super Admin + // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); // Trigger the onUserBeforeSave event. JPluginHelper::importPlugin('user'); $dispatcher = JDispatcher::getInstance(); - if (in_array($user->id, $pks)) { + if (in_array($user->id, $pks)) + { $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DELETE_SELF')); return false; } @@ -209,34 +230,41 @@ public function delete(&$pks) // Iterate the items to delete each one. foreach ($pks as $i => $pk) { - if ($table->load($pk)) { + if ($table->load($pk)) + { // Access checks. $allow = $user->authorise('core.delete', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; - if ($allow) { + if ($allow) + { // Get users data for the users to delete. $user_to_delete = JFactory::getUser($pk); // Fire the onUserBeforeDelete event. $dispatcher->trigger('onUserBeforeDelete', array($table->getProperties())); - if (!$table->delete($pk)) { + if (!$table->delete($pk)) + { $this->setError($table->getError()); return false; - } else { + } + else + { // Trigger the onUserAfterDelete event. $dispatcher->trigger('onUserAfterDelete', array($user_to_delete->getProperties(), true, $this->getError())); } } - else { + else + { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); } } - else { + else + { $this->setError($table->getError()); return false; } @@ -248,11 +276,12 @@ public function delete(&$pks) /** * Method to block user records. * - * @param array $pks The ids of the items to publish. - * @param int $value The value of the published state + * @param array &$pks The ids of the items to publish. + * @param integer $value The value of the published state * - * @return boolean True on success. - * @since 1.6 + * @return boolean True on success. + * + * @since 1.6 */ function block(&$pks, $value = 1) { @@ -260,7 +289,7 @@ function block(&$pks, $value = 1) $app = JFactory::getApplication(); $dispatcher = JDispatcher::getInstance(); $user = JFactory::getUser(); - // Check if I am a Super Admin + // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); $table = $this->getTable(); $pks = (array) $pks; @@ -270,13 +299,15 @@ function block(&$pks, $value = 1) // Access checks. foreach ($pks as $i => $pk) { - if ($value == 1 && $pk == $user->get('id')) { + if ($value == 1 && $pk == $user->get('id')) + { // Cannot block yourself. unset($pks[$i]); JError::raiseWarning(403, JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); } - elseif ($table->load($pk)) { + elseif ($table->load($pk)) + { $old = $table->getProperties(); $allow = $user->authorise('core.edit.state', 'com_users'); // Don't allow non-super-admin to delete a super admin @@ -287,9 +318,11 @@ function block(&$pks, $value = 1) 'clientid' => array(0, 1) ); - if ($allow) { + if ($allow) + { // Skip changing of same state - if ($table->block == $value) { + if ($table->block == $value) + { unset($pks[$i]); continue; } @@ -299,20 +332,23 @@ function block(&$pks, $value = 1) // Allow an exception to be thrown. try { - if (!$table->check()) { + if (!$table->check()) + { $this->setError($table->getError()); return false; } // Trigger the onUserBeforeSave event. $result = $dispatcher->trigger('onUserBeforeSave', array($old, false, $table->getProperties())); - if (in_array(false, $result, true)) { + if (in_array(false, $result, true)) + { // Plugin will have to raise it's own error or throw an exception. return false; } // Store the table. - if (!$table->store()) { + if (!$table->store()) + { $this->setError($table->getError()); return false; } @@ -328,11 +364,13 @@ function block(&$pks, $value = 1) } // Log the user out. - if ($value) { + if ($value) + { $app->logout($table->id, $options); } } - else { + else + { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); @@ -346,17 +384,18 @@ function block(&$pks, $value = 1) /** * Method to activate user records. * - * @param array $pks The ids of the items to activate. + * @param array &$pks The ids of the items to activate. * - * @return boolean True on success. - * @since 1.6 + * @return boolean True on success. + * + * @since 1.6 */ function activate(&$pks) { // Initialise variables. $dispatcher = JDispatcher::getInstance(); $user = JFactory::getUser(); - // Check if I am a Super Admin + // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); $table = $this->getTable(); $pks = (array) $pks; @@ -366,37 +405,43 @@ function activate(&$pks) // Access checks. foreach ($pks as $i => $pk) { - if ($table->load($pk)) { + if ($table->load($pk)) + { $old = $table->getProperties(); $allow = $user->authorise('core.edit.state', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; - if (empty($table->activation)) { + if (empty($table->activation)) + { // Ignore activated accounts. unset($pks[$i]); } - elseif ($allow) { + elseif ($allow) + { $table->block = 0; $table->activation = ''; // Allow an exception to be thrown. try { - if (!$table->check()) { + if (!$table->check()) + { $this->setError($table->getError()); return false; } // Trigger the onUserBeforeSave event. $result = $dispatcher->trigger('onUserBeforeSave', array($old, false, $table->getProperties())); - if (in_array(false, $result, true)) { + if (in_array(false, $result, true)) + { // Plugin will have to raise it's own error or throw an exception. return false; } // Store the table. - if (!$table->store()) { + if (!$table->store()) + { $this->setError($table->getError()); return false; } @@ -411,7 +456,8 @@ function activate(&$pks) return false; } } - else { + else + { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); @@ -425,104 +471,108 @@ function activate(&$pks) /** * Perform batch operations * - * @param array $config An array of variable for the batch operation - * @param array $user_ids An array of IDs on which to operate + * @param array $config An array of variable for the batch operation + * @param array $user_ids An array of IDs on which to operate + * + * @return boolean True on success, false on failure + * * @since 1.6 */ public function batch($config, $user_ids) { // Ensure there are selected users to operate on. - if (empty($user_ids)) { + if (empty($user_ids)) + { $this->setError(JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); - return false; } - elseif (!empty($config)) { + elseif (!empty($config)) + { + // Get the DB object + $db = $this->getDbo(); + // Only run operations if a config array is present. // Ensure there is a valid group. $group_id = JArrayHelper::getValue($config, 'group_id', 0, 'int'); JArrayHelper::toInteger($user_ids); - if ($group_id < 1) { + if ($group_id < 1) + { $this->setError(JText::_('COM_USERS_ERROR_INVALID_GROUP')); - return false; } - // Get the system ACL object and set the mode to database driven. - $acl = JFactory::getACL(); - $oldAclMode = $acl->setCheckMode(1); - - $groupLogic = JArrayHelper::getValue($config, 'group_logic'); - switch ($groupLogic) + $groupAction = JArrayHelper::getValue($config, 'group_action'); + switch ($groupAction) { + // Sets users to a selected group case 'set': - $doDelete = 2; - $doAssign = true; + $doDelete = 'all'; + $doAssign = true; break; + // Remove users from a selected group case 'del': - $doDelete = true; - $doAssign = false; + $doDelete = 'group'; break; + // Add users to a selected group case 'add': default: - $doDelete = false; - $doAssign = true; + $doAssign = true; break; } - // Remove the users from the group(s) if requested. - if ($doDelete) { - // Purge operation, remove the users from all groups. - if ($doDelete === 2) { - $this->_db->setQuery( - 'DELETE FROM '.$this->_db->nameQuote('#__user_usergroup_map') . - ' WHERE '.$this->_db->nameQuote('user_id').' IN ('.implode(',', $user_ids).')' - ); - } - else { - // Remove the users from the group. - $this->_db->setQuery( - 'DELETE FROM '.$this->_db->nameQuote('#__user_usergroup_map') . - ' WHERE '.$this->_db->nameQuote('user_id').' IN ('.implode(',', $user_ids).')' . - ' AND '.$this->_db->nameQuote('group_id').' = '.$group_id - ); + // Remove the users from the group if requested. + if (isset($doDelete)) + { + $query = $db->getQuery(true); + + // Remove users from the group + $query->delete($db->quoteName('#__user_usergroup_map')); + $query->where($db->quoteName('user_id').' IN ('.implode(',', $user_ids).')'); + + // Only remove users from selected group + if ($doDelete == 'group') + { + $query->where($db->quoteName('group_id').' = '.$group_id); } - // Check for database errors. - if (!$this->_db->query()) { - $this->setError($this->_db->getErrorMsg()); + $db->setQuery($query); + // Check for database errors. + if (!$db->query()) + { + $this->setError($db->getErrorMsg()); return false; } } // Assign the users to the group if requested. - if ($doAssign) { - // Build the tuples array for the assignment query. - $tuples = array(); + if (isset($doAssign)) + { + $query = $db->getQuery(true); + + // Build the groups array for the assignment query. + $groups = array(); foreach ($user_ids as $id) { - $tuples[] = '('.$id.','.$group_id.')'; + $groups[] = '('.$id.','.$group_id.')'; } $this->_db->setQuery( 'INSERT INTO '.$this->_db->nameQuote('#__user_usergroup_map').' ('. $this->_db->nameQuote('user_id').', '.$this->_db->nameQuote('group_id').')' . - ' VALUES '.implode(',', $tuples) + ' VALUES '.implode(',', $groups) ); // Check for database errors. - if (!$this->_db->query()) { - $this->setError($this->_db->getErrorMsg()); + if (!$db->query()) + { + $this->setError($db->getErrorMsg()); return false; } } - - // Set the ACL mode back to it's previous state. - $acl->setCheckMode($oldAclMode); } return true; @@ -531,8 +581,9 @@ public function batch($config, $user_ids) /** * Gets the available groups. * - * @return array - * @since 1.6 + * @return array An array of groups + * + * @since 1.6 */ public function getGroups() { @@ -551,22 +602,29 @@ public function getGroups() /** * Gets the groups this object is assigned to * - * @return array - * @since 1.6 + * @param integer $userId The user ID to retrieve the groups for + * + * @return array An array of assigned groups + * + * @since 1.6 */ public function getAssignedGroups($userId = null) { // Initialise variables. $userId = (!empty($userId)) ? $userId : (int)$this->getState('user.id'); - if (empty($userId)) { + if (empty($userId)) + { $result = array(); $config = JComponentHelper::getParams('com_users'); - if ($groupId = $config->get('new_usertype')) { + if ($groupId = $config->get('new_usertype')) + { $result[] = $groupId; } } - else { + else + { + jimport('joomla.user.helper'); $result = JUserHelper::getUserGroups($userId); } diff --git a/administrator/components/com_users/views/users/tmpl/default.php b/administrator/components/com_users/views/users/tmpl/default.php index 0266bfd7ff3fd..ee613f8b3d25c 100755 --- a/administrator/components/com_users/views/users/tmpl/default.php +++ b/administrator/components/com_users/views/users/tmpl/default.php @@ -180,6 +180,9 @@ + + loadTemplate('batch'); ?> +
diff --git a/administrator/components/com_users/views/users/tmpl/default_batch.php b/administrator/components/com_users/views/users/tmpl/default_batch.php new file mode 100644 index 0000000000000..dd05b570dffb5 --- /dev/null +++ b/administrator/components/com_users/views/users/tmpl/default_batch.php @@ -0,0 +1,40 @@ + +
+ + +
+ + +
+ + + +
diff --git a/administrator/language/en-GB/en-GB.com_users.ini b/administrator/language/en-GB/en-GB.com_users.ini index 6ead348984e72..9ed018daff02f 100644 --- a/administrator/language/en-GB/en-GB.com_users.ini +++ b/administrator/language/en-GB/en-GB.com_users.ini @@ -17,6 +17,11 @@ COM_USERS_ACTIONS_AVAILABLE="Actions Permitted" COM_USERS_ACTIVATED="Activated" COM_USERS_ADD_NOTE="Add a note" COM_USERS_ASSIGNED_GROUPS="Assigned User Groups" +COM_USERS_BATCH_ADD="Add To Group" +COM_USERS_BATCH_DELETE="Delete From Group" +COM_USERS_BATCH_GROUP="Select Group" +COM_USERS_BATCH_OPTIONS="Batch process the selected users" +COM_USERS_BATCH_SET="Set To Group" COM_USERS_CATEGORY_HEADING="Category" COM_USERS_CONFIG_FIELD_ALLOWREGISTRATION_DESC="If set to Yes, new Users allowed to self-register." COM_USERS_CONFIG_FIELD_ALLOWREGISTRATION_LABEL="Allow User Registration" diff --git a/administrator/templates/hathor/html/com_users/users/default.php b/administrator/templates/hathor/html/com_users/users/default.php index 7a5c051f21b4f..8defb8f23e46f 100644 --- a/administrator/templates/hathor/html/com_users/users/default.php +++ b/administrator/templates/hathor/html/com_users/users/default.php @@ -182,6 +182,9 @@ + + loadTemplate('batch'); ?> + pagination->getListFooter(); ?> From d2a6aebf32628b6b8066fdc99e0917bd2885a316 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 19 Oct 2011 18:13:57 +0430 Subject: [PATCH 02/40] Add batch access/language to com_modules --- .../com_modules/controllers/module.php | 38 +- .../components/com_modules/models/module.php | 392 ++++++++++++------ .../views/modules/tmpl/default.php | 3 + .../views/modules/tmpl/default_batch.php | 24 ++ .../language/en-GB/en-GB.com_modules.ini | 1 + .../html/com_modules/modules/default.php | 3 + 6 files changed, 329 insertions(+), 132 deletions(-) create mode 100644 administrator/components/com_modules/views/modules/tmpl/default_batch.php diff --git a/administrator/components/com_modules/controllers/module.php b/administrator/components/com_modules/controllers/module.php index e6776702d489d..45a976526e233 100644 --- a/administrator/components/com_modules/controllers/module.php +++ b/administrator/components/com_modules/controllers/module.php @@ -3,8 +3,8 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ // No direct access. @@ -17,7 +17,7 @@ * * @package Joomla.Administrator * @subpackage com_modules - * @version 1.6 + * @since 1.6 */ class ModulesControllerModule extends JControllerForm { @@ -63,7 +63,7 @@ public function add() * * @return boolean True if access level checks pass, false otherwise. * - * @since 11.1 + * @since 1.6 */ public function cancel($key = null) { @@ -81,8 +81,6 @@ public function cancel($key = null) /** * Override parent allowSave method. * - * Extended classes can override this if necessary. - * * @param array $data An array of input data. * @param string $key The name of the key for the primary key. * @@ -93,7 +91,8 @@ public function cancel($key = null) protected function allowSave($data, $key = 'id') { // use custom position if selected - if (empty($data['position'])) { + if (empty($data['position'])) + { $data['position'] = $data['custom_position']; } @@ -102,10 +101,33 @@ protected function allowSave($data, $key = 'id') return parent::allowSave($data, $key); } + /** + * Method to run batch operations. + * + * @param string $model The model + * + * @return boolean True on success. + * + * @since 1.7 + */ + public function batch($model = null) + { + JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Module', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_modules&view=modules'.$this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + /** * Function that allows child controller access to model data after the data has been saved. * - * @param JModel $model The data model object. + * @param JModel &$model The data model object. + * @param array $validData The validated data. * * @return void * diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index a7199f1a29d2c..d974f49f60033 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -1,10 +1,10 @@ getUserState('com_modules.add.module.extension_id')) { + if (!($pk = (int) JRequest::getInt('id'))) + { + if ($extensionId = (int) $app->getUserState('com_modules.add.module.extension_id')) + { $this->setState('extension.id', $extensionId); } } @@ -64,13 +67,76 @@ protected function populateState() $this->setState('params', $params); } + /** + * Method to perform batch operations on a set of modules. + * + * @param array $commands An array of commands to perform. + * @param array $pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.7 + */ + public function batch($commands, $pks) + { + // Sanitize user 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; + + if (!empty($commands['assetgroup_id'])) + { + if (!$this->batchAccess($commands['assetgroup_id'], $pks)) + { + return false; + } + + $done = true; + } + + if (!empty($commands['language_id'])) + { + if (!$this->batchLanguage($commands['language_id'], $pks)) + { + return false; + } + + $done = true; + } + + if (!$done) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + /** * Method to delete rows. * - * @param array $pks An array of item ids. + * @param array &$pks An array of item ids. * - * @return boolean Returns true on success, false on failure. - * @since 1.6 + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 */ public function delete(&$pks) { @@ -82,20 +148,22 @@ public function delete(&$pks) // Iterate the items to delete each one. foreach ($pks as $i => $pk) { - if ($table->load($pk)) { - + if ($table->load($pk)) + { // Access checks. - if (!$user->authorise('core.delete', 'com_modules') || - $table->published != -2) { + if (!$user->authorise('core.delete', 'com_modules') || $table->published != -2) + { JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); // throw new Exception(JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); return; } - if (!$table->delete($pk)) { + if (!$table->delete($pk)) + { throw new Exception($table->getError()); } - else { + else + { // Delete the menu assignments $db = $this->getDbo(); $query = $db->getQuery(true); @@ -109,7 +177,8 @@ public function delete(&$pks) // Clear module cache parent::cleanCache($table->module, $table->client_id); } - else { + else + { throw new Exception($table->getError()); } } @@ -123,11 +192,12 @@ public function delete(&$pks) /** * Method to duplicate modules. * - * @param array $pks An array of primary key IDs. + * @param array &$pks An array of primary key IDs. * - * @return boolean True if successful. - * @since 1.6 - * @throws Exception + * @return boolean True if successful. + * + * @since 1.6 + * @throws Exception */ public function duplicate(&$pks) { @@ -136,7 +206,8 @@ public function duplicate(&$pks) $db = $this->getDbo(); // Access checks. - if (!$user->authorise('core.create', 'com_modules')) { + if (!$user->authorise('core.create', 'com_modules')) + { throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED')); } @@ -144,22 +215,26 @@ public function duplicate(&$pks) foreach ($pks as $pk) { - if ($table->load($pk, true)) { + if ($table->load($pk, true)) + { // Reset the id to create a new record. $table->id = 0; // Alter the title. $m = null; - if (preg_match('#\((\d+)\)$#', $table->title, $m)) { + if (preg_match('#\((\d+)\)$#', $table->title, $m)) + { $table->title = preg_replace('#\(\d+\)$#', '('.($m[1] + 1).')', $table->title); } - else { + else + { $table->title .= ' (2)'; } // Unpublish duplicate module $table->published = 0; - if (!$table->check() || !$table->store()) { + if (!$table->check() || !$table->store()) + { throw new Exception($table->getError()); } @@ -181,18 +256,21 @@ public function duplicate(&$pks) $tuples[] = '('.(int) $table->id.','.(int) $menuid.')'; } } - else { + else + { throw new Exception($table->getError()); } } - if (!empty($tuples)) { + if (!empty($tuples)) + { // Module-Menu Mapping: Do it in one query $query = 'INSERT INTO #__modules_menu (moduleid,menuid) VALUES '.implode(',', $tuples); $this->_db->setQuery($query); - if (!$this->_db->query()) { - return JError::raiseWarning(500, $row->getError()); + if (!$this->_db->query()) + { + return JError::raiseWarning(500, $this->_db->getErrorMsg()); } } @@ -205,8 +283,9 @@ public function duplicate(&$pks) /** * Method to get the client object * - * @return void - * @since 1.6 + * @return void + * + * @since 1.6 */ function &getClient() { @@ -216,21 +295,24 @@ function &getClient() /** * 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 $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. * - * @return JForm A JForm object on success, false on failure - * @since 1.6 + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // The folder and element vars are passed when saving the form. - if (empty($data)) { + if (empty($data)) + { $item = $this->getItem(); $clientId = $item->client_id; $module = $item->module; } - else { + else + { $clientId = JArrayHelper::getValue($data, 'client_id'); $module = JArrayHelper::getValue($data, 'module'); } @@ -241,14 +323,16 @@ public function getForm($data = array(), $loadData = true) // Get the form. $form = $this->loadForm('com_modules.module', 'module', array('control' => 'jform', 'load_data' => $loadData)); - if (empty($form)) { + if (empty($form)) + { return false; } $form->setFieldAttribute('position', 'client', $this->getState('item.client_id') == 0 ? 'site' : 'administrator'); // Modify the form based on access controls. - if (!$this->canEditState((object) $data)) { + if (!$this->canEditState((object) $data)) + { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('published', 'disabled', 'true'); @@ -269,8 +353,9 @@ public function getForm($data = array(), $loadData = true) /** * Method to get the data that should be injected in the form. * - * @return mixed The data for the form. - * @since 1.6 + * @return mixed The data for the form. + * + * @since 1.6 */ protected function loadFormData() { @@ -297,10 +382,11 @@ protected function loadFormData() /** * Method to get a single record. * - * @param integer $pk The id of the primary key. + * @param integer $pk The id of the primary key. * - * @return mixed Object on success, false on failure. - * @since 1.6 + * @return mixed Object on success, false on failure. + * + * @since 1.6 */ public function getItem($pk = null) { @@ -308,7 +394,8 @@ public function getItem($pk = null) $pk = (!empty($pk)) ? (int) $pk : (int) $this->getState('module.id'); $db = $this->getDbo(); - if (!isset($this->_cache[$pk])) { + if (!isset($this->_cache[$pk])) + { $false = false; // Get a row instance. @@ -318,14 +405,17 @@ public function getItem($pk = null) $return = $table->load($pk); // Check for a table object error. - if ($return === false && $error = $table->getError()) { + if ($return === false && $error = $table->getError()) + { $this->setError($error); return $false; } // Check if we are creating a new extension. - if (empty($pk)) { - if ($extensionId = (int) $this->getState('extension.id')) { + if (empty($pk)) + { + if ($extensionId = (int) $this->getState('extension.id')) + { $query = $db->getQuery(true); $query->select('element, client_id'); $query->from('#__extensions'); @@ -334,11 +424,14 @@ public function getItem($pk = null) $db->setQuery($query); $extension = $db->loadObject(); - if (empty($extension)) { - if ($error = $db->getErrorMsg()) { + if (empty($extension)) + { + if ($error = $db->getErrorMsg()) + { $this->setError($error); } - else { + else + { $this->setError('COM_MODULES_ERROR_CANNOT_FIND_MODULE'); } return false; @@ -348,9 +441,10 @@ public function getItem($pk = null) $table->module = $extension->element; $table->client_id = $extension->client_id; } - else { + else + { $app = JFactory::getApplication(); - $app->redirect(JRoute::_('index.php?option=com_modules&view=modules',false)); + $app->redirect(JRoute::_('index.php?option=com_modules&view=modules', false)); return false; } } @@ -372,22 +466,28 @@ public function getItem($pk = null) ); $assigned = $db->loadResultArray(); - if (empty($pk)) { + if (empty($pk)) + { // If this is a new module, assign to all pages. $assignment = 0; } - elseif (empty($assigned)) { + elseif (empty($assigned)) + { // For an existing module it is assigned to none. $assignment = '-'; } - else { - if ($assigned[0] > 0) { + else + { + if ($assigned[0] > 0) + { $assignment = +1; } - elseif ($assigned[0] < 0) { + elseif ($assigned[0] < 0) + { $assignment = -1; } - else { + else + { $assignment = 0; } } @@ -399,10 +499,12 @@ public function getItem($pk = null) $client = JApplicationHelper::getClientInfo($table->client_id); $path = JPath::clean($client->path.'/modules/'.$table->module.'/'.$table->module.'.xml'); - if (file_exists($path)) { + if (file_exists($path)) + { $this->_cache[$pk]->xml = simplexml_load_file($path); } - else { + else + { $this->_cache[$pk]->xml = null; } } @@ -413,8 +515,9 @@ public function getItem($pk = null) /** * Get the necessary data to load an item help screen. * - * @return object An object with key, url, and local properties for loading the item help screen. - * @since 1.6 + * @return object An object with key, url, and local properties for loading the item help screen. + * + * @since 1.6 */ public function getHelp() { @@ -424,12 +527,13 @@ public function getHelp() /** * Returns a reference to the a Table object, always creating it. * - * @param type The table type to instantiate - * @param string A prefix for the table class name. Optional. - * @param array Configuration array for model. Optional. + * @param string $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 + * @return JTable A database object + * + * @since 1.6 */ public function getTable($type = 'Module', $prefix = 'JTable', $config = array()) { @@ -439,8 +543,11 @@ public function getTable($type = 'Module', $prefix = 'JTable', $config = array() /** * Prepare and sanitise the table prior to saving. * - * @return void - * @since 1.6 + * @param JTable &$table The database object + * + * @return void + * + * @since 1.6 */ protected function prepareTable(&$table) { @@ -450,11 +557,13 @@ protected function prepareTable(&$table) $table->title = htmlspecialchars_decode($table->title, ENT_QUOTES); - if (empty($table->id)) { + if (empty($table->id)) + { // Set the values //$table->created = $date->toMySQL(); } - else { + else + { // Set the values //$table->modified = $date->toMySQL(); //$table->modified_by = $user->get('id'); @@ -462,12 +571,16 @@ protected function prepareTable(&$table) } /** - * @param object A form object. - * @param mixed The data expected for the form. + * Method to preprocess the form * - * @return void - * @throws Exception if there is an error loading the form. - * @since 1.6 + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error loading the form. */ protected function preprocessForm(JForm $form, $data, $group = '') { @@ -488,20 +601,24 @@ protected function preprocessForm(JForm $form, $data, $group = '') || $lang->load($module, $client->path, $lang->getDefault(), false, false) || $lang->load($module, $client->path.'/modules/'.$module, $lang->getDefault(), false, false); - if (file_exists($formFile)) { + if (file_exists($formFile)) + { // Get the module form. - if (!$form->loadFile($formFile, false, '//config')) { + if (!$form->loadFile($formFile, false, '//config')) + { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } // Attempt to load the xml file. - if (!$xml = simplexml_load_file($formFile)) { + if (!$xml = simplexml_load_file($formFile)) + { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } // Get the help data from the XML file if present. $help = $xml->xpath('/extension/help'); - if (!empty($help)) { + if (!empty($help)) + { $helpKey = trim((string) $help[0]['key']); $helpURL = trim((string) $help[0]['url']); @@ -518,14 +635,16 @@ protected function preprocessForm(JForm $form, $data, $group = '') /** * Loads ContentHelper for filters before validating data. * - * @param object $form The form to validate against. - * @param array $data The data to validate. - * @return mixed Array of filtered data if valid, false otherwise. - * @since 1.1 + * @param object $form The form to validate against. + * @param array $data The data to validate. + * + * @return mixed Array of filtered data if valid, false otherwise. + * + * @since 1.1 */ function validate($form, $data, $group = null) { - require_once(JPATH_ADMINISTRATOR.'/components/com_content/helpers/content.php'); + require_once JPATH_ADMINISTRATOR.'/components/com_content/helpers/content.php'; return parent::validate($form, $data, $group); } @@ -533,10 +652,11 @@ function validate($form, $data, $group = null) /** * Method to save the form data. * - * @param array $data The form data. + * @param array $data The form data. * - * @return boolean True on success. - * @since 1.6 + * @return boolean True on success. + * + * @since 1.6 */ public function save($data) { @@ -550,25 +670,29 @@ public function save($data) JPluginHelper::importPlugin('extension'); // Load the row if saving an existing record. - if ($pk > 0) { + if ($pk > 0) + { $table->load($pk); $isNew = false; } // Alter the title and published state for Save as Copy - if (JRequest::getVar('task') == 'save2copy') { + if (JRequest::getVar('task') == 'save2copy') + { $orig_data = JRequest::getVar('jform', array(), 'post', 'array'); $orig_table = clone($this->getTable()); - $orig_table->load( (int) $orig_data['id']); + $orig_table->load((int) $orig_data['id']); - if ($data['title'] == $orig_table->title) { + if ($data['title'] == $orig_table->title) + { $data['title'] .= ' '.JText::_('JGLOBAL_COPY'); $data['published'] = 0; } } // Bind the data. - if (!$table->bind($data)) { + if (!$table->bind($data)) + { $this->setError($table->getError()); return false; } @@ -577,21 +701,23 @@ public function save($data) $this->prepareTable($table); // Check the data. - if (!$table->check()) { + if (!$table->check()) + { $this->setError($table->getError()); return false; } - // Trigger the onExtensionBeforeSave event. $result = $dispatcher->trigger('onExtensionBeforeSave', array('com_modules.module', &$table, $isNew)); - if (in_array(false, $result, true)) { + if (in_array(false, $result, true)) + { $this->setError($table->getError()); return false; } // Store the data. - if (!$table->store()) { + if (!$table->store()) + { $this->setError($table->getError()); return false; } @@ -616,41 +742,54 @@ public function save($data) $db->setQuery((string)$query); $db->query(); - if (!$db->query()) { + if (!$db->query()) + { $this->setError($db->getErrorMsg()); return false; } // If the assignment is numeric, then something is selected (otherwise it's none). - if (is_numeric($assignment)) { + if (is_numeric($assignment)) + { // Variable is numeric, but could be a string. $assignment = (int) $assignment; // Logic check: if no module excluded then convert to display on all. - if ($assignment == -1 && empty($data['assigned'])){ + if ($assignment == -1 && empty($data['assigned'])) + { $assignment = 0; } // Check needed to stop a module being assigned to `All` // and other menu items resulting in a module being displayed twice. - if ($assignment === 0) { + if ($assignment === 0) + { + // assign new module to `all` menu item associations + // $this->_db->setQuery( + // 'INSERT INTO #__modules_menu'. + // ' SET moduleid = '.(int) $table->id.', menuid = 0' + // ); + $query->clear(); - $query->insert('#__modules_menu'); - $query->columns(array($db->quoteName('moduleid'), $db->quoteName('menuid'))); + $query->insert('#__modules_menu'); + $query->columns(array($db->quoteName('moduleid'), $db->quoteName('menuid'))); $query->values((int)$table->id . ', 0'); $db->setQuery((string)$query); - if (!$db->query()) { + if (!$db->query()) + { $this->setError($db->getErrorMsg()); return false; } } - elseif (!empty($data['assigned'])) { + elseif (!empty($data['assigned'])) + { // Get the sign of the number. $sign = $assignment < 0 ? -1 : +1; // Preprocess the assigned array. $tuples = array(); - foreach ($data['assigned'] as &$pk) { + foreach ($data['assigned'] as &$pk) + { $tuples[] = '('.(int) $table->id.','.(int) $pk * $sign.')'; } @@ -659,7 +798,8 @@ public function save($data) implode(',', $tuples) ); - if (!$db->query()) { + if (!$db->query()) + { $this->setError($db->getErrorMsg()); return false; } @@ -679,7 +819,8 @@ public function save($data) $extensionId = $db->loadResult(); - if ($error = $db->getErrorMsg()) { + if ($error = $db->getErrorMsg()) + { JError::raiseWarning(500, $error); return; } @@ -699,10 +840,11 @@ public function save($data) /** * A protected method to get a set of ordering conditions. * - * @param object $table A record object. + * @param object $table A record object. * - * @return array An array of conditions to add to add to ordering queries. - * @since 1.6 + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 */ protected function getReorderConditions($table) { @@ -716,6 +858,8 @@ protected function getReorderConditions($table) /** * Custom clean cache method for different clients * + * @return void + * * @since 1.6 */ protected function cleanCache($group = null, $client_id = 0) diff --git a/administrator/components/com_modules/views/modules/tmpl/default.php b/administrator/components/com_modules/views/modules/tmpl/default.php index 26d4adee65b7a..307bd76a4f245 100644 --- a/administrator/components/com_modules/views/modules/tmpl/default.php +++ b/administrator/components/com_modules/views/modules/tmpl/default.php @@ -192,6 +192,9 @@ + + loadTemplate('batch'); ?> +
diff --git a/administrator/components/com_modules/views/modules/tmpl/default_batch.php b/administrator/components/com_modules/views/modules/tmpl/default_batch.php new file mode 100644 index 0000000000000..38dff5d4a33f5 --- /dev/null +++ b/administrator/components/com_modules/views/modules/tmpl/default_batch.php @@ -0,0 +1,24 @@ + +
+ + + + + + +
diff --git a/administrator/language/en-GB/en-GB.com_modules.ini b/administrator/language/en-GB/en-GB.com_modules.ini index eb3a02351af5d..397f6466f5f3c 100644 --- a/administrator/language/en-GB/en-GB.com_modules.ini +++ b/administrator/language/en-GB/en-GB.com_modules.ini @@ -9,6 +9,7 @@ COM_MODULES_ADVANCED_FIELDSET_LABEL="Advanced Options" COM_MODULES_ASSIGNED_VARIES_EXCEPT="All except selected" COM_MODULES_ASSIGNED_VARIES_ONLY="Selected only" COM_MODULES_BASIC_FIELDSET_LABEL="Basic Options" +COM_MODULES_BATCH_OPTIONS="Batch process the selected modules" COM_MODULES_CHANGE_POSITION_BUTTON="Select position" COM_MODULES_CHANGE_POSITION_TITLE="Change position" COM_MODULES_CONFIGURATION="Module Manager Options" diff --git a/administrator/templates/hathor/html/com_modules/modules/default.php b/administrator/templates/hathor/html/com_modules/modules/default.php index 37521b4b354ec..856713567e259 100644 --- a/administrator/templates/hathor/html/com_modules/modules/default.php +++ b/administrator/templates/hathor/html/com_modules/modules/default.php @@ -204,6 +204,9 @@ + + loadTemplate('batch'); ?> + pagination->getListFooter(); ?> From e99205fbeeef4e49f3df278bc42b92d51390c4e7 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 21 Oct 2011 18:16:00 +0430 Subject: [PATCH 03/40] Review batch permission checks In the controller batch method, build an array of contexts for each item that is being edited and pass it to the model; the model forwards this array to each method where permissions are checked on the context versus the extension root. Applied concept to batchAccess and batchLanguage, but error reporting needs to be handled now. --- .../application/component/controllerform.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libraries/joomla/application/component/controllerform.php b/libraries/joomla/application/component/controllerform.php index 67be43b642c1c..674c0f47dd3fe 100644 --- a/libraries/joomla/application/component/controllerform.php +++ b/libraries/joomla/application/component/controllerform.php @@ -272,6 +272,22 @@ public function batch($model) $contexts[$id] = $option . '.' . $this->context . '.' . $id; } + // Build an array of item contexts to check + $contexts = array(); + foreach ($cid as $id) + { + // If we're coming from com_categories, we need to use extension vs. option + if (isset($this->extension)) + { + $option = $this->extension; + } + else + { + $option = $this->option; + } + $contexts[$id] = $option.'.'.$this->context.'.'.$id; + } + // Attempt to run the batch operation. if ($model->batch($vars, $cid, $contexts)) { From 4543a2327e778edc8c2b2f438ec45b3ae4e71f27 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 14 Nov 2011 17:37:10 +0430 Subject: [PATCH 04/40] Batch processing in com_banners banners view Added language and category widgets from library and created a widget to batch edit the client --- .../com_banners/controllers/banner.php | 83 ++++-- .../com_banners/helpers/html/banner.php | 72 +++++ .../com_banners/helpers/html/index.html | 1 + .../components/com_banners/models/banner.php | 266 ++++++++++++++---- .../views/banners/tmpl/default.php | 13 +- .../views/banners/tmpl/default_batch.php | 31 ++ .../com_banners/views/banners/view.html.php | 75 +++-- .../language/en-GB/en-GB.com_banners.ini | 5 + .../html/com_banners/banners/default.php | 4 + 9 files changed, 442 insertions(+), 108 deletions(-) create mode 100644 administrator/components/com_banners/helpers/html/banner.php create mode 100644 administrator/components/com_banners/helpers/html/index.html create mode 100644 administrator/components/com_banners/views/banners/tmpl/default_batch.php diff --git a/administrator/components/com_banners/controllers/banner.php b/administrator/components/com_banners/controllers/banner.php index 88c3e1f2db603..8279164223551 100644 --- a/administrator/components/com_banners/controllers/banner.php +++ b/administrator/components/com_banners/controllers/banner.php @@ -1,8 +1,10 @@ authorise('core.create', $this->option.'.category.'.$categoryId); + $allow = $user->authorise('core.create', $this->option . '.category.' . $categoryId); } - if ($allow === null) { - // In the absense of better information, revert to the component permissions. + if ($allow === null) + { + // In the absence of better information, revert to the component permissions. return parent::allowAdd($data); - } else { + } + else + { return $allow; } } @@ -56,11 +63,12 @@ protected function allowAdd($data = array()) /** * 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. + * @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 + * @return boolean + * + * @since 1.6 */ protected function allowEdit($data = array(), $key = 'id') { @@ -69,16 +77,43 @@ protected function allowEdit($data = array(), $key = 'id') $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $categoryId = 0; - if ($recordId) { + if ($recordId) + { $categoryId = (int) $this->getModel()->getItem($recordId)->catid; } - if ($categoryId) { + if ($categoryId) + { // The category has been set. Check the category permissions. - return $user->authorise('core.edit', $this->option.'.category.'.$categoryId); - } else { + return $user->authorise('core.edit', $this->option . '.category.' . $categoryId); + } + else + { // Since there is no asset tracking, revert to the component permissions. return parent::allowEdit($data, $key); } } + + /** + * Method to run batch operations. + * + * @param string $model The model + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function batch($model = null) + { + JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Banner', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_banners&view=banners' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + } diff --git a/administrator/components/com_banners/helpers/html/banner.php b/administrator/components/com_banners/helpers/html/banner.php new file mode 100644 index 0000000000000..7d6498d67def4 --- /dev/null +++ b/administrator/components/com_banners/helpers/html/banner.php @@ -0,0 +1,72 @@ +', + JText::_('COM_BANNERS_BATCH_CLIENT_LABEL'), + '', + '' + ); + + return implode("\n", $lines); + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * @since 1.6 + */ + public static function clientlist() + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('id As value, name As text'); + $query->from('#__banner_clients AS a'); + $query->order('a.name'); + + // Get the options. + $db->setQuery($query); + + $options = $db->loadObjectList(); + + // Check for a database error. + if ($db->getErrorNum()) { + JError::raiseWarning(500, $db->getErrorMsg()); + } + + return $options; + } +} diff --git a/administrator/components/com_banners/helpers/html/index.html b/administrator/components/com_banners/helpers/html/index.html new file mode 100644 index 0000000000000..2efb97f319a35 --- /dev/null +++ b/administrator/components/com_banners/helpers/html/index.html @@ -0,0 +1 @@ + diff --git a/administrator/components/com_banners/models/banner.php b/administrator/components/com_banners/models/banner.php index 2d8b525a67a9e..a5dd5b4fe51cb 100644 --- a/administrator/components/com_banners/models/banner.php +++ b/administrator/components/com_banners/models/banner.php @@ -1,8 +1,10 @@ setError(JText::_('JGLOBAL_NO_ITEM_SELECTED')); + return false; + } + + $done = false; + + if (!empty($commands['category_id'])) + { + $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); + + if ($cmd == 'c') + { + $result = $this->batchCopy($commands['category_id'], $pks, $contexts); + if (is_array($result)) + { + $pks = $result; + } + else + { + return false; + } + } + elseif ($cmd == 'm' && !$this->batchMove($commands['category_id'], $pks, $contexts)) + { + return false; + } + $done = true; + } + + if (strlen($commands['client_id']) > 0) + { + if (!$this->batchClient($commands['client_id'], $pks, $contexts)) + { + return false; + } + + $done = true; + } + + if (!empty($commands['language_id'])) + { + if (!$this->batchLanguage($commands['language_id'], $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 language changes for a group of rows. + * + * @param string $value The new value matching a language. + * @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 2.5 + */ + protected function batchClient($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $table = $this->getTable(); + + foreach ($pks as $pk) + { + //TODO: Handle error reporting if user is not authorised + if ($user->authorise('core.edit', $contexts[$pk])) + { + $table->reset(); + $table->load($pk); + $table->cid = (int) $value; + + if (!$table->store()) + { + $this->setError($table->getError()); + return false; + } + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + /** * Method to test whether a record can be deleted. * - * @param object A record object. - * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. - * @since 1.6 + * @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->state != -2) { - return ; + if (!empty($record->id)) + { + if ($record->state != -2) + { + return; } $user = JFactory::getUser(); - if (!empty($record->catid)) { - return $user->authorise('core.delete', 'com_banners.category.'.(int) $record->catid); + if (!empty($record->catid)) + { + return $user->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); } - else { + else + { return parent::canDelete($record); } } @@ -52,32 +186,38 @@ protected function canDelete($record) /** * Method to test whether a record can have its state changed. * - * @param object 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 + * @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(); // Check against the category. - if (!empty($record->catid)) { - return $user->authorise('core.edit.state', 'com_banners.category.'.(int) $record->catid); + if (!empty($record->catid)) + { + return $user->authorise('core.edit.state', 'com_banners.category.' . (int) $record->catid); } // Default to component settings if category not known. - else { + else + { return parent::canEditState($record); } } /** - * Returns a reference to the a Table object, always creating it. + * Returns a JTable object, always creating it. + * + * @param string $type The table type to instantiate. [optional] + * @param string $prefix A prefix for the table class name. [optional] + * @param array $config Configuration array for model. [optional] + * + * @return JTable A database object * - * @param type The table type to instantiate - * @param string A prefix for the table class name. Optional. - * @param array Configuration array for model. Optional. - * @return JTable A database object - * @since 1.6 + * @since 1.6 */ public function getTable($type = 'Banner', $prefix = 'BannersTable', $config = array()) { @@ -87,30 +227,37 @@ public function getTable($type = 'Banner', $prefix = 'BannersTable', $config = a /** * 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. - * @return mixed A JForm object on success, false on failure - * @since 1.6 + * @param array $data Data for the form. [optional] + * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] + * + * @return mixed A JForm object on success, false on failure + * + * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_banners.banner', 'banner', array('control' => 'jform', 'load_data' => $loadData)); - if (empty($form)) { + if (empty($form)) + { return false; } // Determine correct permissions to check. - if ($this->getState('banner.id')) { + if ($this->getState('banner.id')) + { // Existing record. Can only edit in selected categories. $form->setFieldAttribute('catid', 'action', 'core.edit'); - } else { + } + else + { // New record. Can only create in selected categories. $form->setFieldAttribute('catid', 'action', 'core.create'); } // Modify the form based on access controls. - if (!$this->canEditState((object) $data)) { + if (!$this->canEditState((object) $data)) + { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('publish_up', 'disabled', 'true'); @@ -133,19 +280,22 @@ public function getForm($data = array(), $loadData = true) /** * Method to get the data that should be injected in the form. * - * @return mixed The data for the form. - * @since 1.6 + * @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_banners.edit.banner.data', array()); - if (empty($data)) { + if (empty($data)) + { $data = $this->getItem(); // Prime some default values. - if ($this->getState('banner.id') == 0) { + if ($this->getState('banner.id') == 0) + { $app = JFactory::getApplication(); $data->set('catid', JRequest::getInt('catid', $app->getUserState('com_banners.banners.filter.category_id'))); } @@ -157,22 +307,27 @@ protected function loadFormData() /** * Method to stick records. * - * @param array The ids of the items to publish. - * @param int The value of the published state + * @param array &$pks The ids of the items to publish. + * @param integer $value The value of the published state * - * @return boolean True on success. + * @return boolean True on success. + * + * @since 1.6 */ function stick(&$pks, $value = 1) { // Initialise variables. - $user = JFactory::getUser(); - $table = $this->getTable(); - $pks = (array) $pks; + $user = JFactory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; // Access checks. - foreach ($pks as $i => $pk) { - if ($table->load($pk)) { - if (!$this->canEditState($table)) { + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if (!$this->canEditState($table)) + { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); @@ -181,7 +336,8 @@ function stick(&$pks, $value = 1) } // Attempt to change the state of the records. - if (!$table->stick($pks, $value, $user->get('id'))) { + if (!$table->stick($pks, $value, $user->get('id'))) + { $this->setError($table->getError()); return false; } @@ -192,9 +348,11 @@ function stick(&$pks, $value = 1) /** * A protected method to get a set of ordering conditions. * - * @param object A record object. - * @return array An array of conditions to add to add to ordering queries. - * @since 1.6 + * @param JTable $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 */ protected function getReorderConditions($table) { diff --git a/administrator/components/com_banners/views/banners/tmpl/default.php b/administrator/components/com_banners/views/banners/tmpl/default.php index 8a8a2e594fb3b..bcc2dd91893e2 100644 --- a/administrator/components/com_banners/views/banners/tmpl/default.php +++ b/administrator/components/com_banners/views/banners/tmpl/default.php @@ -1,10 +1,10 @@ + + loadTemplate('batch'); ?> +
diff --git a/administrator/components/com_banners/views/banners/tmpl/default_batch.php b/administrator/components/com_banners/views/banners/tmpl/default_batch.php new file mode 100644 index 0000000000000..0d29e0e1682e1 --- /dev/null +++ b/administrator/components/com_banners/views/banners/tmpl/default_batch.php @@ -0,0 +1,31 @@ +state->get('filter.published'); +?> +
+ +

+ + + + = 0) : ?> + + + + + +
diff --git a/administrator/components/com_banners/views/banners/view.html.php b/administrator/components/com_banners/views/banners/view.html.php index c7b5e90f1ed09..a183d4b84e934 100644 --- a/administrator/components/com_banners/views/banners/view.html.php +++ b/administrator/components/com_banners/views/banners/view.html.php @@ -1,8 +1,10 @@ state = $this->get('State'); // Check for errors. - if (count($errors = $this->get('Errors'))) { + if (count($errors = $this->get('Errors'))) + { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); - require_once JPATH_COMPONENT .'/models/fields/bannerclient.php'; + require_once JPATH_COMPONENT . '/models/fields/bannerclient.php'; + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + parent::display($tpl); } /** * Add the page title and toolbar. * - * @since 1.6 + * @return void + * + * @since 1.6 */ protected function addToolbar() { - require_once JPATH_COMPONENT.'/helpers/banners.php'; + require_once JPATH_COMPONENT . '/helpers/banners.php'; - $canDo = BannersHelper::getActions($this->state->get('filter.category_id')); - $user = JFactory::getUser(); + $canDo = BannersHelper::getActions($this->state->get('filter.category_id')); + $user = JFactory::getUser(); JToolBarHelper::title(JText::_('COM_BANNERS_MANAGER_BANNERS'), 'banners.png'); - if (count($user->getAuthorisedCategories('com_banners', 'core.create')) > 0) { + if (count($user->getAuthorisedCategories('com_banners', 'core.create')) > 0) + { JToolBarHelper::addNew('banner.add'); } - if (($canDo->get('core.edit'))) { + if (($canDo->get('core.edit'))) + { JToolBarHelper::editList('banner.edit'); } - if ($canDo->get('core.edit.state')) { - if ($this->state->get('filter.state') != 2){ + if ($canDo->get('core.edit.state')) + { + if ($this->state->get('filter.state') != 2) + { JToolBarHelper::divider(); JToolBarHelper::publish('banners.publish', 'JTOOLBAR_PUBLISH', true); JToolBarHelper::unpublish('banners.unpublish', 'JTOOLBAR_UNPUBLISH', true); } - if ($this->state->get('filter.state') != -1 ) { + if ($this->state->get('filter.state') != -1) + { JToolBarHelper::divider(); - if ($this->state->get('filter.state') != 2) { + if ($this->state->get('filter.state') != 2) + { JToolBarHelper::archiveList('banners.archive'); } - elseif ($this->state->get('filter.state') == 2) { + elseif ($this->state->get('filter.state') == 2) + { JToolBarHelper::unarchiveList('banners.publish'); } } } - if ($canDo->get('core.edit.state')) { + if ($canDo->get('core.edit.state')) + { JToolBarHelper::checkin('banners.checkin'); } - - if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) { + if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) + { JToolBarHelper::deleteList('', 'banners.delete', 'JTOOLBAR_EMPTY_TRASH'); JToolBarHelper::divider(); - } elseif ($canDo->get('core.edit.state')) { + } + elseif ($canDo->get('core.edit.state')) + { JToolBarHelper::trash('banners.trash'); JToolBarHelper::divider(); } - if ($canDo->get('core.admin')) { + if ($canDo->get('core.admin')) + { JToolBarHelper::preferences('com_banners'); JToolBarHelper::divider(); } diff --git a/administrator/language/en-GB/en-GB.com_banners.ini b/administrator/language/en-GB/en-GB.com_banners.ini index 58fe221de4fee..21c4b095c3107 100644 --- a/administrator/language/en-GB/en-GB.com_banners.ini +++ b/administrator/language/en-GB/en-GB.com_banners.ini @@ -21,6 +21,11 @@ COM_BANNERS_BANNERS_N_ITEMS_TRASHED_1="%d banner successfully trashed" COM_BANNERS_BANNERS_N_ITEMS_UNPUBLISHED="%d banners successfully unpublished" COM_BANNERS_BANNERS_N_ITEMS_UNPUBLISHED_1="%d banner successfully unpublished" COM_BANNERS_BANNERS_NO_ITEM_SELECTED="No Banners selected" +COM_BANNERS_BATCH_CLIENT_LABEL="Set Client" +COM_BANNERS_BATCH_CLIENT_LABEL_DESC="Not making a selection will keep the original client when processing." +COM_BANNERS_BATCH_CLIENT_NOCHANGE="- Keep original Client -" +COM_BANNERS_BATCH_OPTIONS="Batch process the selected banners" +COM_BANNERS_BATCH_TIP="If choosing to copy a banner, any other actions selected will be applied to the copied banner. Otherwise, all actions are applied to the selected banner." COM_BANNERS_BEGIN_LABEL="Begin date:" COM_BANNERS_CANCEL="Cancel" COM_BANNERS_CLICK="Click" diff --git a/administrator/templates/hathor/html/com_banners/banners/default.php b/administrator/templates/hathor/html/com_banners/banners/default.php index 3cea04d7456d8..b606cc2e8cf26 100644 --- a/administrator/templates/hathor/html/com_banners/banners/default.php +++ b/administrator/templates/hathor/html/com_banners/banners/default.php @@ -207,6 +207,10 @@ pagination->getListFooter(); ?> +
+ + + loadTemplate('batch'); ?> From 9cbac74dbe45711a04538ef96688f471b199d6f2 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 23 Nov 2011 12:16:07 +0430 Subject: [PATCH 05/40] Fix generateNewTitle declarations --- .../components/com_categories/models/category.php | 9 +++++---- administrator/components/com_menus/models/item.php | 10 ++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/administrator/components/com_categories/models/category.php b/administrator/components/com_categories/models/category.php index 7ed6206d006a5..b43e0a8a9bccc 100644 --- a/administrator/components/com_categories/models/category.php +++ b/administrator/components/com_categories/models/category.php @@ -800,11 +800,12 @@ protected function cleanCache($group = null, $client_id = 0) /** * Method to change the title & alias. * - * @param int The value of the parent category ID. - * @param string The value of the category alias. - * @param string The value of the category title. + * @param integer $parent_id The id of the parent. + * @param string $alias The alias. + * @param string $title The title. + * + * @return array Contains the modified title and alias. * - * @return array Contains title and alias. * @since 1.7 */ protected function generateNewTitle($parent_id, $alias, $title) diff --git a/administrator/components/com_menus/models/item.php b/administrator/components/com_menus/models/item.php index 5dd7950a801de..685d8b2522b9b 100644 --- a/administrator/components/com_menus/models/item.php +++ b/administrator/components/com_menus/models/item.php @@ -1315,10 +1315,12 @@ function publish(&$pks, $value = 1) /** * Method to change the title & alias. * - * @param int The value of the menu Parent Id. - * @param string The value of the menu Alias. - * @param string The value of the menu Title. - * @return array Contains title and alias. + * @param integer $parent_id The id of the parent. + * @param string $alias The alias. + * @param string $title The title. + * + * @return array Contains the modified title and alias. + * * @since 1.6 */ protected function generateNewTitle($parent_id, $alias, $title) From 2194a57bd21f88f491b6874be012fa71b07a6597 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 23 Nov 2011 15:54:23 +0430 Subject: [PATCH 06/40] Remove batchAccess override --- .../com_categories/models/category.php | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/administrator/components/com_categories/models/category.php b/administrator/components/com_categories/models/category.php index b43e0a8a9bccc..3d0d22efb5dd5 100644 --- a/administrator/components/com_categories/models/category.php +++ b/administrator/components/com_categories/models/category.php @@ -451,41 +451,6 @@ public function saveorder($idArray = null, $lft_array = null) } - /** - * Batch access level changes for a group of rows. - * - * @param int The new value matching an Asset Group ID. - * @param array An array of row IDs. - * @return booelan True if successful, false otherwise and internal error is set. - * @since 1.6 - */ - protected function batchAccess($value, $pks) - { - // Check that user has edit permission for every category being changed - // Note that the entire batch operation fails if any category lacks edit permission - $user = JFactory::getUser(); - $extension = JRequest::getWord('extension'); - foreach ($pks as $pk) { - if (!$user->authorise('core.edit', $extension.'.category.'.$pk)) { - // Error since user cannot edit this category - $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_EDIT')); - return false; - } - } - $table = $this->getTable(); - foreach ($pks as $pk) { - $table->reset(); - $table->load($pk); - $table->access = (int) $value; - if (!$table->store()) { - $this->setError($table->getError()); - return false; - } - } - - return true; - } - /** * Batch copy categories to a new category. * From 418bc5450b45111085b5ce1654546a9979fee1d8 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 23 Nov 2011 16:20:46 +0430 Subject: [PATCH 07/40] Convert queries and JRequest --- .../com_categories/models/category.php | 509 +++++++++++------- 1 file changed, 300 insertions(+), 209 deletions(-) diff --git a/administrator/components/com_categories/models/category.php b/administrator/components/com_categories/models/category.php index 3d0d22efb5dd5..c4bed0fd8d566 100644 --- a/administrator/components/com_categories/models/category.php +++ b/administrator/components/com_categories/models/category.php @@ -1,8 +1,10 @@ id)) { - if ($record->published != -2) { - return ; + if (!empty($record->id)) + { + if ($record->published != -2) + { + return; } $user = JFactory::getUser(); - return $user->authorise('core.delete', $record->extension.'.category.'.(int) $record->id); - + return $user->authorise('core.delete', $record->extension . '.category.' . (int) $record->id); } } /** - * Method to test whether a record can be deleted. + * Method to test whether a record can have its state changed. * - * @param object 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 + * @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(); // Check for existing category. - if (!empty($record->id)) { - return $user->authorise('core.edit.state', $record->extension.'.category.'.(int) $record->id); + if (!empty($record->id)) + { + return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->id); } // New category, so check against the parent. - elseif (!empty($record->parent_id)) { - return $user->authorise('core.edit.state', $record->extension.'.category.'.(int) $record->parent_id); + elseif (!empty($record->parent_id)) + { + return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->parent_id); } // Default to component settings if neither category nor parent known. - else { + else + { return $user->authorise('core.edit.state', $record->extension); } } /** - * Returns a Table object, always creating it + * Method to get a table object, load it if necessary. * - * @param type The table type to instantiate - * @param string A prefix for the table class name. Optional. - * @param array Configuration array for model. Optional. - * @return JTable A database object - * @since 1.6 + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 1.6 */ public function getTable($type = 'Category', $prefix = 'JTable', $config = array()) { @@ -89,7 +101,9 @@ public function getTable($type = 'Category', $prefix = 'JTable', $config = array * * Note. Calling getState in this method will result in recursion. * - * @since 1.6 + * @return void + * + * @since 1.6 */ protected function populateState() { @@ -100,38 +114,42 @@ protected function populateState() // Load the User state. $pk = (int) JRequest::getInt('id'); - $this->setState($this->getName().'.id', $pk); + $this->setState($this->getName() . '.id', $pk); $extension = JRequest::getCmd('extension', 'com_content'); $this->setState('category.extension', $extension); - $parts = explode('.',$extension); + $parts = explode('.', $extension); // Extract the component name $this->setState('category.component', $parts[0]); // Extract the optional section name - $this->setState('category.section', (count($parts)>1)?$parts[1]:null); + $this->setState('category.section', (count($parts) > 1) ? $parts[1] : null); // Load the parameters. - $params = JComponentHelper::getParams('com_categories'); + $params = JComponentHelper::getParams('com_categories'); $this->setState('params', $params); } /** * Method to get a category. * - * @param integer An optional id of the object to get, otherwise the id from the model state is used. - * @return mixed Category data object on success, false on failure. - * @since 1.6 + * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. + * + * @return mixed Category data object on success, false on failure. + * + * @since 1.6 */ public function getItem($pk = null) { - if ($result = parent::getItem($pk)) { + if ($result = parent::getItem($pk)) + { // Prime required properties. - if (empty($result->id)) { - $result->parent_id = $this->getState('category.parent_id'); - $result->extension = $this->getState('category.extension'); + if (empty($result->id)) + { + $result->parent_id = $this->getState('category.parent_id'); + $result->extension = $this->getState('category.extension'); } // Convert the metadata field to an array. @@ -141,23 +159,27 @@ public function getItem($pk = null) // Convert the created and modified dates to local user time for display in the form. jimport('joomla.utilities.date'); - $tz = new DateTimeZone(JFactory::getApplication()->getCfg('offset')); + $tz = new DateTimeZone(JFactory::getApplication()->getCfg('offset')); - if (intval($result->created_time)) { + if (intval($result->created_time)) + { $date = new JDate($result->created_time); $date->setTimezone($tz); $result->created_time = $date->format('Y-m-d H:i:s', true); } - else { + else + { $result->created_time = null; } - if (intval($result->modified_time)) { + if (intval($result->modified_time)) + { $date = new JDate($result->modified_time); $date->setTimezone($tz); $result->modified_time = $date->format('Y-m-d H:i:s', true); } - else { + else + { $result->modified_time = null; } } @@ -168,39 +190,44 @@ public function getItem($pk = null) /** * Method to get the row 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. - * @return mixed A JForm object on success, false on failure - * @since 1.6 + * @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. + * + * @return mixed A JForm object on success, false on failure + * + * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Initialise variables. - $extension = $this->getState('category.extension'); + $extension = $this->getState('category.extension'); // A workaround to get the extension into the model for save requests. - if (empty($extension) && isset($data['extension'])) { - $extension = $data['extension']; - $parts = explode('.',$extension); + if (empty($extension) && isset($data['extension'])) + { + $extension = $data['extension']; + $parts = explode('.', $extension); - $this->setState('category.extension', $extension); - $this->setState('category.component', $parts[0]); - $this->setState('category.section', @$parts[1]); + $this->setState('category.extension', $extension); + $this->setState('category.component', $parts[0]); + $this->setState('category.section', @$parts[1]); } // Get the form. - $form = $this->loadForm('com_categories.category'.$extension, 'category', array('control' => 'jform', 'load_data' => $loadData)); - if (empty($form)) { + $form = $this->loadForm('com_categories.category' . $extension, 'category', array('control' => 'jform', 'load_data' => $loadData)); + if (empty($form)) + { return false; } // Modify the form based on Edit State access controls. - if (empty($data['extension'])) { + if (empty($data['extension'])) + { $data['extension'] = $extension; } - - if (!$this->canEditState((object) $data)) { + if (!$this->canEditState((object) $data)) + { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('published', 'disabled', 'true'); @@ -218,10 +245,11 @@ public function getForm($data = array(), $loadData = true) * A protected method to get the where clause for the reorder * This ensures that the row will be moved relative to a row with the same extension * - * @param JCategoryTable current table instance + * @param JCategoryTable $table Current table instance * - * @return array An array of conditions to add to add to ordering queries. - * @since 1.6 + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 */ protected function getReorderConditions($table) { @@ -231,15 +259,17 @@ protected function getReorderConditions($table) /** * Method to get the data that should be injected in the form. * - * @return mixed The data for the form. - * @since 1.6 + * @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_categories.edit.'.$this->getName().'.data', array()); + $data = JFactory::getApplication()->getUserState('com_categories.edit.' . $this->getName() . '.data', array()); - if (empty($data)) { + if (empty($data)) + { $data = $this->getItem(); } @@ -247,59 +277,69 @@ protected function loadFormData() } /** - * @param object A form object. - * @param mixed The data expected for the form. - * @throws Exception if there is an error loading the form. - * @since 1.6 + * Method to preprocess the form. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $groups The name of the plugin group to import. + * + * @return void + * + * @see JFormField + * @since 1.6 + * @throws Exception if there is an error in the form event. */ protected function preprocessForm(JForm $form, $data, $groups = '') { jimport('joomla.filesystem.path'); // Initialise variables. - $lang = JFactory::getLanguage(); - $extension = $this->getState('category.extension'); - $component = $this->getState('category.component'); - $section = $this->getState('category.section'); + $lang = JFactory::getLanguage(); + $extension = $this->getState('category.extension'); + $component = $this->getState('category.component'); + $section = $this->getState('category.section'); // Get the component form if it exists jimport('joomla.filesystem.path'); - $name = 'category'.($section ? ('.'.$section):''); + $name = 'category' . ($section ? ('.' . $section) : ''); // Looking first in the component models/forms folder - $path = JPath::clean(JPATH_ADMINISTRATOR."/components/$component/models/forms/$name.xml"); + $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/models/forms/$name.xml"); // Old way: looking in the component folder - if (!file_exists($path)) { - $path = JPath::clean(JPATH_ADMINISTRATOR."/components/$component/$name.xml"); + if (!file_exists($path)) + { + $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/$name.xml"); } - if (file_exists($path)) { + if (file_exists($path)) + { $lang->load($component, JPATH_BASE, null, false, false); $lang->load($component, JPATH_BASE, $lang->getDefault(), false, false); - if (!$form->loadFile($path, false)) { + if (!$form->loadFile($path, false)) + { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } } // Try to find the component helper. - $eName = str_replace('com_', '', $component); - $path = JPath::clean(JPATH_ADMINISTRATOR."/components/$component/helpers/category.php"); + $eName = str_replace('com_', '', $component); + $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/helpers/category.php"); - if (file_exists($path)) { + if (file_exists($path)) + { require_once $path; - $cName = ucfirst($eName).ucfirst($section).'HelperCategory'; + $cName = ucfirst($eName) . ucfirst($section) . 'HelperCategory'; - if (class_exists($cName) && is_callable(array($cName, 'onPrepareForm'))) { - $lang->load($component, JPATH_BASE, null, false, false) - || $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, false) - || $lang->load($component, JPATH_BASE, $lang->getDefault(), false, false) - || $lang->load($component, JPATH_BASE . '/components/' . $component, $lang->getDefault(), false, false); + if (class_exists($cName) && is_callable(array($cName, 'onPrepareForm'))) + { + $lang->load($component, JPATH_BASE, null, false, false) || $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, false) || $lang->load($component, JPATH_BASE, $lang->getDefault(), false, false) || $lang->load($component, JPATH_BASE . '/components/' . $component, $lang->getDefault(), false, false); call_user_func_array(array($cName, 'onPrepareForm'), array(&$form)); // Check for an error. - if ($form instanceof Exception) { + if ($form instanceof Exception) + { $this->setError($form->getMessage()); return false; } @@ -307,8 +347,8 @@ protected function preprocessForm(JForm $form, $data, $groups = '') } // Set the access control rules field component value. - $form->setFieldAttribute('rules', 'component', $component); - $form->setFieldAttribute('rules', 'section', $name); + $form->setFieldAttribute('rules', 'component', $component); + $form->setFieldAttribute('rules', 'section', $name); // Trigger the default form events. parent::preprocessForm($form, $data); @@ -317,86 +357,98 @@ protected function preprocessForm(JForm $form, $data, $groups = '') /** * Method to save the form data. * - * @param array The form data. - * @return boolean True on success. - * @since 1.6 + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 */ public function save($data) { // Initialise variables; $dispatcher = JDispatcher::getInstance(); - $table = $this->getTable(); - $pk = (!empty($data['id'])) ? $data['id'] : (int)$this->getState($this->getName().'.id'); - $isNew = true; + $table = $this->getTable(); + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); + $isNew = true; // Include the content plugins for the on save events. JPluginHelper::importPlugin('content'); // Load the row if saving an existing category. - if ($pk > 0) { + if ($pk > 0) + { $table->load($pk); $isNew = false; } // Set the new parent id if parent id not matched OR while New/Save as Copy . - if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) { + if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) + { $table->setLocation($data['parent_id'], 'last-child'); } // Alter the title for save as copy - if (JRequest::getVar('task') == 'save2copy') { - list($title,$alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['title']); - $data['title'] = $title; - $data['alias'] = $alias; + if (JRequest::getVar('task') == 'save2copy') + { + list($title, $alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['title']); + $data['title'] = $title; + $data['alias'] = $alias; } // Bind the data. - if (!$table->bind($data)) { + if (!$table->bind($data)) + { $this->setError($table->getError()); return false; } // Bind the rules. - if (isset($data['rules'])) { + if (isset($data['rules'])) + { $rules = new JRules($data['rules']); $table->setRules($rules); } // Check the data. - if (!$table->check()) { + if (!$table->check()) + { $this->setError($table->getError()); return false; } // Trigger the onContentBeforeSave event. - $result = $dispatcher->trigger($this->event_before_save, array($this->option.'.'.$this->name, &$table, $isNew)); - if (in_array(false, $result, true)) { + $result = $dispatcher->trigger($this->event_before_save, array($this->option . '.' . $this->name, &$table, $isNew)); + if (in_array(false, $result, true)) + { $this->setError($table->getError()); return false; } // Store the data. - if (!$table->store()) { + if (!$table->store()) + { $this->setError($table->getError()); return false; } // Trigger the onContentAfterSave event. - $dispatcher->trigger($this->event_after_save, array($this->option.'.'.$this->name, &$table, $isNew)); + $dispatcher->trigger($this->event_after_save, array($this->option . '.' . $this->name, &$table, $isNew)); // Rebuild the path for the category: - if (!$table->rebuildPath($table->id)) { + if (!$table->rebuildPath($table->id)) + { $this->setError($table->getError()); return false; } // Rebuild the paths of the category's children: - if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) { + if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) + { $this->setError($table->getError()); return false; } - $this->setState($this->getName().'.id', $table->id); + $this->setState($this->getName() . '.id', $table->id); // Clear the cache $this->cleanCache(); @@ -407,15 +459,17 @@ public function save($data) /** * Method rebuild the entire nested set tree. * - * @return boolean False on failure or error, true otherwise. - * @since 1.6 + * @return boolean False on failure or error, true otherwise. + * + * @since 1.6 */ public function rebuild() { - // Get an instance of the table obejct. + // Get an instance of the table object. $table = $this->getTable(); - if (!$table->rebuild()) { + if (!$table->rebuild()) + { $this->setError($table->getError()); return false; } @@ -431,15 +485,20 @@ public function rebuild() * First we save the new order values in the lft values of the changed ids. * Then we invoke the table rebuild to implement the new ordering. * - * @return boolean false on failuer or error, true otherwise - * @since 1.6 + * @param array $idArray An array of primary key ids. + * @param integer $lft_array The lft value + * + * @return boolean False on failure or error, True otherwise + * + * @since 1.6 */ public function saveorder($idArray = null, $lft_array = null) { // Get an instance of the table object. $table = $this->getTable(); - if (!$table->saveorder($idArray, $lft_array)) { + if (!$table->saveorder($idArray, $lft_array)) + { $this->setError($table->getError()); return false; } @@ -448,48 +507,52 @@ public function saveorder($idArray = null, $lft_array = null) $this->cleanCache(); return true; - } /** * Batch copy categories to a new category. * - * @param int $value The new category or sub-item. - * @param array $pks An array of row IDs. + * @param integer $value The new category or sub-item. + * @param array $pks An array of row IDs. * - * @return mixed An array of new IDs on success, boolean false on failure. - * @since 1.6 + * @return mixed An array of new IDs on success, boolean false on failure. + * + * @since 1.6 */ protected function batchCopy($value, $pks) { // $value comes as {parent_id}.{extension} - $parts = explode('.', $value); - $parentId = (int) JArrayHelper::getValue($parts, 0, 1); + $parts = explode('.', $value); + $parentId = (int) JArrayHelper::getValue($parts, 0, 1); - $table = $this->getTable(); - $db = $this->getDbo(); - $user = JFactory::getUser(); - $extension = JRequest::getWord('extension'); - $i = 0; + $table = $this->getTable(); + $db = $this->getDbo(); + $user = JFactory::getUser(); + $extension = JFactory::getApplication()->input->get('extension', '', 'word'); + $i = 0; // Check that the parent exists - if ($parentId) { - if (!$table->load($parentId)) { - if ($error = $table->getError()) { + if ($parentId) + { + if (!$table->load($parentId)) + { + if ($error = $table->getError()) + { // Fatal error $this->setError($error); return false; } - else { + else + { // Non-fatal error $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); $parentId = 0; } } // Check that user has create permission for parent category - $canCreate = ($parentId == $table->getRootId()) ? $user->authorise('core.create', $extension) : - $user->authorise('core.create', $extension.'.category.'.$parentId); - if (!$canCreate) { + $canCreate = ($parentId == $table->getRootId()) ? $user->authorise('core.create', $extension) : $user->authorise('core.create', $extension . '.category.' . $parentId); + if (!$canCreate) + { // Error since user cannot create in parent category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; @@ -497,13 +560,16 @@ protected function batchCopy($value, $pks) } // If the parent is 0, set it to the ID of the root item in the tree - if (empty($parentId)) { - if (!$parentId = $table->getRootId()) { + if (empty($parentId)) + { + if (!$parentId = $table->getRootId()) + { $this->setError($db->getErrorMsg()); return false; } // Make sure we can create in root - elseif (!$user->authorise('core.create', $extension)) { + elseif (!$user->authorise('core.create', $extension)) + { $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; } @@ -513,13 +579,14 @@ protected function batchCopy($value, $pks) $parents = array(); // Calculate the emergency stop count as a precaution against a runaway loop bug - $db->setQuery( - 'SELECT COUNT(id)' . - ' FROM #__categories' - ); + $query = $db->getQuery(true); + $query->select('COUNT(id)'); + $query->from($db->quoteName('#__categories')); + $db->setQuery($query); $count = $db->loadResult(); - if ($error = $db->getErrorMsg()) { + if ($error = $db->getErrorMsg()) + { $this->setError($error); return false; } @@ -533,13 +600,16 @@ protected function batchCopy($value, $pks) $table->reset(); // Check that the row actually exists - if (!$table->load($pk)) { - if ($error = $table->getError()) { + if (!$table->load($pk)) + { + if ($error = $table->getError()) + { // Fatal error $this->setError($error); return false; } - else { + else + { // Not fatal error $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; @@ -547,49 +617,52 @@ protected function batchCopy($value, $pks) } // Copy is a bit tricky, because we also need to copy the children - $db->setQuery( - 'SELECT id' . - ' FROM #__categories' . - ' WHERE lft > '.(int) $table->lft.' AND rgt < '.(int) $table->rgt - ); - $childIds = $db->loadResultArray(); + $query->clear(); + $query->select('id'); + $query->from($db->quoteName('#__categories')); + $query->where('lft > ' . (int) $table->lft); + $query->where('rgt < ' . (int) $table->rgt); + $db->setQuery($query); + $childIds = $db->loadColumn(); // Add child ID's to the array only if they aren't already there. foreach ($childIds as $childId) { - if (!in_array($childId, $pks)) { + if (!in_array($childId, $pks)) + { array_push($pks, $childId); } } // Make a copy of the old ID and Parent ID - $oldId = $table->id; - $oldParentId = $table->parent_id; + $oldId = $table->id; + $oldParentId = $table->parent_id; // Reset the id because we are making a copy. - $table->id = 0; + $table->id = 0; // If we a copying children, the Old ID will turn up in the parents list // otherwise it's a new top level item - $table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; + $table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; // Set the new location in the tree for the node. $table->setLocation($table->parent_id, 'last-child'); // TODO: Deal with ordering? //$table->ordering = 1; - $table->level = null; - $table->asset_id = null; - $table->lft = null; - $table->rgt = null; + $table->level = null; + $table->asset_id = null; + $table->lft = null; + $table->rgt = null; // Alter the title & alias - list($title,$alias) = $this->generateNewTitle($table->parent_id, $table->alias, $table->title); - $table->title = $title; - $table->alias = $alias; + list($title, $alias) = $this->generateNewTitle($table->parent_id, $table->alias, $table->title); + $table->title = $title; + $table->alias = $alias; // Store the row. - if (!$table->store()) { + if (!$table->store()) + { $this->setError($table->getError()); return false; } @@ -598,7 +671,7 @@ protected function batchCopy($value, $pks) $newId = $table->get('id'); // Add the new ID to the array - $newIds[$i] = $newId; + $newIds[$i] = $newId; $i++; // Now we log the old 'parent' to the new 'parent' @@ -607,13 +680,15 @@ protected function batchCopy($value, $pks) } // Rebuild the hierarchy. - if (!$table->rebuild()) { + if (!$table->rebuild()) + { $this->setError($table->getError()); return false; } // Rebuild the tree path. - if (!$table->rebuildPath($table->id)) { + if (!$table->rebuildPath($table->id)) + { $this->setError($table->getError()); return false; } @@ -624,40 +699,46 @@ protected function batchCopy($value, $pks) /** * Batch move categories to a new category. * - * @param int $value The new category or sub-item. - * @param array $pks An array of row IDs. + * @param integer $value The new category or sub-item. + * @param array $pks An array of row IDs. * - * @return booelan True if successful, false otherwise and internal error is set. - * @since 1.6 + * @return mixed An array of new IDs on success, boolean false on failure. + * + * @since 1.6 */ protected function batchMove($value, $pks) { - $parentId = (int) $value; + $parentId = (int) $value; - $table = $this->getTable(); - $db = $this->getDbo(); - $user = JFactory::getUser(); - $extension = JRequest::getWord('extension'); + $table = $this->getTable(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = JFactory::getUser(); + $extension = JFactory::getApplication()->input->get('extension', '', 'word'); // Check that the parent exists. - if ($parentId) { - if (!$table->load($parentId)) { - if ($error = $table->getError()) { + if ($parentId) + { + if (!$table->load($parentId)) + { + if ($error = $table->getError()) + { // Fatal error $this->setError($error); return false; } - else { + else + { // Non-fatal error $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); $parentId = 0; } } // Check that user has create permission for parent category - $canCreate = ($parentId == $table->getRootId()) ? $user->authorise('core.create', $extension) : - $user->authorise('core.create', $extension.'.category.'.$parentId); - if (!$canCreate) { + $canCreate = ($parentId == $table->getRootId()) ? $user->authorise('core.create', $extension) : $user->authorise('core.create', $extension . '.category.' . $parentId); + if (!$canCreate) + { // Error since user cannot create in parent category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; @@ -665,8 +746,10 @@ protected function batchMove($value, $pks) // Check that user has edit permission for every category being moved // Note that the entire batch operation fails if any category lacks edit permission - foreach ($pks as $pk) { - if (!$user->authorise('core.edit', $extension.'.category.'.$pk)) { + foreach ($pks as $pk) + { + if (!$user->authorise('core.edit', $extension . '.category.' . $pk)) + { // Error since user cannot edit this category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_EDIT')); return false; @@ -674,7 +757,6 @@ protected function batchMove($value, $pks) } } - // We are going to store all the children and just move the category $children = array(); @@ -682,13 +764,16 @@ protected function batchMove($value, $pks) foreach ($pks as $pk) { // Check that the row actually exists - if (!$table->load($pk)) { - if ($error = $table->getError()) { + if (!$table->load($pk)) + { + if ($error = $table->getError()) + { // Fatal error $this->setError($error); return false; } - else { + else + { // Not fatal error $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; @@ -699,36 +784,42 @@ protected function batchMove($value, $pks) $table->setLocation($parentId, 'last-child'); // Check if we are moving to a different parent - if ($parentId != $table->parent_id) { + if ($parentId != $table->parent_id) + { // Add the child node ids to the children array. - $db->setQuery( - 'SELECT '.$db->nameQuote(id).' . - FROM '.$db->nameQuote("#__categories").' WHERE $db->nameQuote(lft) BETWEEN '.(int) $table->lft.' AND '.(int) $table->rgt - ); - $children = array_merge($children, (array) $db->loadResultArray()); + $query->clear(); + $query->select('id'); + $query->from($db->quoteName('#__categories')); + $query->where($db->quoteName('lft' ) .' BETWEEN ' . (int) $table->lft . ' AND ' . (int) $table->rgt); + $db->setQuery($query); + $children = array_merge($children, (array) $db->loadColumn()); } // Store the row. - if (!$table->store()) { + if (!$table->store()) + { $this->setError($table->getError()); return false; } // Rebuild the tree path. - if (!$table->rebuildPath()) { + if (!$table->rebuildPath()) + { $this->setError($table->getError()); return false; } } // Process the child rows - if (!empty($children)) { + if (!empty($children)) + { // Remove any duplicates and sanitize ids. $children = array_unique($children); JArrayHelper::toInteger($children); // Check for a database error. - if ($db->getErrorNum()) { + if ($db->getErrorNum()) + { $this->setError($db->getErrorMsg()); return false; } From d848d76837e7d1d340beba69668bec3bafe4c56e Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 23 Nov 2011 16:32:51 +0430 Subject: [PATCH 08/40] Query work --- .../com_categories/models/category.php | 4 +- .../components/com_menus/models/item.php | 267 ++++++++++-------- 2 files changed, 157 insertions(+), 114 deletions(-) diff --git a/administrator/components/com_categories/models/category.php b/administrator/components/com_categories/models/category.php index c4bed0fd8d566..a08b3ee27898c 100644 --- a/administrator/components/com_categories/models/category.php +++ b/administrator/components/com_categories/models/category.php @@ -1,7 +1,7 @@ setError(JText::_('COM_MENUS_NO_ITEM_SELECTED')); return false; } $done = false; - if (!empty($commands['menu_id'])) + if (!empty($commands['menu_id'])) { $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); @@ -139,8 +145,10 @@ function batch($commands, $pks) $done = true; } - if (!empty($commands['assetgroup_id'])) { - if (!$this->batchAccess($commands['assetgroup_id'], $pks)) { + if (!empty($commands['assetgroup_id'])) + { + if (!$this->batchAccess($commands['assetgroup_id'], $pks, $contexts)) + { return false; } @@ -149,7 +157,7 @@ function batch($commands, $pks) if (!empty($commands['language_id'])) { - if (!$this->batchLanguage($commands['language_id'], $pks)) + if (!$this->batchLanguage($commands['language_id'], $pks, $contexts)) { return false; } @@ -157,7 +165,8 @@ function batch($commands, $pks) $done = true; } - if (!$done) { + if (!$done) + { $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); return false; } @@ -168,32 +177,38 @@ function batch($commands, $pks) /** * Batch copy menu items to a new menu or parent. * - * @param int $value The new menu or sub-item. - * @param array $pks An array of row IDs. + * @param integer $value The new menu or sub-item. + * @param array $pks An array of row IDs. * - * @return mixed An array of new IDs on success, boolean false on failure. - * @since 1.6 + * @return mixed An array of new IDs on success, boolean false on failure. + * + * @since 1.6 */ protected function batchCopy($value, $pks) { // $value comes as {menutype}.{parent_id} - $parts = explode('.', $value); - $menuType = $parts[0]; - $parentId = (int) JArrayHelper::getValue($parts, 1, 0); + $parts = explode('.', $value); + $menuType = $parts[0]; + $parentId = (int) JArrayHelper::getValue($parts, 1, 0); - $table = $this->getTable(); - $db = $this->getDbo(); - $i = 0; + $table = $this->getTable(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + $i = 0; // Check that the parent exists - if ($parentId) { - if (!$table->load($parentId)) { - if ($error = $table->getError()) { + if ($parentId) + { + if (!$table->load($parentId)) + { + if ($error = $table->getError()) + { // Fatal error $this->setError($error); return false; } - else { + else + { // Non-fatal error $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); $parentId = 0; @@ -202,16 +217,19 @@ protected function batchCopy($value, $pks) } // If the parent is 0, set it to the ID of the root item in the tree - if (empty($parentId)) { - if (!$parentId = $table->getRootId()) { + if (empty($parentId)) + { + if (!$parentId = $table->getRootId()) + { $this->setError($db->getErrorMsg()); return false; } } // Check that user has create permission for menus - $user = JFactory::getUser(); - if (!$user->authorise('core.create', 'com_menus')) { + $user = JFactory::getUser(); + if (!$user->authorise('core.create', 'com_menus')) + { $this->setError(JText::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_CREATE')); return false; } @@ -220,13 +238,13 @@ protected function batchCopy($value, $pks) $parents = array(); // Calculate the emergency stop count as a precaution against a runaway loop bug - $db->setQuery( - 'SELECT COUNT(id)' . - ' FROM #__menu' - ); + $query->select('COUNT(id)'); + $query->from($db->quoteName('#__menu')); + $db->setQuery($query); $count = $db->loadResult(); - if ($error = $db->getErrorMsg()) { + if ($error = $db->getErrorMsg()) + { $this->setError($error); return false; } @@ -240,13 +258,16 @@ protected function batchCopy($value, $pks) $table->reset(); // Check that the row actually exists - if (!$table->load($pk)) { - if ($error = $table->getError()) { + if (!$table->load($pk)) + { + if ($error = $table->getError()) + { // Fatal error $this->setError($error); return false; } - else { + else + { // Not fatal error $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; @@ -254,55 +275,59 @@ protected function batchCopy($value, $pks) } // Copy is a bit tricky, because we also need to copy the children - $db->setQuery( - 'SELECT id' . - ' FROM #__menu' . - ' WHERE lft > '.(int) $table->lft.' AND rgt < '.(int) $table->rgt - ); - $childIds = $db->loadResultArray(); + $query->clear(); + $query->select('id'); + $query->from($db->quoteName('#__menu')); + $query->where('lft > ' . (int) $table->lft); + $query->where('rgt < ' . (int) $table->rgt); + $db->setQuery($query); + $childIds = $db->loadColumn(); // Add child ID's to the array only if they aren't already there. foreach ($childIds as $childId) { - if (!in_array($childId, $pks)) { + if (!in_array($childId, $pks)) + { array_push($pks, $childId); } } // Make a copy of the old ID and Parent ID - $oldId = $table->id; - $oldParentId = $table->parent_id; + $oldId = $table->id; + $oldParentId = $table->parent_id; // Reset the id because we are making a copy. - $table->id = 0; + $table->id = 0; // If we a copying children, the Old ID will turn up in the parents list // otherwise it's a new top level item - $table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; - $table->menutype = $menuType; + $table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; + $table->menutype = $menuType; // Set the new location in the tree for the node. $table->setLocation($table->parent_id, 'last-child'); // TODO: Deal with ordering? //$table->ordering = 1; - $table->level = null; - $table->lft = null; - $table->rgt = null; - $table->home = 0; + $table->level = null; + $table->lft = null; + $table->rgt = null; + $table->home = 0; // Alter the title & alias - list($title,$alias) = $this->generateNewTitle($table->parent_id, $table->alias, $table->title); - $table->title = $title; - $table->alias = $alias; + list($title, $alias) = $this->generateNewTitle($table->parent_id, $table->alias, $table->title); + $table->title = $title; + $table->alias = $alias; // Check the row. - if (!$table->check()) { + if (!$table->check()) + { $this->setError($table->getError()); return false; } // Store the row. - if (!$table->store()) { + if (!$table->store()) + { $this->setError($table->getError()); return false; } @@ -311,7 +336,7 @@ protected function batchCopy($value, $pks) $newId = $table->get('id'); // Add the new ID to the array - $newIds[$i] = $newId; + $newIds[$i] = $newId; $i++; // Now we log the old 'parent' to the new 'parent' @@ -320,13 +345,15 @@ protected function batchCopy($value, $pks) } // Rebuild the hierarchy. - if (!$table->rebuild()) { + if (!$table->rebuild()) + { $this->setError($table->getError()); return false; } // Rebuild the tree path. - if (!$table->rebuildPath($table->id)) { + if (!$table->rebuildPath($table->id)) + { $this->setError($table->getError()); return false; } @@ -340,32 +367,38 @@ protected function batchCopy($value, $pks) /** * Batch move menu items to a new menu or parent. * - * @param int $value The new menu or sub-item. - * @param array $pks An array of row IDs. + * @param integer $value The new menu or sub-item. + * @param array $pks An array of row IDs. * - * @return booelan True if successful, false otherwise and internal error is set. - * @since 1.6 + * @return boolean True on success. + * + * @since 1.6 */ protected function batchMove($value, $pks) { // $value comes as {menutype}.{parent_id} - $parts = explode('.', $value); - $menuType = $parts[0]; - $parentId = (int) JArrayHelper::getValue($parts, 1, 0); + $parts = explode('.', $value); + $menuType = $parts[0]; + $parentId = (int) JArrayHelper::getValue($parts, 1, 0); - $table = $this->getTable(); - $db = $this->getDbo(); + $table = $this->getTable(); + $db = $this->getDbo(); + $query = $db->getQuery(true); // Check that the parent exists. - if ($parentId) { - if (!$table->load($parentId)) { - if ($error = $table->getError()) { + if ($parentId) + { + if (!$table->load($parentId)) + { + if ($error = $table->getError()) + { // Fatal error $this->setError($error); return false; } - else { + else + { // Non-fatal error $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); $parentId = 0; @@ -374,13 +407,15 @@ protected function batchMove($value, $pks) } // Check that user has create and edit permission for menus - $user = JFactory::getUser(); - if (!$user->authorise('core.create', 'com_menus')) { + $user = JFactory::getUser(); + if (!$user->authorise('core.create', 'com_menus')) + { $this->setError(JText::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_CREATE')); return false; } - if (!$user->authorise('core.edit', 'com_menus')) { + if (!$user->authorise('core.edit', 'com_menus')) + { $this->setError(JText::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_EDIT')); return false; } @@ -392,13 +427,16 @@ protected function batchMove($value, $pks) foreach ($pks as $pk) { // Check that the row actually exists - if (!$table->load($pk)) { - if ($error = $table->getError()) { + if (!$table->load($pk)) + { + if ($error = $table->getError()) + { // Fatal error $this->setError($error); return false; } - else { + else + { // Not fatal error $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; @@ -412,54 +450,60 @@ protected function batchMove($value, $pks) $table->parent_id = $parentId; // Check if we are moving to a different menu - if ($menuType != $table->menutype) { + if ($menuType != $table->menutype) + { // Add the child node ids to the children array. - $db->setQuery( - 'SELECT '.$db->nameQuote('id') . - ' FROM '.$db->nameQuote('#__menu') . - ' WHERE '.$db->nameQuote('lft').' BETWEEN '.(int) $table->lft.' AND '.(int) $table->rgt - ); - $children = array_merge($children, (array) $db->loadResultArray()); + $query->clear(); + $query->select($db->quoteName('id')); + $query->from($db->quoteName('#__menu')); + $query->where($db->quoteName('lft') .' BETWEEN ' . (int) $table->lft . ' AND ' . (int) $table->rgt); + $db->setQuery($query); + $children = array_merge($children, (array) $db->loadColumn()); } // Check the row. - if (!$table->check()) { + if (!$table->check()) + { $this->setError($table->getError()); return false; } // Store the row. - if (!$table->store()) { + if (!$table->store()) + { $this->setError($table->getError()); return false; } // Rebuild the tree path. - if (!$table->rebuildPath()) { + if (!$table->rebuildPath()) + { $this->setError($table->getError()); return false; } } // Process the child rows - if (!empty($children)) { + if (!empty($children)) + { // Remove any duplicates and sanitize ids. $children = array_unique($children); JArrayHelper::toInteger($children); // Update the menutype field in all nodes where necessary. - $db->setQuery( - 'UPDATE '.$db->nameQuote('#__menu') . - ' SET '.$db->nameQuote('menutype').' = '.$db->quote($menuType). - ' WHERE '.$db->nameQuote('id').' IN ('.implode(',', $children).')' - ); - $db->query(); + $query->clear(); + $query->update($db->quoteName('#__menu')); + $query->set($db->quoteName('menutype') . ' = ' . $db->quote($menuType)); + $query->where($db->quoteName('id') . ' IN (' . implode(',', $children) . ')'); + $db->setQuery($query); + $db->query(); - // Check for a database error. - if ($db->getErrorNum()) { - $this->setError($db->getErrorMsg()); - return false; - } + // Check for a database error. + if ($db->getErrorNum()) + { + $this->setError($db->getErrorMsg()); + return false; + } } // Clean the cache @@ -1333,7 +1377,7 @@ protected function generateNewTitle($parent_id, $alias, $title) $alias = JString::increment($alias, 'dash'); } - return array($title ,$alias); + return array($title, $alias); } /** @@ -1346,5 +1390,4 @@ protected function cleanCache($group = null, $client_id = 0) parent::cleanCache('com_modules'); parent::cleanCache('mod_menu'); } - } From 0389d8048ea705d794086b0e21c7de706860fa4b Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 23 Nov 2011 17:02:10 +0430 Subject: [PATCH 09/40] Add HTML widget for modules copy/move --- .../com_modules/helpers/html/modules.php | 74 +++++++++++++++++++ .../views/modules/tmpl/default.php | 2 - .../views/modules/tmpl/default_batch.php | 10 ++- .../com_modules/views/modules/view.html.php | 2 + .../language/en-GB/en-GB.com_modules.ini | 3 + 5 files changed, 88 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_modules/helpers/html/modules.php b/administrator/components/com_modules/helpers/html/modules.php index 0b1bb1a000b59..37ae0e8ef9c0a 100644 --- a/administrator/components/com_modules/helpers/html/modules.php +++ b/administrator/components/com_modules/helpers/html/modules.php @@ -104,4 +104,78 @@ public static function state($value, $i, $enabled = true, $checkbox = 'cb') return JHtml::_('jgrid.state', $states, $value, $i, 'modules.', $enabled, true, $checkbox); } + + /** + * Display a batch widget for the module position selector. + * + * @param integer $clientId The client ID + * + * @return string The necessary HTML for the widget. + * + * @since 2.5 + */ + public static function positions($clientId) + { + // Create the copy/move options. + $options = array( + JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')), + JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE')) + ); + + // Create the batch selector to change select the category by which to move or copy. + $lines = array( + '', + '
', + '', + JHtml::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm'), + '
' + ); + + return implode("\n", $lines); + } + + /** + * Method to get the field options. + * + * @param integer $clientId The client ID + * + * @return array The field option objects. + * + * @since 2.5 + */ + public static function positionList($clientId = 0) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('DISTINCT(position) as value'); + $query->select('position as text'); + $query->from($db->quoteName('#__modules')); + $query->where($db->quoteName('client_id') . ' = ' . (int) $clientId); + $query->order('position'); + + // Get the options. + $db->setQuery($query); + + $options = $db->loadObjectList(); + + // Check for a database error. + if ($db->getErrorNum()) + { + JError::raiseWarning(500, $db->getErrorMsg()); + } + + // Pop the first item off the array if it's blank + if (strlen($options[0]->text) < 1) + { + array_shift($options); + } + + return $options; + } } diff --git a/administrator/components/com_modules/views/modules/tmpl/default.php b/administrator/components/com_modules/views/modules/tmpl/default.php index 307bd76a4f245..35f72ba71d776 100644 --- a/administrator/components/com_modules/views/modules/tmpl/default.php +++ b/administrator/components/com_modules/views/modules/tmpl/default.php @@ -10,8 +10,6 @@ // No direct access. defined('_JEXEC') or die; -// Include the component HTML helpers. -JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); JHtml::_('behavior.tooltip'); JHtml::_('behavior.multiselect'); diff --git a/administrator/components/com_modules/views/modules/tmpl/default_batch.php b/administrator/components/com_modules/views/modules/tmpl/default_batch.php index 38dff5d4a33f5..ab88396c846c8 100644 --- a/administrator/components/com_modules/views/modules/tmpl/default_batch.php +++ b/administrator/components/com_modules/views/modules/tmpl/default_batch.php @@ -9,16 +9,24 @@ // no direct access defined('_JEXEC') or die; + +$clientId = $this->state->get('filter.client_id'); +$published = $this->state->get('filter.published'); ?>
+

+ = 0) : ?> + + + -
diff --git a/administrator/components/com_modules/views/modules/view.html.php b/administrator/components/com_modules/views/modules/view.html.php index 412c231eaff6a..b94b35c4818c4 100644 --- a/administrator/components/com_modules/views/modules/view.html.php +++ b/administrator/components/com_modules/views/modules/view.html.php @@ -47,6 +47,8 @@ public function display($tpl = null) } $this->addToolbar(); + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); parent::display($tpl); } diff --git a/administrator/language/en-GB/en-GB.com_modules.ini b/administrator/language/en-GB/en-GB.com_modules.ini index 397f6466f5f3c..62fddd968ddc4 100644 --- a/administrator/language/en-GB/en-GB.com_modules.ini +++ b/administrator/language/en-GB/en-GB.com_modules.ini @@ -9,7 +9,10 @@ COM_MODULES_ADVANCED_FIELDSET_LABEL="Advanced Options" COM_MODULES_ASSIGNED_VARIES_EXCEPT="All except selected" COM_MODULES_ASSIGNED_VARIES_ONLY="Selected only" COM_MODULES_BASIC_FIELDSET_LABEL="Basic Options" +COM_MODULES_BATCH_POSITION_LABEL="Set Position" +COM_MODULES_BATCH_POSITION_NOCHANGE="- Keep original Position -" COM_MODULES_BATCH_OPTIONS="Batch process the selected modules" +COM_MODULES_BATCH_TIP="If choosing to copy a module, any other actions selected will be applied to the copied module. Otherwise, all actions are applied to the selected module." COM_MODULES_CHANGE_POSITION_BUTTON="Select position" COM_MODULES_CHANGE_POSITION_TITLE="Change position" COM_MODULES_CONFIGURATION="Module Manager Options" From 6fc2e0f535f0b622f5da4bd960ecf830a6258028 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 23 Nov 2011 17:06:38 +0430 Subject: [PATCH 10/40] CSS for batch widgets --- administrator/templates/bluestork/css/template.css | 11 +++++------ .../templates/bluestork/css/template_rtl.css | 6 ++++-- administrator/templates/hathor/css/template.css | 9 ++++----- administrator/templates/hathor/css/template_rtl.css | 10 ++++------ 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/administrator/templates/bluestork/css/template.css b/administrator/templates/bluestork/css/template.css index 87739d65e6e10..3a788508808a0 100644 --- a/administrator/templates/bluestork/css/template.css +++ b/administrator/templates/bluestork/css/template.css @@ -679,7 +679,7 @@ div.current fieldset { border: none 0; } -div.current fieldset.adminform { +div.current fieldset.adminform { border: 1px #ccc solid; } @@ -773,7 +773,7 @@ li.acl-resetbtn:hover { margin-right: 15px; float: left; margin-bottom: 15px; - + } #cpanel div.icon a { @@ -1056,10 +1056,9 @@ label#batch-language-lbl { select#batch-language-id { margin-top: 15px; } -select#batch-category-id { - margin-right: 30px; -} -select#batch-menu-id { +select#batch-category-id, +select#batch-menu-id, +select#batch-position-id { margin-right: 30px; } label#batch-access-lbl { diff --git a/administrator/templates/bluestork/css/template_rtl.css b/administrator/templates/bluestork/css/template_rtl.css index e2020b803771d..5f59e27ec4eca 100644 --- a/administrator/templates/bluestork/css/template_rtl.css +++ b/administrator/templates/bluestork/css/template_rtl.css @@ -488,11 +488,13 @@ label#batch-language-lbl { select#batch-language-id { margin-top: 15px; } -select#batch-category-id { +select#batch-category-id, +select#batch-menu-id, +select#batch-position-id { margin-left: 30px; margin-right: 0; } -select#batch-menu-id { + { margin-left: 30px; margin-right: 0; } diff --git a/administrator/templates/hathor/css/template.css b/administrator/templates/hathor/css/template.css index b76189bc61d4f..50290c2ae3366 100644 --- a/administrator/templates/hathor/css/template.css +++ b/administrator/templates/hathor/css/template.css @@ -1969,16 +1969,15 @@ label#batch-language-lbl { select#batch-language-id { margin-top: 15px; } -select#batch-category-id { +select#batch-category-id, +select#batch-position-id, +select#batch-menu-id { margin-right: 30px; } fieldset.batch select, fieldset.batch input, fieldset.batch img, fieldset.batch button { float: left; } -select#batch-menu-id { - margin-right: 30px; -} label#batch-access-lbl { margin-right: 10px; } @@ -2594,4 +2593,4 @@ span.update-badge { padding: 0 0.1em 0; position: relative; top: -88px; -} \ No newline at end of file +} diff --git a/administrator/templates/hathor/css/template_rtl.css b/administrator/templates/hathor/css/template_rtl.css index 5ed9f77c6085e..27c398cd2ca4f 100644 --- a/administrator/templates/hathor/css/template_rtl.css +++ b/administrator/templates/hathor/css/template_rtl.css @@ -950,18 +950,16 @@ label#batch-language-lbl { select#batch-language-id { margin-top: 15px; } -select#batch-category-id { +select#batch-category-id, +select#batch-menu-id, +select#batch-position-id +{ margin-left: 30px; margin-right: 0; } fieldset.batch select, fieldset.batch input, fieldset.batch img, fieldset.batch button { float: right; } - -select#batch-menu-id { - margin-right: 0; - margin-left: 30px; -} label#batch-access-lbl { margin-right: 0; margin-left: 10px; From 93d795d0978aa524b795555f87665d900bc431db Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 2 Dec 2011 17:14:53 +0600 Subject: [PATCH 11/40] Fix Client appearance --- .../com_banners/views/banners/tmpl/default_batch.php | 2 +- administrator/templates/bluestork/css/template.css | 3 ++- administrator/templates/bluestork/css/template_rtl.css | 3 ++- administrator/templates/hathor/css/template.css | 3 ++- administrator/templates/hathor/css/template_rtl.css | 3 ++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/administrator/components/com_banners/views/banners/tmpl/default_batch.php b/administrator/components/com_banners/views/banners/tmpl/default_batch.php index 0d29e0e1682e1..951cb9adf6e4d 100644 --- a/administrator/components/com_banners/views/banners/tmpl/default_batch.php +++ b/administrator/components/com_banners/views/banners/tmpl/default_batch.php @@ -15,8 +15,8 @@

- + = 0) : ?> diff --git a/administrator/templates/bluestork/css/template.css b/administrator/templates/bluestork/css/template.css index 3a788508808a0..1ba9e682965d2 100644 --- a/administrator/templates/bluestork/css/template.css +++ b/administrator/templates/bluestork/css/template.css @@ -1061,7 +1061,8 @@ select#batch-menu-id, select#batch-position-id { margin-right: 30px; } -label#batch-access-lbl { +label#batch-access-lbl, +label#batch-client-lbl { margin-right: 10px; } diff --git a/administrator/templates/bluestork/css/template_rtl.css b/administrator/templates/bluestork/css/template_rtl.css index 5f59e27ec4eca..d279ab139c0c5 100644 --- a/administrator/templates/bluestork/css/template_rtl.css +++ b/administrator/templates/bluestork/css/template_rtl.css @@ -498,7 +498,8 @@ select#batch-position-id { margin-left: 30px; margin-right: 0; } -label#batch-access-lbl { +label#batch-access-lbl, +label#batch-client-lbl { margin-left: 10px; margin-right: 0; } diff --git a/administrator/templates/hathor/css/template.css b/administrator/templates/hathor/css/template.css index 50290c2ae3366..2579a869394e7 100644 --- a/administrator/templates/hathor/css/template.css +++ b/administrator/templates/hathor/css/template.css @@ -1978,7 +1978,8 @@ fieldset.batch select, fieldset.batch input, fieldset.batch img, fieldset.batch float: left; } -label#batch-access-lbl { +label#batch-access-lbl, +label#batch-client-lbl { margin-right: 10px; } diff --git a/administrator/templates/hathor/css/template_rtl.css b/administrator/templates/hathor/css/template_rtl.css index 27c398cd2ca4f..0dc81236fb1aa 100644 --- a/administrator/templates/hathor/css/template_rtl.css +++ b/administrator/templates/hathor/css/template_rtl.css @@ -960,7 +960,8 @@ select#batch-position-id fieldset.batch select, fieldset.batch input, fieldset.batch img, fieldset.batch button { float: right; } -label#batch-access-lbl { +label#batch-access-lbl, +label#batch-client-lbl { margin-right: 0; margin-left: 10px; } From c7aacb78b0a8ac20e6850351e56eb8330b7bb469 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 2 Dec 2011 17:18:50 +0600 Subject: [PATCH 12/40] Remove published param --- .../components/com_banners/views/banners/tmpl/default_batch.php | 2 +- .../com_content/views/articles/tmpl/default_batch.php | 2 +- .../com_weblinks/views/weblinks/tmpl/default_batch.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_banners/views/banners/tmpl/default_batch.php b/administrator/components/com_banners/views/banners/tmpl/default_batch.php index 951cb9adf6e4d..b16936564883b 100644 --- a/administrator/components/com_banners/views/banners/tmpl/default_batch.php +++ b/administrator/components/com_banners/views/banners/tmpl/default_batch.php @@ -19,7 +19,7 @@ = 0) : ?> - + + +
diff --git a/administrator/language/en-GB/en-GB.com_contact.ini b/administrator/language/en-GB/en-GB.com_contact.ini index 40a5a879c2971..b5dd86161cb74 100644 --- a/administrator/language/en-GB/en-GB.com_contact.ini +++ b/administrator/language/en-GB/en-GB.com_contact.ini @@ -6,6 +6,9 @@ COM_CONTACT="Contacts" COM_CONTACT_BASIC_OPTIONS_FIELDSET_LABEL="Contact Display Options" +COM_CONTACT_BATCH_MENU_LABEL="Select Category for Move/Copy" +COM_CONTACT_BATCH_OPTIONS="Batch process the selected contacts" +COM_CONTACT_BATCH_TIP="If choosing to copy a contact, any other actions selected will be applied to the copied contact. Otherwise, all actions are applied to the selected contact." COM_CONTACT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of contact categories within a category." COM_CONTACT_CATEGORY_VIEW_DEFAULT_DESC="This view lists the contacts in a category." COM_CONTACT_CHANGE_CONTACT="Change Contact" diff --git a/administrator/templates/hathor/html/com_contact/contacts/default.php b/administrator/templates/hathor/html/com_contact/contacts/default.php index fb8445b4a97cd..b2401f4d415bc 100644 --- a/administrator/templates/hathor/html/com_contact/contacts/default.php +++ b/administrator/templates/hathor/html/com_contact/contacts/default.php @@ -189,6 +189,9 @@ + + loadTemplate('batch'); ?> + pagination->getListFooter(); ?> From 0877612fe256b3a2b48a80e2c5e41938628950eb Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 2 Dec 2011 17:35:26 +0600 Subject: [PATCH 14/40] Modify CategoriesControllerCategory::batch --- .../com_categories/controllers/category.php | 114 ++++++++++-------- 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/administrator/components/com_categories/controllers/category.php b/administrator/components/com_categories/controllers/category.php index 8c02b62c03e41..c570d2e8b38ab 100644 --- a/administrator/components/com_categories/controllers/category.php +++ b/administrator/components/com_categories/controllers/category.php @@ -1,8 +1,10 @@ extension)) { + if (empty($this->extension)) + { $this->extension = JRequest::getCmd('extension', 'com_content'); } } @@ -44,12 +50,11 @@ public function __construct($config = array()) /** * Method to check if you can add a new record. * - * Extended classes can override this if necessary. + * @param array $data An array of input data. * - * @param array An array of input data. + * @return boolean * - * @return boolean - * @since 1.6 + * @since 1.6 */ protected function allowAdd($data = array()) { @@ -59,41 +64,45 @@ protected function allowAdd($data = array()) /** * Method to check if you can edit a record. * - * Extended classes can override this if necessary. + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. * - * @param array An array of input data. - * @param string The name of the key for the primary key. + * @return boolean * - * @return boolean - * @since 1.6 + * @since 1.6 */ protected function allowEdit($data = array(), $key = 'parent_id') { // Initialise variables. - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - $user = JFactory::getUser(); - $userId = $user->get('id'); + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + $userId = $user->get('id'); // Check general edit permission first. - if ($user->authorise('core.edit', $this->extension)) { + if ($user->authorise('core.edit', $this->extension)) + { return true; } // Check specific edit permission. - if ($user->authorise('core.edit', $this->extension.'.category.'.$recordId)) { + if ($user->authorise('core.edit', $this->extension . '.category.' . $recordId)) + { return true; } // Fallback on edit.own. // First test if the permission is available. - if ($user->authorise('core.edit.own', $this->extension.'.category.'.$recordId) || $user->authorise('core.edit.own', $this->extension)) { + if ($user->authorise('core.edit.own', $this->extension . '.category.' . $recordId) || $user->authorise('core.edit.own', $this->extension)) + { // Now test the owner is the user. - $ownerId = (int) isset($data['created_user_id']) ? $data['created_user_id'] : 0; - if (empty($ownerId) && $recordId) { + $ownerId = (int) isset($data['created_user_id']) ? $data['created_user_id'] : 0; + if (empty($ownerId) && $recordId) + { // Need to do a lookup from the model. - $record = $this->getModel()->getItem($recordId); + $record = $this->getModel()->getItem($recordId); - if (empty($record)) { + if (empty($record)) + { return false; } @@ -101,32 +110,32 @@ protected function allowEdit($data = array(), $key = 'parent_id') } // If the owner matches 'me' then do the test. - if ($ownerId == $userId) { + if ($ownerId == $userId) + { return true; } } return false; - } + } /** - * Method to run batch opterations. + * Method to run batch operations. + * + * @param object $model The model. * - * @return void + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 1.6 */ - public function batch($model) + public function batch($model = null) { JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model - $model = $this->getModel('Category'); - - $extension = JRequest::getCmd('extension', ''); - if ($extension) { - $extension = '&extension='.$extension; - } + $model = $this->getModel('Category'); // Preset the redirect - $this->setRedirect('index.php?option=com_categories&view=categories'.$extension); + $this->setRedirect('index.php?option=com_categories&view=categories&extension=' . $this->extension); return parent::batch($model); } @@ -134,15 +143,17 @@ public function batch($model) /** * Gets the URL arguments to append to an item redirect. * - * @param int $recordId The primary key id for the item. + * @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 + * @return string The arguments to append to the redirect URL. + * + * @since 1.6 */ protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') { $append = parent::getRedirectToItemAppend($recordId); - $append .= '&extension='.$this->extension; + $append .= '&extension=' . $this->extension; return $append; } @@ -150,13 +161,14 @@ protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') /** * Gets the URL arguments to append to a list redirect. * - * @return string The arguments to append to the redirect URL. - * @since 1.6 + * @return string The arguments to append to the redirect URL. + * + * @since 1.6 */ protected function getRedirectToListAppend() { $append = parent::getRedirectToListAppend(); - $append .= '&extension='.$this->extension; + $append .= '&extension=' . $this->extension; return $append; } From ed17c90e8f9ea1fc7512e26114fdfc8017e25d16 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 2 Dec 2011 17:41:45 +0600 Subject: [PATCH 15/40] Default param for batch is null --- .../com_contact/controllers/contact.php | 2 +- .../views/contacts/tmpl/default_batch.php | 3 +- .../com_content/controllers/article.php | 93 ++++--- .../views/articles/tmpl/default_batch.php | 10 +- .../components/com_menus/controllers/item.php | 236 ++++++++++-------- .../com_weblinks/controllers/weblink.php | 69 +++-- 6 files changed, 238 insertions(+), 175 deletions(-) diff --git a/administrator/components/com_contact/controllers/contact.php b/administrator/components/com_contact/controllers/contact.php index c8a16ead4c095..30c8eab0503af 100644 --- a/administrator/components/com_contact/controllers/contact.php +++ b/administrator/components/com_contact/controllers/contact.php @@ -113,7 +113,7 @@ protected function allowEdit($data = array(), $key = 'id') * * @return boolean True if successful, false otherwise and internal error is set. * - * @since 1.6 + * @since 2.5 */ public function batch($model = null) { diff --git a/administrator/components/com_contact/views/contacts/tmpl/default_batch.php b/administrator/components/com_contact/views/contacts/tmpl/default_batch.php index e42f133248b35..925cedd04726b 100644 --- a/administrator/components/com_contact/views/contacts/tmpl/default_batch.php +++ b/administrator/components/com_contact/views/contacts/tmpl/default_batch.php @@ -9,8 +9,9 @@ // no direct access defined('_JEXEC') or die; -?> +$published = $this->state->get('filter.published'); +?>

diff --git a/administrator/components/com_content/controllers/article.php b/administrator/components/com_content/controllers/article.php index 2ee454a112aab..6a8ae1a3e82f2 100644 --- a/administrator/components/com_content/controllers/article.php +++ b/administrator/components/com_content/controllers/article.php @@ -1,10 +1,10 @@ view_list = 'featured'; $this->view_item = 'article&return=featured'; } @@ -42,28 +42,32 @@ function __construct($config = array()) /** * Method override to check if you can add a new record. * - * @param array An array of input data. + * @param array $data An array of input data. * - * @return boolean - * @since 1.6 + * @return boolean + * + * @since 1.6 */ protected function allowAdd($data = array()) { // Initialise variables. - $user = JFactory::getUser(); - $categoryId = JArrayHelper::getValue($data, 'catid', JRequest::getInt('filter_category_id'), 'int'); - $allow = null; + $user = JFactory::getUser(); + $categoryId = JArrayHelper::getValue($data, 'catid', JRequest::getInt('filter_category_id'), 'int'); + $allow = null; - if ($categoryId) { + if ($categoryId) + { // If the category has been passed in the data or URL check it. - $allow = $user->authorise('core.create', 'com_content.category.'.$categoryId); + $allow = $user->authorise('core.create', 'com_content.category.' . $categoryId); } - if ($allow === null) { + if ($allow === null) + { // In the absense of better information, revert to the component permissions. return parent::allowAdd(); } - else { + else + { return $allow; } } @@ -71,34 +75,39 @@ protected function allowAdd($data = array()) /** * 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. + * @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 + * @return boolean + * + * @since 1.6 */ protected function allowEdit($data = array(), $key = 'id') { // Initialise variables. - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - $user = JFactory::getUser(); - $userId = $user->get('id'); + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + $userId = $user->get('id'); // Check general edit permission first. - if ($user->authorise('core.edit', 'com_content.article.'.$recordId)) { + if ($user->authorise('core.edit', 'com_content.article.' . $recordId)) + { return true; } // Fallback on edit.own. // First test if the permission is available. - if ($user->authorise('core.edit.own', 'com_content.article.'.$recordId)) { + if ($user->authorise('core.edit.own', 'com_content.article.' . $recordId)) + { // Now test the owner is the user. - $ownerId = (int) isset($data['created_by']) ? $data['created_by'] : 0; - if (empty($ownerId) && $recordId) { + $ownerId = (int) isset($data['created_by']) ? $data['created_by'] : 0; + if (empty($ownerId) && $recordId) + { // Need to do a lookup from the model. - $record = $this->getModel()->getItem($recordId); + $record = $this->getModel()->getItem($recordId); - if (empty($record)) { + if (empty($record)) + { return false; } @@ -106,7 +115,8 @@ protected function allowEdit($data = array(), $key = 'id') } // If the owner matches 'me' then do the test. - if ($ownerId == $userId) { + if ($ownerId == $userId) + { return true; } } @@ -118,18 +128,21 @@ protected function allowEdit($data = array(), $key = 'id') /** * Method to run batch operations. * - * @return void - * @since 1.6 + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 1.6 */ - public function batch($model) + public function batch($model = null) { JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model - $model = $this->getModel('Article', '', array()); + $model = $this->getModel('Article', '', array()); // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_content&view=articles'.$this->getRedirectToListAppend(), false)); + $this->setRedirect(JRoute::_('index.php?option=com_content&view=articles' . $this->getRedirectToListAppend(), false)); return parent::batch($model); } diff --git a/administrator/components/com_content/views/articles/tmpl/default_batch.php b/administrator/components/com_content/views/articles/tmpl/default_batch.php index b7382bbbff110..ec0d4f5bc33a3 100644 --- a/administrator/components/com_content/views/articles/tmpl/default_batch.php +++ b/administrator/components/com_content/views/articles/tmpl/default_batch.php @@ -1,10 +1,10 @@ setUserState($context.'.type', null); - $app->setUserState($context.'.link', null); + if ($result) + { + $app->setUserState($context . '.type', null); + $app->setUserState($context . '.link', null); - $menuType = $app->getUserStateFromRequest($this->context.'.filter.menutype', 'menutype', 'mainmenu', 'cmd'); + $menuType = $app->getUserStateFromRequest($this->context . '.filter.menutype', 'menutype', 'mainmenu', 'cmd'); - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=item&menutype='.$menuType.$this->getRedirectToItemAppend(), false)); + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=item&menutype=' . $menuType . $this->getRedirectToItemAppend(), false)); } return $result; } /** - * Method to run batch opterations. + * Method to run batch operations. + * + * @param object $model The model. * - * @return void - * @since 1.6 + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 1.6 */ - public function batch($model) + public function batch($model = null) { JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Initialise variables. - $model = $this->getModel('Item', '', array()); + $model = $this->getModel('Item', '', array()); // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=items'.$this->getRedirectToListAppend(), false)); + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=items' . $this->getRedirectToListAppend(), false)); return parent::batch($model); } /** - * Method to cancel an edit + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable. * - * Checks the item in, sets item ID in the session to null, and then redirects to the list page. + * @return boolean True if access level checks pass, false otherwise. * - * @return void - * @since 1.6 + * @since 1.6 */ public function cancel($key = null) { JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Initialise variables. - $app = JFactory::getApplication(); - $context = 'com_menus.edit.item'; - $result = parent::cancel(); + $app = JFactory::getApplication(); + $context = 'com_menus.edit.item'; + $result = parent::cancel(); - if ($result) { + if ($result) + { // Clear the ancillary data from the session. - $app->setUserState($context.'.type', null); - $app->setUserState($context.'.link', null); + $app->setUserState($context . '.type', null); + $app->setUserState($context . '.link', null); } } /** - * Method to edit an existing menu item. + * Method to edit an existing 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 void - * @since 1.6 + * @return boolean True if access level check and checkout passes, false otherwise. + * + * @since 1.6 */ public function edit($key = null, $urlVar = null) { // Initialise variables. - $app = JFactory::getApplication(); - $result = parent::edit(); + $app = JFactory::getApplication(); + $result = parent::edit(); - if ($result) { + if ($result) + { // Push the new ancillary data into the session. - $app->setUserState('com_menus.edit.item.type', null); - $app->setUserState('com_menus.edit.item.link', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); } return true; } /** - * Method to save a menu item. + * 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. * - * @return void - * @since 1.6 + * @since 1.6 */ public function save($key = null, $urlVar = null) { @@ -119,18 +138,19 @@ public function save($key = null, $urlVar = null) JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Initialise variables. - $app = JFactory::getApplication(); - $model = $this->getModel('Item', '', array()); - $data = JRequest::getVar('jform', array(), 'post', 'array'); - $task = $this->getTask(); - $context = 'com_menus.edit.item'; - $recordId = JRequest::getInt('id'); - - if (!$this->checkEditId($context, $recordId)) { + $app = JFactory::getApplication(); + $model = $this->getModel('Item', '', array()); + $data = JRequest::getVar('jform', array(), 'post', 'array'); + $task = $this->getTask(); + $context = 'com_menus.edit.item'; + $recordId = JRequest::getInt('id'); + + if (!$this->checkEditId($context, $recordId)) + { // Somehow the person just went to the form and saved it - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $recordId)); $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=items'.$this->getRedirectToListAppend(), false)); + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=items' . $this->getRedirectToListAppend(), false)); return false; } @@ -139,24 +159,27 @@ public function save($key = null, $urlVar = null) $data['id'] = $recordId; // The save2copy task needs to be handled slightly differently. - if ($task == 'save2copy') { + if ($task == 'save2copy') + { // Check-in the original row. - if ($model->checkin($data['id']) === false) { + if ($model->checkin($data['id']) === false) + { // Check-in failed, go back to the item and display a notice. $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'warning'); return false; } // Reset the ID and then treat the request as for Apply. - $data['id'] = 0; + $data['id'] = 0; $data['associations'] = array(); - $task = 'apply'; + $task = 'apply'; } // Validate the posted data. // This post is made up of two forms, one for the item and one for params. $form = $model->getForm($data); - if (!$form) { + if (!$form) + { JError::raiseError(500, $model->getError()); return false; @@ -164,29 +187,33 @@ public function save($key = null, $urlVar = null) $data = $model->validate($form, $data); // Check for the special 'request' entry. - if ($data['type'] == 'component' && isset($data['request']) && is_array($data['request']) && !empty($data['request'])) { + if ($data['type'] == 'component' && isset($data['request']) && is_array($data['request']) && !empty($data['request'])) + { // Parse the submitted link arguments. $args = array(); parse_str(parse_url($data['link'], PHP_URL_QUERY), $args); // Merge in the user supplied request arguments. $args = array_merge($args, $data['request']); - $data['link'] = 'index.php?'.urldecode(http_build_query($args,'','&')); + $data['link'] = 'index.php?' . urldecode(http_build_query($args, '', '&')); unset($data['request']); } // Check for validation errors. - if ($data === false) { + if ($data === false) + { // Get the validation messages. - $errors = $model->getErrors(); + $errors = $model->getErrors(); // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { - if ($errors[$i] instanceof Exception) { + if ($errors[$i] instanceof Exception) + { $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); } - else { + else + { $app->enqueueMessage($errors[$i], 'warning'); } } @@ -195,28 +222,30 @@ public function save($key = null, $urlVar = null) $app->setUserState('com_menus.edit.item.data', $data); // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($recordId), false)); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false)); return false; } // Attempt to save the data. - if (!$model->save($data)) { + if (!$model->save($data)) + { // Save the data in the session. $app->setUserState('com_menus.edit.item.data', $data); // Redirect back to the edit screen. $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'warning'); - $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($recordId), false)); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false)); return false; } // Save succeeded, check-in the row. - if ($model->checkin($data['id']) === false) { + if ($model->checkin($data['id']) === false) + { // Check-in failed, go back to the row and display a notice. $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'warning'); - $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($recordId), false)); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false)); return false; } @@ -224,40 +253,41 @@ public function save($key = null, $urlVar = null) $this->setMessage(JText::_('COM_MENUS_SAVE_SUCCESS')); // Redirect the user and adjust session state based on the chosen task. - switch ($task) { + switch ($task) + { case 'apply': // Set the row data in the session. - $recordId = $model->getState($this->context.'.id'); + $recordId = $model->getState($this->context . '.id'); $this->holdEditId($context, $recordId); - $app->setUserState('com_menus.edit.item.data', null); - $app->setUserState('com_menus.edit.item.type', null); - $app->setUserState('com_menus.edit.item.link', null); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($recordId), false)); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false)); break; case 'save2new': // Clear the row id and data in the session. $this->releaseEditId($context, $recordId); - $app->setUserState('com_menus.edit.item.data', null); - $app->setUserState('com_menus.edit.item.type', null); - $app->setUserState('com_menus.edit.item.link', null); - $app->setUserState('com_menus.edit.item.menutype', $model->getState('item.menutype')); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); + $app->setUserState('com_menus.edit.item.menutype', $model->getState('item.menutype')); // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend(), false)); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(), false)); break; default: // Clear the row id and data in the session. $this->releaseEditId($context, $recordId); - $app->setUserState('com_menus.edit.item.data', null); - $app->setUserState('com_menus.edit.item.type', null); - $app->setUserState('com_menus.edit.item.link', null); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); // Redirect to the list screen. - $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_list.$this->getRedirectToListAppend(), false)); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); break; } } @@ -265,48 +295,52 @@ public function save($key = null, $urlVar = null) /** * Sets the type of the menu item currently being edited. * - * @return void - * @since 1.6 + * @return void + * + * @since 1.6 */ function setType() { // Initialise variables. - $app = JFactory::getApplication(); + $app = JFactory::getApplication(); // Get the posted values from the request. - $data = JRequest::getVar('jform', array(), 'post', 'array'); - $recordId = JRequest::getInt('id'); + $data = JRequest::getVar('jform', array(), 'post', 'array'); + $recordId = JRequest::getInt('id'); // Get the type. - $type = $data['type']; + $type = $data['type']; - $type = json_decode(base64_decode($type)); - $title = isset($type->title) ? $type->title : null; - $recordId = isset($type->id) ? $type->id : 0; + $type = json_decode(base64_decode($type)); + $title = isset($type->title) ? $type->title : null; + $recordId = isset($type->id) ? $type->id : 0; - if ($title != 'alias' && $title != 'separator' && $title != 'url') { + if ($title != 'alias' && $title != 'separator' && $title != 'url') + { $title = 'component'; } - $app->setUserState('com_menus.edit.item.type', $title); - if ($title == 'component') { - if (isset($type->request)) { + $app->setUserState('com_menus.edit.item.type', $title); + if ($title == 'component') + { + if (isset($type->request)) + { $component = JComponentHelper::getComponent($type->request->option); $data['component_id'] = $component->id; - $app->setUserState( - 'com_menus.edit.item.link', - 'index.php?' . JURI::buildQuery((array)$type->request)); + $app->setUserState('com_menus.edit.item.link', 'index.php?' . JURI::buildQuery((array) $type->request)); } } // If the type is alias you just need the item id from the menu item referenced. - elseif ($title == 'alias') { + elseif ($title == 'alias') + { $app->setUserState('com_menus.edit.item.link', 'index.php?Itemid='); } unset($data['request']); $data['type'] = $title; - if (JRequest::getCmd('fieldtype') == 'type') { + if (JRequest::getCmd('fieldtype') == 'type') + { $data['link'] = $app->getUserState('com_menus.edit.item.link'); } @@ -314,6 +348,6 @@ function setType() $app->setUserState('com_menus.edit.item.data', $data); $this->type = $type; - $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($recordId), false)); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false)); } } diff --git a/administrator/components/com_weblinks/controllers/weblink.php b/administrator/components/com_weblinks/controllers/weblink.php index a121078e61d62..4c12bb5ebd4f4 100644 --- a/administrator/components/com_weblinks/controllers/weblink.php +++ b/administrator/components/com_weblinks/controllers/weblink.php @@ -1,8 +1,10 @@ authorise('core.create', $this->option.'.category.'.$categoryId); + $allow = $user->authorise('core.create', $this->option . '.category.' . $categoryId); } - if ($allow === null) { + if ($allow === null) + { // In the absense of better information, revert to the component permissions. return parent::allowAdd($data); - } else { + } + else + { return $allow; } } @@ -49,26 +57,30 @@ protected function allowAdd($data = array()) /** * Method to check if you can add a new record. * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. + * @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 + * @return boolean + * @since 1.6 */ protected function allowEdit($data = array(), $key = 'id') { // Initialise variables. - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $categoryId = 0; - if ($recordId) { + if ($recordId) + { $categoryId = (int) $this->getModel()->getItem($recordId)->catid; } - if ($categoryId) { + if ($categoryId) + { // The category has been set. Check the category permissions. - return JFactory::getUser()->authorise('core.edit', $this->option.'.category.'.$categoryId); - } else { + return JFactory::getUser()->authorise('core.edit', $this->option . '.category.' . $categoryId); + } + else + { // Since there is no asset tracking, revert to the component permissions. return parent::allowEdit($data, $key); } @@ -77,18 +89,21 @@ protected function allowEdit($data = array(), $key = 'id') /** * Method to run batch operations. * - * @return void - * @since 1.7 + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 1.7 */ - public function batch($model) + public function batch($model = null) { JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model - $model = $this->getModel('Weblink', '', array()); + $model = $this->getModel('Weblink', '', array()); // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_weblinks&view=weblinks'.$this->getRedirectToListAppend(), false)); + $this->setRedirect(JRoute::_('index.php?option=com_weblinks&view=weblinks' . $this->getRedirectToListAppend(), false)); return parent::batch($model); } From 69e3c796cee1e84a89e8c6d94bef947a8300e0a9 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 2 Dec 2011 17:44:20 +0600 Subject: [PATCH 16/40] Default param for com_users batch --- .../components/com_users/controllers/user.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_users/controllers/user.php b/administrator/components/com_users/controllers/user.php index e7e57dea705bf..3e810cd60448f 100644 --- a/administrator/components/com_users/controllers/user.php +++ b/administrator/components/com_users/controllers/user.php @@ -57,19 +57,21 @@ protected function allowEdit($data = array(), $key = 'id') /** * Method to run batch operations. * + * @param object $model The model. + * * @return boolean True on success, false on failure * - * @since 1.7 + * @since 2.5 */ - public function batch() + public function batch($model = null) { JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model - $model = $this->getModel('User', '', array()); + $model = $this->getModel('User', '', array()); // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_users&view=users'.$this->getRedirectToListAppend(), false)); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=users' . $this->getRedirectToListAppend(), false)); return parent::batch($model); } From da17186a6d0f5a4b131b0c7ea43a5a90e6a850b4 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 2 Dec 2011 18:01:17 +0600 Subject: [PATCH 17/40] Work on user lists Add JHtmlUser to the libraries and moved the group selection list from com_users there. Added a userlist function to display a list of users (primary user will be com_contact to handle linked users). Added HTML to display the linked user field, but still needs processing code. --- .../views/contacts/tmpl/default_batch.php | 1 + .../com_users/helpers/html/index.html | 1 - .../com_users/helpers/html/user.php | 57 ------------------- .../com_users/views/users/tmpl/default.php | 3 - .../views/users/tmpl/default_batch.php | 2 - .../language/en-GB/en-GB.com_contact.ini | 1 + .../language/en-GB/en-GB.lib_joomla.ini | 4 ++ language/en-GB/en-GB.lib_joomla.ini | 4 ++ 8 files changed, 10 insertions(+), 63 deletions(-) delete mode 100644 administrator/components/com_users/helpers/html/index.html delete mode 100644 administrator/components/com_users/helpers/html/user.php diff --git a/administrator/components/com_contact/views/contacts/tmpl/default_batch.php b/administrator/components/com_contact/views/contacts/tmpl/default_batch.php index 925cedd04726b..0ae8bee1b195d 100644 --- a/administrator/components/com_contact/views/contacts/tmpl/default_batch.php +++ b/administrator/components/com_contact/views/contacts/tmpl/default_batch.php @@ -17,6 +17,7 @@

+ = 0) : ?> diff --git a/administrator/components/com_users/helpers/html/index.html b/administrator/components/com_users/helpers/html/index.html deleted file mode 100644 index 2efb97f319a35..0000000000000 --- a/administrator/components/com_users/helpers/html/index.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/administrator/components/com_users/helpers/html/user.php b/administrator/components/com_users/helpers/html/user.php deleted file mode 100644 index 09c5156e6d858..0000000000000 --- a/administrator/components/com_users/helpers/html/user.php +++ /dev/null @@ -1,57 +0,0 @@ -getQuery(true); - $query->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level'); - $query->from($db->quoteName('#__usergroups').' AS a'); - $query->join('LEFT', $db->quoteName('#__usergroups').' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); - $query->group('a.id'); - $query->order('a.lft ASC'); - $db->setQuery($query); - $options = $db->loadObjectList(); - - // Check for a database error. - if ($db->getErrorNum()) - { - JError::raiseNotice(500, $db->getErrorMsg()); - return null; - } - - for ($i = 0, $n = count($options); $i < $n; $i++) - { - $options[$i]->text = str_repeat('- ', $options[$i]->level).$options[$i]->text; - $groups[] = JHtml::_('select.option', $options[$i]->value, $options[$i]->text); - } - - return $groups; - } -} diff --git a/administrator/components/com_users/views/users/tmpl/default.php b/administrator/components/com_users/views/users/tmpl/default.php index ee613f8b3d25c..6417b7f7f9223 100755 --- a/administrator/components/com_users/views/users/tmpl/default.php +++ b/administrator/components/com_users/views/users/tmpl/default.php @@ -10,9 +10,6 @@ // No direct access. defined('_JEXEC') or die; -// Include the component HTML helpers. -JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); - // Load the tooltip behavior. JHtml::_('behavior.tooltip'); JHtml::_('behavior.multiselect'); diff --git a/administrator/components/com_users/views/users/tmpl/default_batch.php b/administrator/components/com_users/views/users/tmpl/default_batch.php index dd05b570dffb5..1fe4b95d32099 100644 --- a/administrator/components/com_users/views/users/tmpl/default_batch.php +++ b/administrator/components/com_users/views/users/tmpl/default_batch.php @@ -10,8 +10,6 @@ // no direct access defined('_JEXEC') or die; -JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); - // Create the copy/move options. $options = array( JHtml::_('select.option', 'add', JText::_('COM_USERS_BATCH_ADD')), diff --git a/administrator/language/en-GB/en-GB.com_contact.ini b/administrator/language/en-GB/en-GB.com_contact.ini index b5dd86161cb74..9cc3fcbb4f10f 100644 --- a/administrator/language/en-GB/en-GB.com_contact.ini +++ b/administrator/language/en-GB/en-GB.com_contact.ini @@ -272,4 +272,5 @@ COM_CONTACT_WARNING_SAME_NAME="The name of this contact is already used. Please COM_CONTACT_WARNING_SELECT_CONTACT_TOPUBLISH="Please select a contact to publish" COM_CONTACT_XML_DESCRIPTION="This component shows a listing of contact information" JGLOBAL_NEWITEMSLAST_DESC="New Contacts default to the last position. Ordering can be changed after this Contact is saved." +JLIB_HTML_BATCH_USER_LABEL="Set Linked User" JLIB_RULES_SETTING_NOTES="1. If you change the setting, it will apply to this component. Note that:
Inherited means that the permissions from global configuration and parent group will be used.
Denied means that no matter what the global configuration or parent group settings are, the group being edited cannot take this action on this component.
Allowed means that the group being edited will be able to take this action for this component (but if this is in conflict with the global configuration or parent group it will have no impact; a conflict will be indicated by Not Allowed (Locked) under Calculated Settings).
2. If you select a new setting, click Save to refresh the calculated settings." diff --git a/administrator/language/en-GB/en-GB.lib_joomla.ini b/administrator/language/en-GB/en-GB.lib_joomla.ini index d2e54344c81d1..922c7037778c6 100644 --- a/administrator/language/en-GB/en-GB.lib_joomla.ini +++ b/administrator/language/en-GB/en-GB.lib_joomla.ini @@ -319,6 +319,10 @@ JLIB_HTML_BATCH_LANGUAGE_NOCHANGE="- Keep original Language -" JLIB_HTML_BATCH_MENU_LABEL="Select Category for Move/Copy" JLIB_HTML_BATCH_MOVE="Move" JLIB_HTML_BATCH_NOCHANGE="- Keep original Access Levels -" +JLIB_HTML_BATCH_USER_LABEL="Set User" +JLIB_HTML_BATCH_USER_LABEL_DESC="Not making a selection will keep the original user when processing." +JLIB_HTML_BATCH_USER_NOCHANGE="- Keep original User -" +JLIB_HTML_BATCH_USER_NOUSER="No User" JLIB_HTML_BEHAVIOR_ABOUT_THE_CALENDAR="About the Calendar" JLIB_HTML_BEHAVIOR_CLOSE="Close" JLIB_HTML_BEHAVIOR_DATE_SELECTION="Date selection:\n" diff --git a/language/en-GB/en-GB.lib_joomla.ini b/language/en-GB/en-GB.lib_joomla.ini index d2e54344c81d1..922c7037778c6 100644 --- a/language/en-GB/en-GB.lib_joomla.ini +++ b/language/en-GB/en-GB.lib_joomla.ini @@ -319,6 +319,10 @@ JLIB_HTML_BATCH_LANGUAGE_NOCHANGE="- Keep original Language -" JLIB_HTML_BATCH_MENU_LABEL="Select Category for Move/Copy" JLIB_HTML_BATCH_MOVE="Move" JLIB_HTML_BATCH_NOCHANGE="- Keep original Access Levels -" +JLIB_HTML_BATCH_USER_LABEL="Set User" +JLIB_HTML_BATCH_USER_LABEL_DESC="Not making a selection will keep the original user when processing." +JLIB_HTML_BATCH_USER_NOCHANGE="- Keep original User -" +JLIB_HTML_BATCH_USER_NOUSER="No User" JLIB_HTML_BEHAVIOR_ABOUT_THE_CALENDAR="About the Calendar" JLIB_HTML_BEHAVIOR_CLOSE="Close" JLIB_HTML_BEHAVIOR_DATE_SELECTION="Date selection:\n" From 25bf5a4e2764b88ef0ed24319da43a3b50a10d56 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 2 Dec 2011 18:08:05 +0600 Subject: [PATCH 18/40] CSS for batch user select --- administrator/templates/bluestork/css/template.css | 6 ++++-- administrator/templates/bluestork/css/template_rtl.css | 6 ++++-- administrator/templates/hathor/css/template.css | 6 ++++-- administrator/templates/hathor/css/template_rtl.css | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/administrator/templates/bluestork/css/template.css b/administrator/templates/bluestork/css/template.css index 1ba9e682965d2..9cbc70fbd2fde 100644 --- a/administrator/templates/bluestork/css/template.css +++ b/administrator/templates/bluestork/css/template.css @@ -1048,12 +1048,14 @@ fieldset label#batch-choose-action-lbl { clear: left; margin-top: 15px; } -label#batch-language-lbl { +label#batch-language-lbl, +label#batch-user-lbl { clear: left; margin-right: 10px; margin-top: 15px; } -select#batch-language-id { +select#batch-language-id, +select#batch-user-id { margin-top: 15px; } select#batch-category-id, diff --git a/administrator/templates/bluestork/css/template_rtl.css b/administrator/templates/bluestork/css/template_rtl.css index d279ab139c0c5..6109816a6b46e 100644 --- a/administrator/templates/bluestork/css/template_rtl.css +++ b/administrator/templates/bluestork/css/template_rtl.css @@ -479,13 +479,15 @@ fieldset.batch label { fieldset label#batch-choose-action-lbl { clear: right; } -label#batch-language-lbl { +label#batch-language-lbl, +label#batch-user-lbl { clear: right; margin-left: 10px; margin-right: 0; margin-top: 15px; } -select#batch-language-id { +select#batch-language-id, +select#batch-user-id { margin-top: 15px; } select#batch-category-id, diff --git a/administrator/templates/hathor/css/template.css b/administrator/templates/hathor/css/template.css index 2579a869394e7..9f05aee292479 100644 --- a/administrator/templates/hathor/css/template.css +++ b/administrator/templates/hathor/css/template.css @@ -1961,12 +1961,14 @@ fieldset label#batch-choose-action-lbl { clear: left; margin-top: 15px; } -label#batch-language-lbl { +label#batch-language-lbl, +label#batch-user-lbl { clear: left; margin-right: 10px; margin-top: 15px; } -select#batch-language-id { +select#batch-language-id, +select#batch-user-id { margin-top: 15px; } select#batch-category-id, diff --git a/administrator/templates/hathor/css/template_rtl.css b/administrator/templates/hathor/css/template_rtl.css index 0dc81236fb1aa..c95e470f2ab6e 100644 --- a/administrator/templates/hathor/css/template_rtl.css +++ b/administrator/templates/hathor/css/template_rtl.css @@ -941,13 +941,15 @@ fieldset label#batch-choose-action-lbl { clear: none; clear: right; } -label#batch-language-lbl { +label#batch-language-lbl, +label#batch-user-lbl { clear: right; margin-left: 10px; margin-right: 0; margin-top: 15px; } -select#batch-language-id { +select#batch-language-id, +select#batch-user-id { margin-top: 15px; } select#batch-category-id, From cf85395fba24c34c2427b070388766e3c7f632ac Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 2 Dec 2011 18:23:44 +0600 Subject: [PATCH 19/40] Add logic to process linked user --- .../components/com_contact/models/contact.php | 140 ++++++++++++++++++ .../views/contacts/tmpl/default_batch.php | 2 +- 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_contact/models/contact.php b/administrator/components/com_contact/models/contact.php index c90a1ee91f0d7..e2a9d3cdaecfe 100644 --- a/administrator/components/com_contact/models/contact.php +++ b/administrator/components/com_contact/models/contact.php @@ -21,6 +21,146 @@ */ class ContactModelContact extends JModelAdmin { + /** + * 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 2.5 + */ + public function batch($commands, $pks, $contexts) + { + // Sanitize user 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; + + if (!empty($commands['category_id'])) + { + $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); + + if ($cmd == 'c') + { + $result = $this->batchCopy($commands['category_id'], $pks, $contexts); + if (is_array($result)) + { + $pks = $result; + } + else + { + return false; + } + } + elseif ($cmd == 'm' && !$this->batchMove($commands['category_id'], $pks, $contexts)) + { + return false; + } + $done = true; + } + + if (!empty($commands['assetgroup_id'])) + { + if (!$this->batchAccess($commands['assetgroup_id'], $pks, $contexts)) + { + return false; + } + + $done = true; + } + + if (!empty($commands['language_id'])) + { + if (!$this->batchLanguage($commands['language_id'], $pks, $contexts)) + { + return false; + } + + $done = true; + } + + if (strlen($commands['user_id']) > 0) + { + if (!$this->batchUser($commands['user_id'], $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 change a linked user. + * + * @param integer $value The new value matching a User 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 2.5 + */ + protected function batchUser($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $table = $this->getTable(); + + foreach ($pks as $pk) + { + if ($user->authorise('core.edit', $contexts[$pk])) + { + $table->reset(); + $table->load($pk); + $table->user_id = (int) $value; + + if (!$table->store()) + { + $this->setError($table->getError()); + return false; + } + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + /** * Method to test whether a record can be deleted. * diff --git a/administrator/components/com_contact/views/contacts/tmpl/default_batch.php b/administrator/components/com_contact/views/contacts/tmpl/default_batch.php index 0ae8bee1b195d..6dbda45847c01 100644 --- a/administrator/components/com_contact/views/contacts/tmpl/default_batch.php +++ b/administrator/components/com_contact/views/contacts/tmpl/default_batch.php @@ -26,7 +26,7 @@ -
From 64e6f1a8461f80b7ca7f241feaae6e57a943d761 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sat, 3 Dec 2011 18:57:51 +0600 Subject: [PATCH 20/40] Start logic for batch copy/move modules --- .../com_modules/helpers/html/modules.php | 3 +- .../components/com_modules/models/module.php | 175 +++++++++++++++++- .../language/en-GB/en-GB.com_modules.ini | 1 + 3 files changed, 175 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_modules/helpers/html/modules.php b/administrator/components/com_modules/helpers/html/modules.php index 37ae0e8ef9c0a..60eea00007288 100644 --- a/administrator/components/com_modules/helpers/html/modules.php +++ b/administrator/components/com_modules/helpers/html/modules.php @@ -129,7 +129,8 @@ public static function positions($clientId) '', '
', '', JHtml::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm'), diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index d974f49f60033..02778fc6480cd 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -72,12 +72,13 @@ protected function populateState() * * @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 1.7 */ - public function batch($commands, $pks) + public function batch($commands, $pks, $contexts) { // Sanitize user ids. $pks = array_unique($pks); @@ -97,9 +98,35 @@ public function batch($commands, $pks) $done = false; + if (!empty($commands['position_id'])) + { + $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); + + if ($commands['position_id'] != 'nochange') + { + if ($cmd == 'c') + { + $result = $this->batchCopy($commands['position_id'], $pks, $contexts); + if (is_array($result)) + { + $pks = $result; + } + else + { + return false; + } + } + elseif ($cmd == 'm' && !$this->batchMove($commands['position_id'], $pks, $contexts)) + { + return false; + } + $done = true; + } + } + if (!empty($commands['assetgroup_id'])) { - if (!$this->batchAccess($commands['assetgroup_id'], $pks)) + if (!$this->batchAccess($commands['assetgroup_id'], $pks, $contexts)) { return false; } @@ -109,7 +136,7 @@ public function batch($commands, $pks) if (!empty($commands['language_id'])) { - if (!$this->batchLanguage($commands['language_id'], $pks)) + if (!$this->batchLanguage($commands['language_id'], $pks, $contexts)) { return false; } @@ -129,6 +156,126 @@ public function batch($commands, $pks) return true; } + /** + * Batch copy modules to a new position or current. + * + * @param integer $value The new value matching a module position. + * @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 11.1 + */ + protected function batchCopy($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $table = $this->getTable(); + $i = 0; + + foreach ($pks as $pk) + { + if ($user->authorise('core.create', 'com_modules')) + { + $table->reset(); + $table->load($pk); + + // Set the new position + if ($value == 'noposition') + { + $value = ''; + } + $table->position = $value; + + // Alter the title if necessary + $data = $this->generateNewTitle($table->title, $table->position); + $table->title = $data['0']; + + // Reset the ID because we are making a copy + $table->id = 0; + + if (!$table->store()) + { + $this->setError($table->getError()); + return false; + } + + // Get the new item ID + $newId = $table->get('id'); + + // Add the new ID to the array + $newIds[$i] = $newId; + $i++; + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + + /** + * Batch move modules to a new position or current. + * + * @param integer $value The new value matching a module position. + * @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 11.1 + */ + protected function batchMove($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $table = $this->getTable(); + $i = 0; + + foreach ($pks as $pk) + { + if ($user->authorise('core.edit', 'com_modules')) + { + $table->reset(); + $table->load($pk); + + // Set the new position + if ($value == 'noposition') + { + $value = ''; + } + $table->position = $value; + + // Alter the title if necessary + $data = $this->generateNewTitle($table->title, $table->position); + $table->title = $data['0']; + + if (!$table->store()) + { + $this->setError($table->getError()); + return false; + } + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + /** * Method to delete rows. * @@ -280,6 +427,28 @@ public function duplicate(&$pks) return true; } + /** + * Method to change the title. + * + * @param string $title The title. + * @param string $position The position. + * + * @return array Contains the modified title. + * + * @since 2.5 + */ + protected function generateNewTitle($title, $position) + { + // Alter the title & alias + $table = $this->getTable(); + while ($table->load(array('position' => $position, 'title' => $title))) + { + $title = JString::increment($title); + } + + return array($title); + } + /** * Method to get the client object * diff --git a/administrator/language/en-GB/en-GB.com_modules.ini b/administrator/language/en-GB/en-GB.com_modules.ini index 62fddd968ddc4..f41b1074ab7dc 100644 --- a/administrator/language/en-GB/en-GB.com_modules.ini +++ b/administrator/language/en-GB/en-GB.com_modules.ini @@ -11,6 +11,7 @@ COM_MODULES_ASSIGNED_VARIES_ONLY="Selected only" COM_MODULES_BASIC_FIELDSET_LABEL="Basic Options" COM_MODULES_BATCH_POSITION_LABEL="Set Position" COM_MODULES_BATCH_POSITION_NOCHANGE="- Keep original Position -" +COM_MODULES_BATCH_POSITION_NOPOSITION="No Module Position" COM_MODULES_BATCH_OPTIONS="Batch process the selected modules" COM_MODULES_BATCH_TIP="If choosing to copy a module, any other actions selected will be applied to the copied module. Otherwise, all actions are applied to the selected module." COM_MODULES_CHANGE_POSITION_BUTTON="Select position" From 21f29717d90460c7a1cd482ac2696f34c77db6f2 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sat, 3 Dec 2011 19:04:02 +0600 Subject: [PATCH 21/40] Handle module assignments for copy --- .../components/com_modules/models/module.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index 02778fc6480cd..79b729f69e8c1 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -207,6 +207,26 @@ protected function batchCopy($value, $pks, $contexts) // Add the new ID to the array $newIds[$i] = $newId; $i++; + + // Now we need to handle the module assignments + $db = $this->getDbo(); + $query = $db->getQuery(true); + $query->select($db->quoteName('menuid')); + $query->from($db->quoteName('#__modules_menu')); + $query->where($db->quoteName('moduleid') . ' = ' . $pk); + $db->setQuery($query); + $menus = $db->loadColumn(); + + // Insert the new records into the table + foreach ($menus as $menu) + { + $query->clear(); + $query->insert($db->quoteName('#__modules_menu')); + $query->columns(array($db->quoteName('moduleid'), $db->quoteName('menuid'))); + $query->values($newId . ', ' . $menu); + $db->setQuery($query); + $db->query(); + } } else { From fa1000f1503cfc6526d2387047e4667e1e055f9d Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 5 Dec 2011 00:01:42 +0600 Subject: [PATCH 22/40] Add batch process to com_newsfeeds --- .../com_newsfeeds/controllers/newsfeed.php | 89 +++++++++++++------ .../views/newsfeeds/tmpl/default.php | 3 + .../views/newsfeeds/tmpl/default_batch.php | 31 +++++++ .../language/en-GB/en-GB.com_newsfeeds.ini | 3 + .../html/com_newsfeeds/newsfeeds/default.php | 3 + 5 files changed, 102 insertions(+), 27 deletions(-) create mode 100644 administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch.php diff --git a/administrator/components/com_newsfeeds/controllers/newsfeed.php b/administrator/components/com_newsfeeds/controllers/newsfeed.php index 03168d6cf763b..b6060c4f5df93 100644 --- a/administrator/components/com_newsfeeds/controllers/newsfeed.php +++ b/administrator/components/com_newsfeeds/controllers/newsfeed.php @@ -1,10 +1,13 @@ authorise('core.create', $this->option.'.category.'.$categoryId); + $allow = $user->authorise('core.create', $this->option . '.category.' . $categoryId); } - if ($allow === null) { - // In the absense of better information, revert to the component permissions. + if ($allow === null) + { + // In the absence of better information, revert to the component permissions. return parent::allowAdd($data); - } else { + } + else + { return $allow; } } @@ -50,29 +58,56 @@ protected function allowAdd($data = array()) /** * Method to check if you can edit a record. * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean * - * @return boolean - * @since 1.6 + * @since 1.6 */ protected function allowEdit($data = array(), $key = 'id') { // Initialise variables. - $user = JFactory::getUser(); - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $categoryId = 0; - if ($recordId) { + if ($recordId) + { $categoryId = (int) $this->getModel()->getItem($recordId)->catid; } - if ($categoryId) { + if ($categoryId) + { // The category has been set. Check the category permissions. - return $user->authorise('core.edit', $this->option.'.category.'.$categoryId); - } else { + return $user->authorise('core.edit', $this->option . '.category.' . $categoryId); + } + else + { // Since there is no asset tracking, revert to the component permissions. return parent::allowEdit($data, $key); } } + + /** + * 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) + { + JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Newsfeed', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_newsfeeds&view=newsfeeds' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } } diff --git a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php index e4ae5e1cd5c8f..45026305549fc 100644 --- a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php +++ b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php @@ -173,6 +173,9 @@ + + loadTemplate('batch'); ?> +
diff --git a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch.php b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch.php new file mode 100644 index 0000000000000..a3463784e4397 --- /dev/null +++ b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch.php @@ -0,0 +1,31 @@ +state->get('filter.published'); +?> +
+ +

+ + + + = 0) : ?> + + + + + +
diff --git a/administrator/language/en-GB/en-GB.com_newsfeeds.ini b/administrator/language/en-GB/en-GB.com_newsfeeds.ini index 77b1e95041cde..bb2323212b038 100644 --- a/administrator/language/en-GB/en-GB.com_newsfeeds.ini +++ b/administrator/language/en-GB/en-GB.com_newsfeeds.ini @@ -5,6 +5,9 @@ ; Note : All ini files need to be saved as UTF-8 COM_NEWSFEEDS="Newsfeeds" +COM_NEWSFEEDS_BATCH_MENU_LABEL="Select Category for Move/Copy" +COM_NEWSFEEDS_BATCH_OPTIONS="Batch process the selected newsfeeds" +COM_NEWSFEEDS_BATCH_TIP="If choosing to copy a newsfeed, any other actions selected will be applied to the copied newsfeed. Otherwise, all actions are applied to the selected newsfeed." COM_NEWSFEEDS_CACHE_TIME_HEADING="Cache Time" COM_NEWSFEEDS_CATEGORIES_DESC="These settings apply for Newsfeeds Categories Options unless they are changed for a specific menu item." COM_NEWSFEEDS_CHANGE_FEED_BUTTON="Select feed" diff --git a/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/default.php b/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/default.php index 552775b84c3e5..89441e632748c 100644 --- a/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/default.php +++ b/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/default.php @@ -184,6 +184,9 @@ + + loadTemplate('batch'); ?> + pagination->getListFooter(); ?> From eea828762ad0537037ad765fded10f68b9ec5d28 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 5 Dec 2011 03:49:48 +0600 Subject: [PATCH 23/40] Update permissions checks --- administrator/components/com_banners/models/banner.php | 6 +++++- administrator/components/com_modules/models/module.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_banners/models/banner.php b/administrator/components/com_banners/models/banner.php index a5dd5b4fe51cb..03a14c7617f18 100644 --- a/administrator/components/com_banners/models/banner.php +++ b/administrator/components/com_banners/models/banner.php @@ -132,7 +132,6 @@ protected function batchClient($value, $pks, $contexts) foreach ($pks as $pk) { - //TODO: Handle error reporting if user is not authorised if ($user->authorise('core.edit', $contexts[$pk])) { $table->reset(); @@ -145,6 +144,11 @@ protected function batchClient($value, $pks, $contexts) return false; } } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + return false; + } } // Clean the cache diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index 79b729f69e8c1..1b5f423ab2536 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -230,7 +230,7 @@ protected function batchCopy($value, $pks, $contexts) } else { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); return false; } } From e9706d78212710964d6fb9a2581ea58b6216572d Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 5 Dec 2011 17:25:23 +0600 Subject: [PATCH 24/40] Handle featured articles in batchCopy --- .../components/com_content/models/article.php | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/administrator/components/com_content/models/article.php b/administrator/components/com_content/models/article.php index 8c8ae73d49dd2..ddb1f80c9a240 100644 --- a/administrator/components/com_content/models/article.php +++ b/administrator/components/com_content/models/article.php @@ -29,6 +29,140 @@ class ContentModelArticle extends JModelAdmin */ protected $text_prefix = 'COM_CONTENT'; + /** + * Batch copy items to a new category or current. + * + * @param integer $value The new category. + * @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 11.1 + */ + protected function batchCopy($value, $pks, $contexts) + { + $categoryId = (int) $value; + + $table = $this->getTable(); + $i = 0; + + // Check that the category exists + if ($categoryId) + { + $categoryTable = JTable::getInstance('Category'); + if (!$categoryTable->load($categoryId)) + { + if ($error = $categoryTable->getError()) + { + // Fatal error + $this->setError($error); + return false; + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + return false; + } + } + } + + if (empty($categoryId)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + return false; + } + + // Check that the user has create permission for the component + $extension = JFactory::getApplication()->input->get('option', ''); + $user = JFactory::getUser(); + if (!$user->authorise('core.create', $extension . '.category.' . $categoryId)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + return false; + } + + // Parent exists so we let's proceed + while (!empty($pks)) + { + // Pop the first ID off the stack + $pk = array_shift($pks); + + $table->reset(); + + // Check that the row actually exists + if (!$table->load($pk)) + { + if ($error = $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; + } + } + + // Alter the title & alias + $data = $this->generateNewTitle($categoryId, $table->alias, $table->title); + $table->title = $data['0']; + $table->alias = $data['1']; + + // Reset the ID because we are making a copy + $table->id = 0; + + // New category ID + $table->catid = $categoryId; + + // TODO: Deal with ordering? + //$table->ordering = 1; + + // Get the featured state + $featured = $table->featured; + + // Check the row. + if (!$table->check()) + { + $this->setError($table->getError()); + return false; + } + + // Store the row. + if (!$table->store()) + { + $this->setError($table->getError()); + return false; + } + + // Get the new item ID + $newId = $table->get('id'); + + // Add the new ID to the array + $newIds[$i] = $newId; + $i++; + + // Check if the article was featured and update the #__content_frontpage table + if ($featured == 1) + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + $query->insert($db->quoteName('#__content_frontpage')); + $query->values($newId . ', 0'); + $db->setQuery($query); + $db->query(); + } + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + /** * Method to test whether a record can be deleted. * From bdc4ac36c64ae15527b5a58406d820f63c4f9d49 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 7 Dec 2011 18:37:48 +0600 Subject: [PATCH 25/40] Edit query --- administrator/components/com_users/models/user.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/administrator/components/com_users/models/user.php b/administrator/components/com_users/models/user.php index 5a57acf0730a6..79fc5572f8578 100644 --- a/administrator/components/com_users/models/user.php +++ b/administrator/components/com_users/models/user.php @@ -560,11 +560,10 @@ public function batch($config, $user_ids) $groups[] = '('.$id.','.$group_id.')'; } - $this->_db->setQuery( - 'INSERT INTO '.$this->_db->nameQuote('#__user_usergroup_map').' ('. - $this->_db->nameQuote('user_id').', '.$this->_db->nameQuote('group_id').')' . - ' VALUES '.implode(',', $groups) - ); + $query->insert($this->_db->quoteName('#__user_usergroup_map')); + $query->columns(array($this->_db->quoteName('user_id'), $this->_db->nameQuote('group_id'))); + $query->values(implode(',', $groups)); + $this->_db->setQuery($query); // Check for database errors. if (!$db->query()) From d570ab2f1b99d32e459e24e6d13e8ddc7839c09b Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sun, 18 Dec 2011 23:59:35 -0500 Subject: [PATCH 26/40] Extend batchCopy into BannersModelBanner --- .../components/com_banners/models/banner.php | 127 +++++++++++++++++- 1 file changed, 123 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_banners/models/banner.php b/administrator/components/com_banners/models/banner.php index 03a14c7617f18..6e133b37db767 100644 --- a/administrator/components/com_banners/models/banner.php +++ b/administrator/components/com_banners/models/banner.php @@ -114,11 +114,11 @@ public function batch($commands, $pks, $contexts) } /** - * Batch language changes for a group of rows. + * Batch client changes for a group of banners. * - * @param string $value The new value matching a language. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. + * @param string $value The new value matching a client. + * @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. * @@ -157,6 +157,125 @@ protected function batchClient($value, $pks, $contexts) return true; } + /** + * Batch copy items to a new category or current. + * + * @param integer $value The new category. + * @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 2.5 + */ + protected function batchCopy($value, $pks, $contexts) + { + $categoryId = (int) $value; + + $table = $this->getTable(); + $i = 0; + + // Check that the category exists + if ($categoryId) + { + $categoryTable = JTable::getInstance('Category'); + if (!$categoryTable->load($categoryId)) + { + if ($error = $categoryTable->getError()) + { + // Fatal error + $this->setError($error); + return false; + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + return false; + } + } + } + + if (empty($categoryId)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + return false; + } + + // Check that the user has create permission for the component + $user = JFactory::getUser(); + if (!$user->authorise('core.create', 'com_banners.category.' . $categoryId)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + return false; + } + + // Parent exists so we let's proceed + while (!empty($pks)) + { + // Pop the first ID off the stack + $pk = array_shift($pks); + + $table->reset(); + + // Check that the row actually exists + if (!$table->load($pk)) + { + if ($error = $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; + } + } + + // Alter the title & alias + $data = $this->generateNewTitle($categoryId, $table->alias, $table->name); + $table->name = $data['0']; + $table->alias = $data['1']; + + // Reset the ID because we are making a copy + $table->id = 0; + + // New category ID + $table->catid = $categoryId; + + // TODO: Deal with ordering? + //$table->ordering = 1; + + // Check the row. + if (!$table->check()) + { + $this->setError($table->getError()); + return false; + } + + // Store the row. + if (!$table->store()) + { + $this->setError($table->getError()); + return false; + } + + // Get the new item ID + $newId = $table->get('id'); + + // Add the new ID to the array + $newIds[$i] = $newId; + $i++; + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + /** * Method to test whether a record can be deleted. * From 2215097aa46cfa77394b2e2d9a36bdb1ba80fbc1 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 19 Dec 2011 13:03:01 -0500 Subject: [PATCH 27/40] Fix method declarations to match parent --- .../components/com_categories/models/category.php | 14 ++++++++------ administrator/components/com_menus/models/item.php | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/administrator/components/com_categories/models/category.php b/administrator/components/com_categories/models/category.php index a08b3ee27898c..7907f7f03f60d 100644 --- a/administrator/components/com_categories/models/category.php +++ b/administrator/components/com_categories/models/category.php @@ -512,14 +512,15 @@ public function saveorder($idArray = null, $lft_array = null) /** * Batch copy categories to a new category. * - * @param integer $value The new category or sub-item. - * @param array $pks An array of row IDs. + * @param integer $value The new category. + * @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 1.6 */ - protected function batchCopy($value, $pks) + protected function batchCopy($value, $pks, $contexts) { // $value comes as {parent_id}.{extension} $parts = explode('.', $value); @@ -699,14 +700,15 @@ protected function batchCopy($value, $pks) /** * Batch move categories to a new category. * - * @param integer $value The new category or sub-item. - * @param array $pks An array of row IDs. + * @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 on success. * * @since 1.6 */ - protected function batchMove($value, $pks) + protected function batchMove($value, $pks, $contexts) { $parentId = (int) $value; diff --git a/administrator/components/com_menus/models/item.php b/administrator/components/com_menus/models/item.php index 1ba19317665be..12d3bea85629a 100644 --- a/administrator/components/com_menus/models/item.php +++ b/administrator/components/com_menus/models/item.php @@ -177,14 +177,15 @@ function batch($commands, $pks, $contexts) /** * Batch copy menu items to a new menu or parent. * - * @param integer $value The new menu or sub-item. - * @param array $pks An array of row IDs. + * @param integer $value The new menu or sub-item. + * @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 1.6 */ - protected function batchCopy($value, $pks) + protected function batchCopy($value, $pks, $contexts) { // $value comes as {menutype}.{parent_id} $parts = explode('.', $value); @@ -367,14 +368,15 @@ protected function batchCopy($value, $pks) /** * Batch move menu items to a new menu or parent. * - * @param integer $value The new menu or sub-item. - * @param array $pks An array of row IDs. + * @param integer $value The new menu or sub-item. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. * * @return boolean True on success. * * @since 1.6 */ - protected function batchMove($value, $pks) + protected function batchMove($value, $pks, $contexts) { // $value comes as {menutype}.{parent_id} $parts = explode('.', $value); From 81b191897f09f2645510a7ed714069a21e33016a Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 19 Dec 2011 22:34:48 -0500 Subject: [PATCH 28/40] Restore HTML helpers declaration --- administrator/components/com_users/views/users/view.html.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/administrator/components/com_users/views/users/view.html.php b/administrator/components/com_users/views/users/view.html.php index 18d0d99400d11..da565b0e4155d 100644 --- a/administrator/components/com_users/views/users/view.html.php +++ b/administrator/components/com_users/views/users/view.html.php @@ -38,6 +38,9 @@ public function display($tpl = null) return false; } + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + $this->addToolbar(); parent::display($tpl); } From 2ff5084e7db818ed02b9fb082873cc8eea22b174 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 21 Dec 2011 16:22:42 -0500 Subject: [PATCH 29/40] Improve copy/move check for com_modules --- administrator/components/com_modules/models/module.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index 4ab69355d643d..fc6527f38a0e9 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -102,7 +102,7 @@ public function batch($commands, $pks, $contexts) { $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); - if ($commands['position_id'] != 'nochange') + if (!empty($commands['position_id'])) { if ($cmd == 'c') { @@ -186,6 +186,10 @@ protected function batchCopy($value, $pks, $contexts) { $value = ''; } + elseif ($value == 'nochange') + { + $value = $table->position; + } $table->position = $value; // Alter the title if necessary @@ -271,6 +275,10 @@ protected function batchMove($value, $pks, $contexts) { $value = ''; } + elseif ($value == 'nochange') + { + $value = $table->position; + } $table->position = $value; // Alter the title if necessary From 915de1c018a751fb8ec2dcbe0b01b9ea16ee1c63 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 23 Dec 2011 14:10:14 -0500 Subject: [PATCH 30/40] Refactor com_users batch to match other uses --- .../components/com_users/models/user.php | 194 +++++++++++------- 1 file changed, 118 insertions(+), 76 deletions(-) diff --git a/administrator/components/com_users/models/user.php b/administrator/components/com_users/models/user.php index 79fc5572f8578..0a277fbf0fa6f 100644 --- a/administrator/components/com_users/models/user.php +++ b/administrator/components/com_users/models/user.php @@ -469,108 +469,150 @@ function activate(&$pks) } /** - * Perform batch operations + * Method to perform batch operations on an item or a set of items. * - * @param array $config An array of variable for the batch operation - * @param array $user_ids An array of IDs on which to operate + * @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 True on success, false on failure + * @return boolean Returns true on success, false on failure. * - * @since 1.6 + * @since 2.5 */ - public function batch($config, $user_ids) + public function batch($commands, $pks, $contexts) { - // Ensure there are selected users to operate on. - if (empty($user_ids)) + // Sanitize user 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::_('COM_USERS_USERS_NO_ITEM_SELECTED')); return false; } - elseif (!empty($config)) - { - // Get the DB object - $db = $this->getDbo(); - // Only run operations if a config array is present. - // Ensure there is a valid group. - $group_id = JArrayHelper::getValue($config, 'group_id', 0, 'int'); - JArrayHelper::toInteger($user_ids); + $done = false; + + if (!empty($commands['group_id'])) + { + $cmd = JArrayHelper::getValue($commands, 'group_action', 'add'); - if ($group_id < 1) + if (!$this->batchUser((int) $commands['group_id'], $pks, $cmd)) { - $this->setError(JText::_('COM_USERS_ERROR_INVALID_GROUP')); return false; } + $done = true; + } - $groupAction = JArrayHelper::getValue($config, 'group_action'); - switch ($groupAction) - { - // Sets users to a selected group - case 'set': - $doDelete = 'all'; - $doAssign = true; - break; - - // Remove users from a selected group - case 'del': - $doDelete = 'group'; - break; - - // Add users to a selected group - case 'add': - default: - $doAssign = true; - break; - } + if (!$done) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + return false; + } - // Remove the users from the group if requested. - if (isset($doDelete)) - { - $query = $db->getQuery(true); + // Clear the cache + $this->cleanCache(); - // Remove users from the group - $query->delete($db->quoteName('#__user_usergroup_map')); - $query->where($db->quoteName('user_id').' IN ('.implode(',', $user_ids).')'); + return true; + } - // Only remove users from selected group - if ($doDelete == 'group') - { - $query->where($db->quoteName('group_id').' = '.$group_id); - } + /** + * Perform batch operations + * + * @param integer $group_id The group ID which assignments are being edited + * @param array $user_ids An array of user IDs on which to operate + * @param string $action The action to perform + * + * @return boolean True on success, false on failure + * + * @since 1.6 + */ + public function batchUser($group_id, $user_ids, $action) + { + // Get the DB object + $db = $this->getDbo(); - $db->setQuery($query); + JArrayHelper::toInteger($user_ids); - // Check for database errors. - if (!$db->query()) - { - $this->setError($db->getErrorMsg()); - return false; - } + if ($group_id < 1) + { + $this->setError(JText::_('COM_USERS_ERROR_INVALID_GROUP')); + return false; + } + + switch ($action) + { + // Sets users to a selected group + case 'set': + $doDelete = 'all'; + $doAssign = true; + break; + + // Remove users from a selected group + case 'del': + $doDelete = 'group'; + break; + + // Add users to a selected group + case 'add': + default: + $doAssign = true; + break; + } + + // Remove the users from the group if requested. + if (isset($doDelete)) + { + $query = $db->getQuery(true); + + // Remove users from the group + $query->delete($db->quoteName('#__user_usergroup_map')); + $query->where($db->quoteName('user_id').' IN ('.implode(',', $user_ids).')'); + + // Only remove users from selected group + if ($doDelete == 'group') + { + $query->where($db->quoteName('group_id').' = '.$group_id); } - // Assign the users to the group if requested. - if (isset($doAssign)) + $db->setQuery($query); + + // Check for database errors. + if (!$db->query()) { - $query = $db->getQuery(true); + $this->setError($db->getErrorMsg()); + return false; + } + } - // Build the groups array for the assignment query. - $groups = array(); - foreach ($user_ids as $id) - { - $groups[] = '('.$id.','.$group_id.')'; - } + // Assign the users to the group if requested. + if (isset($doAssign)) + { + $query = $db->getQuery(true); - $query->insert($this->_db->quoteName('#__user_usergroup_map')); - $query->columns(array($this->_db->quoteName('user_id'), $this->_db->nameQuote('group_id'))); - $query->values(implode(',', $groups)); - $this->_db->setQuery($query); + // Build the groups array for the assignment query. + $groups = array(); + foreach ($user_ids as $id) + { + $groups[] = $id.','.$group_id; + } - // Check for database errors. - if (!$db->query()) - { - $this->setError($db->getErrorMsg()); - return false; - } + $query->insert($db->quoteName('#__user_usergroup_map')); + $query->columns(array($db->quoteName('user_id'), $db->nameQuote('group_id'))); + $query->values(implode(',', $groups)); + $db->setQuery($query); + + // Check for database errors. + if (!$db->query()) + { + $this->setError($db->getErrorMsg()); + return false; } } From fd6d71fb40954a7a9b28e48ae42c5125385cff11 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sun, 25 Dec 2011 09:54:48 -0500 Subject: [PATCH 31/40] Fix usergroup selection --- libraries/joomla/html/html/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/joomla/html/html/user.php b/libraries/joomla/html/html/user.php index 54c2acdd64d09..f55379137e84e 100644 --- a/libraries/joomla/html/html/user.php +++ b/libraries/joomla/html/html/user.php @@ -32,7 +32,7 @@ public static function groups() $query->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level'); $query->from($db->quoteName('#__usergroups') . ' AS a'); $query->join('LEFT', $db->quoteName('#__usergroups') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); - $query->group('a.id, a.title, a.lft, b.lft, a.rgt'); + $query->group('a.id, a.title, a.lft, a.rgt'); $query->order('a.lft ASC'); $db->setQuery($query); $options = $db->loadObjectList(); From afa032cb9372ac32b7001768ac50896abe9ffbf2 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Tue, 27 Dec 2011 10:04:48 -0500 Subject: [PATCH 32/40] Unpublish on copy/move --- administrator/components/com_modules/models/module.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index fc6527f38a0e9..f95b3e824a907 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -199,6 +199,9 @@ protected function batchCopy($value, $pks, $contexts) // Reset the ID because we are making a copy $table->id = 0; + // Unpublish the new module + $table->published = 0; + if (!$table->store()) { $this->setError($table->getError()); @@ -285,6 +288,9 @@ protected function batchMove($value, $pks, $contexts) $data = $this->generateNewTitle($table->title, $table->position); $table->title = $data['0']; + // Unpublish the moved module + $table->published = 0; + if (!$table->store()) { $this->setError($table->getError()); From 6461fad633202fcfd53275cc3c54fa14b49f9e3f Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Tue, 27 Dec 2011 10:23:03 -0500 Subject: [PATCH 33/40] Fix position issue for multiple modules in copy/move --- .../components/com_modules/models/module.php | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index f95b3e824a907..4e60bea7f5ddb 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -184,13 +184,17 @@ protected function batchCopy($value, $pks, $contexts) // Set the new position if ($value == 'noposition') { - $value = ''; + $position = ''; } elseif ($value == 'nochange') { - $value = $table->position; + $position = $table->position; } - $table->position = $value; + else + { + $position = $value; + } + $table->position = $position; // Alter the title if necessary $data = $this->generateNewTitle($table->title, $table->position); @@ -276,13 +280,17 @@ protected function batchMove($value, $pks, $contexts) // Set the new position if ($value == 'noposition') { - $value = ''; + $position = ''; } elseif ($value == 'nochange') { - $value = $table->position; + $position = $table->position; + } + else + { + $position = $value; } - $table->position = $value; + $table->position = $position; // Alter the title if necessary $data = $this->generateNewTitle($table->title, $table->position); From 2dcd64e2b325eba56480394ed10f41848a168779 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sat, 31 Dec 2011 12:10:10 -0500 Subject: [PATCH 34/40] Fix com_contact batchCopy --- .../components/com_contact/models/contact.php | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/administrator/components/com_contact/models/contact.php b/administrator/components/com_contact/models/contact.php index 955ae874a04b8..a22b9c50800e3 100644 --- a/administrator/components/com_contact/models/contact.php +++ b/administrator/components/com_contact/models/contact.php @@ -117,6 +117,125 @@ public function batch($commands, $pks, $contexts) return true; } + /** + * Batch copy items to a new category or current. + * + * @param integer $value The new category. + * @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 11.1 + */ + protected function batchCopy($value, $pks, $contexts) + { + $categoryId = (int) $value; + + $table = $this->getTable(); + $i = 0; + + // Check that the category exists + if ($categoryId) + { + $categoryTable = JTable::getInstance('Category'); + if (!$categoryTable->load($categoryId)) + { + if ($error = $categoryTable->getError()) + { + // Fatal error + $this->setError($error); + return false; + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + return false; + } + } + } + + if (empty($categoryId)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + return false; + } + + // Check that the user has create permission for the component + $user = JFactory::getUser(); + if (!$user->authorise('core.create', 'com_contact.category.' . $categoryId)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + return false; + } + + // Parent exists so we let's proceed + while (!empty($pks)) + { + // Pop the first ID off the stack + $pk = array_shift($pks); + + $table->reset(); + + // Check that the row actually exists + if (!$table->load($pk)) + { + if ($error = $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; + } + } + + // Alter the title & alias + $data = $this->generateNewTitle($categoryId, $table->alias, $table->name); + $table->name = $data['0']; + $table->alias = $data['1']; + + // Reset the ID because we are making a copy + $table->id = 0; + + // New category ID + $table->catid = $categoryId; + + // TODO: Deal with ordering? + //$table->ordering = 1; + + // Check the row. + if (!$table->check()) + { + $this->setError($table->getError()); + return false; + } + + // Store the row. + if (!$table->store()) + { + $this->setError($table->getError()); + return false; + } + + // Get the new item ID + $newId = $table->get('id'); + + // Add the new ID to the array + $newIds[$i] = $newId; + $i++; + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + /** * Batch change a linked user. * From 2ee4a737d9fb60c31d3a530fb3e2d14fae14b203 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sat, 31 Dec 2011 12:10:52 -0500 Subject: [PATCH 35/40] Fix com_newsfeeds batchCopy --- .../com_newsfeeds/models/newsfeed.php | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/administrator/components/com_newsfeeds/models/newsfeed.php b/administrator/components/com_newsfeeds/models/newsfeed.php index a9167b88972e2..f1f9571994363 100644 --- a/administrator/components/com_newsfeeds/models/newsfeed.php +++ b/administrator/components/com_newsfeeds/models/newsfeed.php @@ -25,6 +25,125 @@ class NewsfeedsModelNewsfeed extends JModelAdmin */ protected $text_prefix = 'COM_NEWSFEEDS'; + /** + * Batch copy items to a new category or current. + * + * @param integer $value The new category. + * @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 11.1 + */ + protected function batchCopy($value, $pks, $contexts) + { + $categoryId = (int) $value; + + $table = $this->getTable(); + $i = 0; + + // Check that the category exists + if ($categoryId) + { + $categoryTable = JTable::getInstance('Category'); + if (!$categoryTable->load($categoryId)) + { + if ($error = $categoryTable->getError()) + { + // Fatal error + $this->setError($error); + return false; + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + return false; + } + } + } + + if (empty($categoryId)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + return false; + } + + // Check that the user has create permission for the component + $user = JFactory::getUser(); + if (!$user->authorise('core.create', 'com_newsfeeds.category.' . $categoryId)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + return false; + } + + // Parent exists so we let's proceed + while (!empty($pks)) + { + // Pop the first ID off the stack + $pk = array_shift($pks); + + $table->reset(); + + // Check that the row actually exists + if (!$table->load($pk)) + { + if ($error = $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; + } + } + + // Alter the title & alias + $data = $this->generateNewTitle($categoryId, $table->alias, $table->name); + $table->name = $data['0']; + $table->alias = $data['1']; + + // Reset the ID because we are making a copy + $table->id = 0; + + // New category ID + $table->catid = $categoryId; + + // TODO: Deal with ordering? + //$table->ordering = 1; + + // Check the row. + if (!$table->check()) + { + $this->setError($table->getError()); + return false; + } + + // Store the row. + if (!$table->store()) + { + $this->setError($table->getError()); + return false; + } + + // Get the new item ID + $newId = $table->get('id'); + + // Add the new ID to the array + $newIds[$i] = $newId; + $i++; + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + /** * Method to test whether a record can be deleted. * From 5d7b8dc50bcdee3672654683ebe469b081a9c56e Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sat, 31 Dec 2011 12:25:41 -0500 Subject: [PATCH 36/40] Add check in batchUser for unique assignment --- .../components/com_users/models/user.php | 26 ++++++++++++++++--- .../language/en-GB/en-GB.com_users.ini | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_users/models/user.php b/administrator/components/com_users/models/user.php index 4692ea717f7d9..1f0726312aa20 100644 --- a/administrator/components/com_users/models/user.php +++ b/administrator/components/com_users/models/user.php @@ -571,12 +571,12 @@ public function batchUser($group_id, $user_ids, $action) // Remove users from the group $query->delete($db->quoteName('#__user_usergroup_map')); - $query->where($db->quoteName('user_id').' IN ('.implode(',', $user_ids).')'); + $query->where($db->quoteName('user_id') . ' IN (' . implode(',', $user_ids) . ')'); // Only remove users from selected group if ($doDelete == 'group') { - $query->where($db->quoteName('group_id').' = '.$group_id); + $query->where($db->quoteName('group_id') . ' = ' . (int) $group_id); } $db->setQuery($query); @@ -594,15 +594,33 @@ public function batchUser($group_id, $user_ids, $action) { $query = $db->getQuery(true); + // First, we need to check if the user is already assigned to a group + $query->select($db->quoteName('user_id')); + $query->from($db->quoteName('#__user_usergroup_map')); + $query->where($db->quoteName('group_id') . ' = ' . (int) $group_id); + $db->setQuery($query); + $users = $db->loadColumn(); + // Build the groups array for the assignment query. $groups = array(); foreach ($user_ids as $id) { - $groups[] = $id.','.$group_id; + if (!in_array($id, $users)) + { + $groups[] = $id . ',' . $group_id; + } + } + + // If we have no users to process, throw an error to notify the user + if (empty($groups)) + { + $this->setError(JText::_('COM_USERS_ERROR_NO_ADDITIONS')); + return false; } + $query->clear(); $query->insert($db->quoteName('#__user_usergroup_map')); - $query->columns(array($db->quoteName('user_id'), $db->nameQuote('group_id'))); + $query->columns(array($db->quoteName('user_id'), $db->quoteName('group_id'))); $query->values(implode(',', $groups)); $db->setQuery($query); diff --git a/administrator/language/en-GB/en-GB.com_users.ini b/administrator/language/en-GB/en-GB.com_users.ini index 9023338d0eaba..15925aa6a0cb3 100644 --- a/administrator/language/en-GB/en-GB.com_users.ini +++ b/administrator/language/en-GB/en-GB.com_users.ini @@ -62,6 +62,7 @@ COM_USERS_EMPTY_REVIEW="-" COM_USERS_EMPTY_SUBJECT="- No subject -" COM_USERS_ERROR_INVALID_GROUP="Invalid Group" COM_USERS_ERROR_LEVELS_NOLEVELS_SELECTED="No View Permission Level(s) selected." +COM_USERS_ERROR_NO_ADDITIONS="The selected user(s) are already assigned to the selected group." COM_USERS_ERROR_VIEW_LEVEL_IN_USE="You cannot delete the view access level '%d:%s' because it is being used by content." COM_USERS_FIELD_CATEGORY_ID_LABEL="Category" COM_USERS_FIELD_ID_LABEL="ID" From f29aa82565aef627c15322569a7a7ae5555b032b Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 2 Jan 2012 00:41:06 -0500 Subject: [PATCH 37/40] Add return to com_users batch --- administrator/components/com_users/models/user.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/administrator/components/com_users/models/user.php b/administrator/components/com_users/models/user.php index 1f0726312aa20..c84fb37ca9340 100644 --- a/administrator/components/com_users/models/user.php +++ b/administrator/components/com_users/models/user.php @@ -518,6 +518,8 @@ public function batch($commands, $pks, $contexts) // Clear the cache $this->cleanCache(); + + return true; } /** From d97df218dbc6ceb3cb1d25e3f5c24caa8d394c45 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 2 Jan 2012 00:46:56 -0500 Subject: [PATCH 38/40] Fix modules batch processing --- .../components/com_modules/helpers/html/modules.php | 2 +- administrator/components/com_modules/models/module.php | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/administrator/components/com_modules/helpers/html/modules.php b/administrator/components/com_modules/helpers/html/modules.php index 60eea00007288..f43d8c31a7262 100644 --- a/administrator/components/com_modules/helpers/html/modules.php +++ b/administrator/components/com_modules/helpers/html/modules.php @@ -129,7 +129,7 @@ public static function positions($clientId) '', '
', '', diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index 4e60bea7f5ddb..f32d4b2c52719 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -186,10 +186,6 @@ protected function batchCopy($value, $pks, $contexts) { $position = ''; } - elseif ($value == 'nochange') - { - $position = $table->position; - } else { $position = $value; @@ -282,10 +278,6 @@ protected function batchMove($value, $pks, $contexts) { $position = ''; } - elseif ($value == 'nochange') - { - $position = $table->position; - } else { $position = $value; From 3479f9cbff8ee412f557c16ed033b311f34278cc Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 2 Jan 2012 12:44:37 -0500 Subject: [PATCH 39/40] Final fix for modules --- .../components/com_modules/helpers/html/modules.php | 5 +++-- administrator/components/com_modules/models/module.php | 8 ++++++++ administrator/language/en-GB/en-GB.com_modules.ini | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_modules/helpers/html/modules.php b/administrator/components/com_modules/helpers/html/modules.php index f43d8c31a7262..dfda68206bb1b 100644 --- a/administrator/components/com_modules/helpers/html/modules.php +++ b/administrator/components/com_modules/helpers/html/modules.php @@ -129,8 +129,9 @@ public static function positions($clientId) '', '
', '', JHtml::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm'), diff --git a/administrator/components/com_modules/models/module.php b/administrator/components/com_modules/models/module.php index f32d4b2c52719..4e60bea7f5ddb 100644 --- a/administrator/components/com_modules/models/module.php +++ b/administrator/components/com_modules/models/module.php @@ -186,6 +186,10 @@ protected function batchCopy($value, $pks, $contexts) { $position = ''; } + elseif ($value == 'nochange') + { + $position = $table->position; + } else { $position = $value; @@ -278,6 +282,10 @@ protected function batchMove($value, $pks, $contexts) { $position = ''; } + elseif ($value == 'nochange') + { + $position = $table->position; + } else { $position = $value; diff --git a/administrator/language/en-GB/en-GB.com_modules.ini b/administrator/language/en-GB/en-GB.com_modules.ini index f41b1074ab7dc..68d1dea8f56d4 100644 --- a/administrator/language/en-GB/en-GB.com_modules.ini +++ b/administrator/language/en-GB/en-GB.com_modules.ini @@ -10,7 +10,7 @@ COM_MODULES_ASSIGNED_VARIES_EXCEPT="All except selected" COM_MODULES_ASSIGNED_VARIES_ONLY="Selected only" COM_MODULES_BASIC_FIELDSET_LABEL="Basic Options" COM_MODULES_BATCH_POSITION_LABEL="Set Position" -COM_MODULES_BATCH_POSITION_NOCHANGE="- Keep original Position -" +COM_MODULES_BATCH_POSITION_NOCHANGE="Keep original Position" COM_MODULES_BATCH_POSITION_NOPOSITION="No Module Position" COM_MODULES_BATCH_OPTIONS="Batch process the selected modules" COM_MODULES_BATCH_TIP="If choosing to copy a module, any other actions selected will be applied to the copied module. Otherwise, all actions are applied to the selected module." From 29e68be9a5e9f6d8a1b58f3dbce9a105df0b8193 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Mon, 2 Jan 2012 16:06:11 -0500 Subject: [PATCH 40/40] index.html --- administrator/components/com_users/helpers/html/index.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 administrator/components/com_users/helpers/html/index.html diff --git a/administrator/components/com_users/helpers/html/index.html b/administrator/components/com_users/helpers/html/index.html new file mode 100644 index 0000000000000..2efb97f319a35 --- /dev/null +++ b/administrator/components/com_users/helpers/html/index.html @@ -0,0 +1 @@ +