AAAAmodeladmin.php000066600000057406151372620460007414 0ustar00event_after_delete = $config['event_after_delete']; } elseif (empty($this->event_after_delete)) { $this->event_after_delete = 'onContentAfterDelete'; } if (isset($config['event_after_save'])) { $this->event_after_save = $config['event_after_save']; } elseif (empty($this->event_after_save)) { $this->event_after_save = 'onContentAfterSave'; } if (isset($config['event_before_delete'])) { $this->event_before_delete = $config['event_before_delete']; } elseif (empty($this->event_before_delete)) { $this->event_before_delete = 'onContentBeforeDelete'; } if (isset($config['event_before_save'])) { $this->event_before_save = $config['event_before_save']; } elseif (empty($this->event_before_save)) { $this->event_before_save = 'onContentBeforeSave'; } if (isset($config['event_change_state'])) { $this->event_change_state = $config['event_change_state']; } elseif (empty($this->event_change_state)) { $this->event_change_state = 'onContentChangeState'; } // Guess the JText message prefix. Defaults to the option. if (isset($config['text_prefix'])) { $this->text_prefix = strtoupper($config['text_prefix']); } elseif (empty($this->text_prefix)) { $this->text_prefix = strtoupper($this->option); } } /** * 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 11.1 */ 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 (!$done) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Batch access level changes for a group of rows. * * @param integer $value The new value matching an Asset Group 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 11.1 */ protected function batchAccess($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->access = (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; } /** * 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; // 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 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 11.3 */ protected function batchLanguage($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->language = $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; } /** * Batch move items to a new category * * @param integer $value The new category ID. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 11.1 */ protected function batchMove($value, $pks, $contexts) { $categoryId = (int) $value; $table = $this->getTable(); // 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 user has create and edit 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 foreach ($pks as $pk) { if (!$user->authorise('core.edit', $contexts[$pk])) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; } // 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; } } // Set the new category ID $table->catid = $categoryId; // Check the row. if (!$table->check()) { $this->setError($table->getError()); return false; } // Store the row. 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 $record A record object. * * @return boolean True if allowed to delete the record. Defaults to the permission for the component. * * @since 11.1 */ protected function canDelete($record) { $user = JFactory::getUser(); return $user->authorise('core.delete', $this->option); } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. * * @since 11.1 */ protected function canEditState($record) { $user = JFactory::getUser(); return $user->authorise('core.edit.state', $this->option); } /** * Method override to check-in a record or an array of record * * @param mixed $pks The ID of the primary key or an array of IDs * * @return mixed Boolean false if there is an error, otherwise the count of records checked in. * * @since 11.1 */ public function checkin($pks = array()) { // Initialise variables. $pks = (array) $pks; $table = $this->getTable(); $count = 0; if (empty($pks)) { $pks = array((int) $this->getState($this->getName() . '.id')); } // Check in all items. foreach ($pks as $pk) { if ($table->load($pk)) { if ($table->checked_out > 0) { if (!parent::checkin($pk)) { return false; } $count++; } } else { $this->setError($table->getError()); return false; } } return $count; } /** * Method override to check-out a record. * * @param integer $pk The ID of the primary key. * * @return boolean True if successful, false if an error occurs. * * @since 11.1 */ public function checkout($pk = null) { // Initialise variables. $pk = (!empty($pk)) ? $pk : (int) $this->getState($this->getName() . '.id'); return parent::checkout($pk); } /** * Method to delete one or more records. * * @param array &$pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 11.1 */ public function delete(&$pks) { // Initialise variables. $dispatcher = JDispatcher::getInstance(); $pks = (array) $pks; $table = $this->getTable(); // Include the content plugins for the on delete events. JPluginHelper::importPlugin('content'); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ($this->canDelete($table)) { $context = $this->option . '.' . $this->name; // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger($this->event_before_delete, array($context, $table)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } // Trigger the onContentAfterDelete event. $dispatcher->trigger($this->event_after_delete, array($context, $table)); } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { JError::raiseWarning(500, $error); return false; } else { JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); return false; } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Method to change the title & alias. * * @param integer $category_id The id of the category. * @param string $alias The alias. * @param string $title The title. * * @return array Contains the modified title and alias. * * @since 11.1 */ protected function generateNewTitle($category_id, $alias, $title) { // Alter the title & alias $table = $this->getTable(); while ($table->load(array('alias' => $alias, 'catid' => $category_id))) { $title = JString::increment($title); $alias = JString::increment($alias, 'dash'); } return array($title, $alias); } /** * Method to get a single record. * * @param integer $pk The id of the primary key. * * @return mixed Object on success, false on failure. * * @since 11.1 */ public function getItem($pk = null) { // Initialise variables. $pk = (!empty($pk)) ? $pk : (int) $this->getState($this->getName() . '.id'); $table = $this->getTable(); if ($pk > 0) { // Attempt to load the row. $return = $table->load($pk); // Check for a table object error. if ($return === false && $table->getError()) { $this->setError($table->getError()); return false; } } // Convert to the JObject before adding other data. $properties = $table->getProperties(1); $item = JArrayHelper::toObject($properties, 'JObject'); if (property_exists($item, 'params')) { $registry = new JRegistry; $registry->loadString($item->params); $item->params = $registry->toArray(); } return $item; } /** * A protected method to get a set of ordering conditions. * * @param JTable $table A JTable object. * * @return array An array of conditions to add to ordering queries. * * @since 11.1 */ protected function getReorderConditions($table) { return array(); } /** * Stock method to auto-populate the model state. * * @return void * * @since 11.1 */ protected function populateState() { // Initialise variables. $table = $this->getTable(); $key = $table->getKeyName(); // Get the pk of the record from the request. $pk = JRequest::getInt($key); $this->setState($this->getName() . '.id', $pk); // Load the parameters. $value = JComponentHelper::getParams($this->option); $this->setState('params', $value); } /** * Prepare and sanitise the table data prior to saving. * * @param JTable &$table A reference to a JTable object. * * @return void * * @since 11.1 */ protected function prepareTable(&$table) { // Derived class will provide its own implementation if required. } /** * Method to change the published state of one or more records. * * @param array &$pks A list of the primary keys to change. * @param integer $value The value of the published state. * * @return boolean True on success. * * @since 11.1 */ public function publish(&$pks, $value = 1) { // Initialise variables. $dispatcher = JDispatcher::getInstance(); $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Include the content plugins for the change of state event. JPluginHelper::importPlugin('content'); // Access checks. foreach ($pks as $i => $pk) { $table->reset(); 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')); return false; } } } // Attempt to change the state of the records. if (!$table->publish($pks, $value, $user->get('id'))) { $this->setError($table->getError()); return false; } $context = $this->option . '.' . $this->name; // Trigger the onContentChangeState event. $result = $dispatcher->trigger($this->event_change_state, array($context, $pks, $value)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Clear the component's cache $this->cleanCache(); return true; } /** * Method to adjust the ordering of a row. * * Returns NULL if the user did not have edit * privileges for any of the selected primary keys. * * @param integer $pks The ID of the primary key to move. * @param integer $delta Increment, usually +1 or -1 * * @return mixed False on failure or error, true on success, null if the $pk is empty (no items selected). * * @since 11.1 */ public function reorder($pks, $delta = 0) { // Initialise variables. $table = $this->getTable(); $pks = (array) $pks; $result = true; $allowed = true; foreach ($pks as $i => $pk) { $table->reset(); if ($table->load($pk) && $this->checkout($pk)) { // Access checks. if (!$this->canEditState($table)) { // Prune items that you can't change. unset($pks[$i]); $this->checkin($pk); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); $allowed = false; continue; } $where = array(); $where = $this->getReorderConditions($table); if (!$table->move($delta, $where)) { $this->setError($table->getError()); unset($pks[$i]); $result = false; } $this->checkin($pk); } else { $this->setError($table->getError()); unset($pks[$i]); $result = false; } } if ($allowed === false && empty($pks)) { $result = null; } // Clear the component's cache if ($result == true) { $this->cleanCache(); } return $result; } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success, False on error. * * @since 11.1 */ public function save($data) { // Initialise variables; $dispatcher = JDispatcher::getInstance(); $table = $this->getTable(); $key = $table->getKeyName(); $pk = (!empty($data[$key])) ? $data[$key] : (int) $this->getState($this->getName() . '.id'); $isNew = true; // Include the content plugins for the on save events. JPluginHelper::importPlugin('content'); // Allow an exception to be thrown. try { // Load the row if saving an existing record. if ($pk > 0) { $table->load($pk); $isNew = false; } // Bind the data. if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // Prepare the row for saving $this->prepareTable($table); // Check the data. 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)) { $this->setError($table->getError()); return false; } // Store the data. if (!$table->store()) { $this->setError($table->getError()); return false; } // Clean the cache. $this->cleanCache(); // Trigger the onContentAfterSave event. $dispatcher->trigger($this->event_after_save, array($this->option . '.' . $this->name, &$table, $isNew)); } catch (Exception $e) { $this->setError($e->getMessage()); return false; } $pkName = $table->getKeyName(); if (isset($table->$pkName)) { $this->setState($this->getName() . '.id', $table->$pkName); } $this->setState($this->getName() . '.new', $isNew); return true; } /** * Saves the manually set order of records. * * @param array $pks An array of primary key ids. * @param integer $order +1 or -1 * * @return mixed * * @since 11.1 */ public function saveorder($pks = null, $order = null) { // Initialise variables. $table = $this->getTable(); $conditions = array(); if (empty($pks)) { return JError::raiseWarning(500, JText::_($this->text_prefix . '_ERROR_NO_ITEMS_SELECTED')); } // Update ordering values foreach ($pks as $i => $pk) { $table->load((int) $pk); // Access checks. if (!$this->canEditState($table)) { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } elseif ($table->ordering != $order[$i]) { $table->ordering = $order[$i]; if (!$table->store()) { $this->setError($table->getError()); return false; } // Remember to reorder within position and client_id $condition = $this->getReorderConditions($table); $found = false; foreach ($conditions as $cond) { if ($cond[1] == $condition) { $found = true; break; } } if (!$found) { $key = $table->getKeyName(); $conditions[] = array($table->$key, $condition); } } } // Execute reorder for each category. foreach ($conditions as $cond) { $table->load($cond[0]); $table->reorder($cond[1]); } // Clear the component's cache $this->cleanCache(); return true; } } controlleradmin.php000066600000020203151372620460010460 0ustar00registerTask('unpublish', 'publish'); // Value = 2 $this->registerTask('archive', 'publish'); // Value = -2 $this->registerTask('trash', 'publish'); // Value = -3 $this->registerTask('report', 'publish'); $this->registerTask('orderup', 'reorder'); $this->registerTask('orderdown', 'reorder'); // Guess the option as com_NameOfController. if (empty($this->option)) { $this->option = 'com_' . strtolower($this->getName()); } // Guess the JText message prefix. Defaults to the option. if (empty($this->text_prefix)) { $this->text_prefix = strtoupper($this->option); } // Guess the list view as the suffix, eg: OptionControllerSuffix. if (empty($this->view_list)) { $r = null; if (!preg_match('/(.*)Controller(.*)/i', get_class($this), $r)) { JError::raiseError(500, JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME')); } $this->view_list = strtolower($r[2]); } } /** * Removes an item. * * @return void * * @since 11.1 */ public function delete() { // Check for request forgeries JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); // Get items to remove from the request. $cid = JRequest::getVar('cid', array(), '', 'array'); if (!is_array($cid) || count($cid) < 1) { JError::raiseWarning(500, JText::_($this->text_prefix . '_NO_ITEM_SELECTED')); } else { // Get the model. $model = $this->getModel(); // Make sure the item ids are integers jimport('joomla.utilities.arrayhelper'); JArrayHelper::toInteger($cid); // Remove the items. if ($model->delete($cid)) { $this->setMessage(JText::plural($this->text_prefix . '_N_ITEMS_DELETED', count($cid))); } else { $this->setMessage($model->getError()); } } $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); } /** * Display is not supported by this controller. * * @param boolean $cachable If true, the view output will be cached * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. * * @return JController A JController object to support chaining. * * @since 11.1 */ public function display($cachable = false, $urlparams = false) { return $this; } /** * Method to publish a list of items * * @return void * * @since 11.1 */ public function publish() { // Check for request forgeries JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); // Get items to publish from the request. $cid = JRequest::getVar('cid', array(), '', 'array'); $data = array('publish' => 1, 'unpublish' => 0, 'archive' => 2, 'trash' => -2, 'report' => -3); $task = $this->getTask(); $value = JArrayHelper::getValue($data, $task, 0, 'int'); if (empty($cid)) { JError::raiseWarning(500, JText::_($this->text_prefix . '_NO_ITEM_SELECTED')); } else { // Get the model. $model = $this->getModel(); // Make sure the item ids are integers JArrayHelper::toInteger($cid); // Publish the items. if (!$model->publish($cid, $value)) { JError::raiseWarning(500, $model->getError()); } else { if ($value == 1) { $ntext = $this->text_prefix . '_N_ITEMS_PUBLISHED'; } elseif ($value == 0) { $ntext = $this->text_prefix . '_N_ITEMS_UNPUBLISHED'; } elseif ($value == 2) { $ntext = $this->text_prefix . '_N_ITEMS_ARCHIVED'; } else { $ntext = $this->text_prefix . '_N_ITEMS_TRASHED'; } $this->setMessage(JText::plural($ntext, count($cid))); } } $extension = JRequest::getCmd('extension'); $extensionURL = ($extension) ? '&extension=' . JRequest::getCmd('extension') : ''; $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $extensionURL, false)); } /** * Changes the order of one or more records. * * @return boolean True on success * * @since 11.1 */ public function reorder() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Initialise variables. $ids = JRequest::getVar('cid', null, 'post', 'array'); $inc = ($this->getTask() == 'orderup') ? -1 : +1; $model = $this->getModel(); $return = $model->reorder($ids, $inc); if ($return === false) { // Reorder failed. $message = JText::sprintf('JLIB_APPLICATION_ERROR_REORDER_FAILED', $model->getError()); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false), $message, 'error'); return false; } else { // Reorder succeeded. $message = JText::_('JLIB_APPLICATION_SUCCESS_ITEM_REORDERED'); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false), $message); return true; } } /** * Method to save the submitted ordering values for records. * * @return boolean True on success * * @since 11.1 */ public function saveorder() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Get the input $pks = JRequest::getVar('cid', null, 'post', 'array'); $order = JRequest::getVar('order', null, 'post', 'array'); // Sanitize the input JArrayHelper::toInteger($pks); JArrayHelper::toInteger($order); // Get the model $model = $this->getModel(); // Save the ordering $return = $model->saveorder($pks, $order); if ($return === false) { // Reorder failed $message = JText::sprintf('JLIB_APPLICATION_ERROR_REORDER_FAILED', $model->getError()); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false), $message, 'error'); return false; } else { // Reorder succeeded. $this->setMessage(JText::_('JLIB_APPLICATION_SUCCESS_ORDERING_SAVED')); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); return true; } } /** * Check in of one or more records. * * @return boolean True on success * * @since 11.1 */ public function checkin() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Initialise variables. $ids = JRequest::getVar('cid', null, 'post', 'array'); $model = $this->getModel(); $return = $model->checkin($ids); if ($return === false) { // Checkin failed. $message = JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false), $message, 'error'); return false; } else { // Checkin succeeded. $message = JText::plural($this->text_prefix . '_N_ITEMS_CHECKED_IN', count($ids)); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false), $message); return true; } } } index.html000066600000000037151372620460006553 0ustar00 helper.php000066600000025666151372620460006565 0ustar00enabled = $strict ? false : true; $result->params = new JRegistry; } } else { $result = self::$components[$option]; } return $result; } /** * Checks if the component is enabled * * @param string $option The component option. * @param boolean $strict If set and the component does not exist, false will be returned. * * @return boolean * * @since 11.1 */ public static function isEnabled($option, $strict = false) { $result = self::getComponent($option, $strict); return ($result->enabled | JFactory::getApplication()->isAdmin()); } /** * Gets the parameter object for the component * * @param string $option The option for the component. * @param boolean $strict If set and the component does not exist, false will be returned * * @return JRegistry A JRegistry object. * * @see JRegistry * @since 11.1 */ public static function getParams($option, $strict = false) { $component = self::getComponent($option, $strict); return $component->params; } /** * Applies the global text filters to arbitrary text as per settings for current user groups * * @param string $text The string to filter * * @return string The filtered string * * @since 11.4 */ public static function filterText($text) { // Filter settings $config = self::getParams('com_config'); $user = JFactory::getUser(); $userGroups = JAccess::getGroupsByUser($user->get('id')); $filters = $config->get('filters'); $blackListTags = array(); $blackListAttributes = array(); $customListTags = array(); $customListAttributes = array(); $whiteListTags = array(); $whiteListAttributes = array(); $noHtml = false; $whiteList = false; $blackList = false; $customList = false; $unfiltered = false; // Cycle through each of the user groups the user is in. // Remember they are included in the Public group as well. foreach ($userGroups as $groupId) { // May have added a group by not saved the filters. if (!isset($filters->$groupId)) { continue; } // Each group the user is in could have different filtering properties. $filterData = $filters->$groupId; $filterType = strtoupper($filterData->filter_type); if ($filterType == 'NH') { // Maximum HTML filtering. $noHtml = true; } elseif ($filterType == 'NONE') { // No HTML filtering. $unfiltered = true; } else { // Black or white list. // Preprocess the tags and attributes. $tags = explode(',', $filterData->filter_tags); $attributes = explode(',', $filterData->filter_attributes); $tempTags = array(); $tempAttributes = array(); foreach ($tags as $tag) { $tag = trim($tag); if ($tag) { $tempTags[] = $tag; } } foreach ($attributes as $attribute) { $attribute = trim($attribute); if ($attribute) { $tempAttributes[] = $attribute; } } // Collect the black or white list tags and attributes. // Each list is cummulative. if ($filterType == 'BL') { $blackList = true; $blackListTags = array_merge($blackListTags, $tempTags); $blackListAttributes = array_merge($blackListAttributes, $tempAttributes); } elseif ($filterType == 'CBL') { // Only set to true if Tags or Attributes were added if ($tempTags || $tempAttributes) { $customList = true; $customListTags = array_merge($customListTags, $tempTags); $customListAttributes = array_merge($customListAttributes, $tempAttributes); } } elseif ($filterType == 'WL') { $whiteList = true; $whiteListTags = array_merge($whiteListTags, $tempTags); $whiteListAttributes = array_merge($whiteListAttributes, $tempAttributes); } } } // Remove duplicates before processing (because the black list uses both sets of arrays). $blackListTags = array_unique($blackListTags); $blackListAttributes = array_unique($blackListAttributes); $customListTags = array_unique($customListTags); $customListAttributes = array_unique($customListAttributes); $whiteListTags = array_unique($whiteListTags); $whiteListAttributes = array_unique($whiteListAttributes); // Unfiltered assumes first priority. if ($unfiltered) { // Dont apply filtering. } else { // Custom blacklist precedes Default blacklist if ($customList) { $filter = JFilterInput::getInstance(array(), array(), 1, 1); // Override filter's default blacklist tags and attributes if ($customListTags) { $filter->tagBlacklist = $customListTags; } if ($customListAttributes) { $filter->attrBlacklist = $customListAttributes; } } // Black lists take second precedence. elseif ($blackList) { // Remove the white-listed tags and attributes from the black-list. $blackListTags = array_diff($blackListTags, $whiteListTags); $blackListAttributes = array_diff($blackListAttributes, $whiteListAttributes); $filter = JFilterInput::getInstance($blackListTags, $blackListAttributes, 1, 1); // Remove white listed tags from filter's default blacklist if ($whiteListTags) { $filter->tagBlacklist = array_diff($filter->tagBlacklist, $whiteListTags); } // Remove white listed attributes from filter's default blacklist if ($whiteListAttributes) { $filter->attrBlacklist = array_diff($filter->attrBlacklist); } } // White lists take third precedence. elseif ($whiteList) { // Turn off xss auto clean $filter = JFilterInput::getInstance($whiteListTags, $whiteListAttributes, 0, 0, 0); } // No HTML takes last place. else { $filter = JFilterInput::getInstance(); } $text = $filter->clean($text, 'html'); } return $text; } /** * Render the component. * * @param string $option The component option. * @param array $params The component parameters * * @return object * * @since 11.1 */ public static function renderComponent($option, $params = array()) { // Initialise variables. $app = JFactory::getApplication(); // Load template language files. $template = $app->getTemplate(true)->template; $lang = JFactory::getLanguage(); $lang->load('tpl_' . $template, JPATH_BASE, null, false, true) || $lang->load('tpl_' . $template, JPATH_THEMES . "/$template", null, false, true); if (empty($option)) { // Throw 404 if no component JError::raiseError(404, JText::_('JLIB_APPLICATION_ERROR_COMPONENT_NOT_FOUND')); return; } // Record the scope $scope = $app->scope; // Set scope to component name $app->scope = $option; // Build the component path. $option = preg_replace('/[^A-Z0-9_\.-]/i', '', $option); $file = substr($option, 4); // Define component path. define('JPATH_COMPONENT', JPATH_BASE . '/components/' . $option); define('JPATH_COMPONENT_SITE', JPATH_SITE . '/components/' . $option); define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/' . $option); // Get component path if ($app->isAdmin() && file_exists(JPATH_COMPONENT . '/admin.' . $file . '.php')) { JLog::add('Files in the format admin.COMPONENTNAME.php are considered deprecated and will not be loaded in Joomla 3.0.', JLog::WARNING, 'deprecated'); $path = JPATH_COMPONENT . '/admin.' . $file . '.php'; } else { $path = JPATH_COMPONENT . '/' . $file . '.php'; } // If component is disabled throw error if (!self::isEnabled($option) || !file_exists($path)) { JError::raiseError(404, JText::_('JLIB_APPLICATION_ERROR_COMPONENT_NOT_FOUND')); } $task = JRequest::getString('task'); // Load common and local language files. $lang->load($option, JPATH_BASE, null, false, true) || $lang->load($option, JPATH_COMPONENT, null, false, true); // Handle template preview outlining. $contents = null; // Execute the component. $contents = self::executeComponent($path); // Build the component toolbar $path = JApplicationHelper::getPath('toolbar'); if ($path && $app->isAdmin()) { JLog::add('Files in the format toolbar.COMPONENTNAME.php are considered deprecated and will not be loaded in Joomla 3.0.', JLog::WARNING, 'deprecated'); // Get the task again, in case it has changed $task = JRequest::getString('task'); // Make the toolbar include_once $path; } // Revert the scope $app->scope = $scope; return $contents; } /** * Execute the component. * * @param string $path The component path. * * @return string The component output * * @since 11.3 */ protected static function executeComponent($path) { ob_start(); require_once $path; $contents = ob_get_contents(); ob_end_clean(); return $contents; } /** * Load the installed components into the components property. * * @param string $option The element value for the extension * * @return boolean True on success * * @since 11.1 */ protected static function _load($option) { $db = JFactory::getDbo(); $query = $db->getQuery(true); $query->select('extension_id AS id, element AS "option", params, enabled'); $query->from('#__extensions'); $query->where($query->qn('type') . ' = ' . $db->quote('component')); $query->where($query->qn('element') . ' = ' . $db->quote($option)); $db->setQuery($query); $cache = JFactory::getCache('_system', 'callback'); self::$components[$option] = $cache->get(array($db, 'loadObject'), null, $option, false); if ($error = $db->getErrorMsg() || empty(self::$components[$option])) { // Fatal error. JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_COMPONENT_NOT_LOADING', $option, $error)); return false; } // Convert the params to an object. if (is_string(self::$components[$option]->params)) { $temp = new JRegistry; $temp->loadString(self::$components[$option]->params); self::$components[$option]->params = $temp; } return true; } } modelform.php000066600000015507151372620460007263 0ustar00getTable(); if (!$table->load($pk)) { $this->setError($table->getError()); return false; } // Check if this is the user having previously checked out the row. if ($table->checked_out > 0 && $table->checked_out != $user->get('id') && !$user->authorise('core.admin', 'com_checkin')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH')); return false; } // Attempt to check the row in. if (!$table->checkin($pk)) { $this->setError($table->getError()); return false; } } return true; } /** * Method to check-out a row for editing. * * @param integer $pk The numeric id of the primary key. * * @return boolean False on failure or error, true otherwise. * * @since 11.1 */ public function checkout($pk = null) { // Only attempt to check the row in if it exists. if ($pk) { $user = JFactory::getUser(); // Get an instance of the row to checkout. $table = $this->getTable(); if (!$table->load($pk)) { $this->setError($table->getError()); return false; } // Check if this is the user having previously checked out the row. if ($table->checked_out > 0 && $table->checked_out != $user->get('id')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_CHECKOUT_USER_MISMATCH')); return false; } // Attempt to check the row out. if (!$table->checkout($user->get('id'), $pk)) { $this->setError($table->getError()); return false; } } return true; } /** * Abstract method for getting the form from the model. * * @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 11.1 */ abstract public function getForm($data = array(), $loadData = true); /** * Method to get a form object. * * @param string $name The name of the form. * @param string $source The form source. Can be XML string if file flag is set to false. * @param array $options Optional array of options for the form creation. * @param boolean $clear Optional argument to force load a new form. * @param string $xpath An optional xpath to search for the fields. * * @return mixed JForm object on success, False on error. * * @see JForm * @since 11.1 */ protected function loadForm($name, $source = null, $options = array(), $clear = false, $xpath = false) { // Handle the optional arguments. $options['control'] = JArrayHelper::getValue($options, 'control', false); // Create a signature hash. $hash = md5($source . serialize($options)); // Check if we can use a previously loaded form. if (isset($this->_forms[$hash]) && !$clear) { return $this->_forms[$hash]; } // Get the form. JForm::addFormPath(JPATH_COMPONENT . '/models/forms'); JForm::addFieldPath(JPATH_COMPONENT . '/models/fields'); try { $form = JForm::getInstance($name, $source, $options, false, $xpath); if (isset($options['load_data']) && $options['load_data']) { // Get the data for the form. $data = $this->loadFormData(); } else { $data = array(); } // Allow for additional modification of the form, and events to be triggered. // We pass the data because plugins may require it. $this->preprocessForm($form, $data); // Load the data into the form after the plugins have operated. $form->bind($data); } catch (Exception $e) { $this->setError($e->getMessage()); return false; } // Store the form for later. $this->_forms[$hash] = $form; return $form; } /** * Method to get the data that should be injected in the form. * * @return array The default data is an empty array. * * @since 11.1 */ protected function loadFormData() { return array(); } /** * Method to allow derived classes to preprocess the form. * * @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"). * * @return void * * @see JFormField * @since 11.1 * @throws Exception if there is an error in the form event. */ protected function preprocessForm(JForm $form, $data, $group = 'content') { // Import the appropriate plugin group. JPluginHelper::importPlugin($group); // Get the dispatcher. $dispatcher = JDispatcher::getInstance(); // Trigger the form preparation event. $results = $dispatcher->trigger('onContentPrepareForm', array($form, $data)); // Check for errors encountered while preparing the form. if (count($results) && in_array(false, $results, true)) { // Get the last error. $error = $dispatcher->getError(); if (!($error instanceof Exception)) { throw new Exception($error); } } } /** * Method to validate the form data. * * @param JForm $form The form to validate against. * @param array $data The data to validate. * @param string $group The name of the field group to validate. * * @return mixed Array of filtered data if valid, false otherwise. * * @see JFormRule * @see JFilterInput * @since 11.1 */ public function validate($form, $data, $group = null) { // Filter and validate the form data. $data = $form->filter($data); $return = $form->validate($data, $group); // Check for an error. if ($return instanceof Exception) { $this->setError($return->getMessage()); return false; } // Check the validation results. if ($return === false) { // Get the validation messages from the form. foreach ($form->getErrors() as $message) { $this->setError(JText::_($message)); } return false; } return $data; } } controller.php000066600000063744151372620460007470 0ustar00clean(array_pop(array_keys($command)), 'cmd'); } else { $command = $filter->clean($command, 'cmd'); } // Check for a controller.task command. if (strpos($command, '.') !== false) { // Explode the controller.task command. list ($type, $task) = explode('.', $command); // Define the controller filename and path. $file = self::createFileName('controller', array('name' => $type, 'format' => $format)); $path = $basePath . '/controllers/' . $file; // Reset the task without the controller context. JRequest::setVar('task', $task); } else { // Base controller. $type = null; $task = $command; // Define the controller filename and path. $file = self::createFileName('controller', array('name' => 'controller', 'format' => $format)); $path = $basePath . '/' . $file; $backupfile = self::createFileName('controller', array('name' => 'controller')); $backuppath = $basePath . '/' . $backupfile; } // Get the controller class name. $class = ucfirst($prefix) . 'Controller' . ucfirst($type); // Include the class if not present. if (!class_exists($class)) { // If the controller file path exists, include it. if (file_exists($path)) { require_once $path; } elseif (isset($backuppath) && file_exists($backuppath)) { require_once $backuppath; } else { throw new InvalidArgumentException(JText::sprintf('JLIB_APPLICATION_ERROR_INVALID_CONTROLLER', $type, $format)); } } // Instantiate the class. if (class_exists($class)) { self::$instance = new $class($config); } else { throw new InvalidArgumentException(JText::sprintf('JLIB_APPLICATION_ERROR_INVALID_CONTROLLER_CLASS', $class)); } return self::$instance; } /** * Constructor. * * @param array $config An optional associative array of configuration settings. * Recognized key values include 'name', 'default_task', 'model_path', and * 'view_path' (this list is not meant to be comprehensive). * * @since 11.1 */ public function __construct($config = array()) { // Initialise variables. $this->methods = array(); $this->message = null; $this->messageType = 'message'; $this->paths = array(); $this->redirect = null; $this->taskMap = array(); if (defined('JDEBUG') && JDEBUG) { JLog::addLogger(array('text_file' => 'jcontroller.log.php'), JLog::ALL, array('controller')); } // Determine the methods to exclude from the base class. $xMethods = get_class_methods('JController'); // Get the public methods in this class using reflection. $r = new ReflectionClass($this); $rMethods = $r->getMethods(ReflectionMethod::IS_PUBLIC); foreach ($rMethods as $rMethod) { $mName = $rMethod->getName(); // Add default display method if not explicitly declared. if (!in_array($mName, $xMethods) || $mName == 'display') { $this->methods[] = strtolower($mName); // Auto register the methods as tasks. $this->taskMap[strtolower($mName)] = $mName; } } // Set the view name if (empty($this->name)) { if (array_key_exists('name', $config)) { $this->name = $config['name']; } else { $this->name = $this->getName(); } } // Set a base path for use by the controller if (array_key_exists('base_path', $config)) { $this->basePath = $config['base_path']; } else { $this->basePath = JPATH_COMPONENT; } // If the default task is set, register it as such if (array_key_exists('default_task', $config)) { $this->registerDefaultTask($config['default_task']); } else { $this->registerDefaultTask('display'); } // Set the models prefix if (empty($this->model_prefix)) { if (array_key_exists('model_prefix', $config)) { // User-defined prefix $this->model_prefix = $config['model_prefix']; } else { $this->model_prefix = $this->name . 'Model'; } } // Set the default model search path if (array_key_exists('model_path', $config)) { // User-defined dirs $this->addModelPath($config['model_path'], $this->model_prefix); } else { $this->addModelPath($this->basePath . '/models', $this->model_prefix); } // Set the default view search path if (array_key_exists('view_path', $config)) { // User-defined dirs $this->setPath('view', $config['view_path']); } else { $this->setPath('view', $this->basePath . '/views'); } // Set the default view. if (array_key_exists('default_view', $config)) { $this->default_view = $config['default_view']; } elseif (empty($this->default_view)) { $this->default_view = $this->getName(); } } /** * Adds to the search path for templates and resources. * * @param string $type The path type (e.g. 'model', 'view'). * @param mixed $path The directory string or stream array to search. * * @return JController A JController object to support chaining. * * @since 11.1 * @note Replaces _addPath. */ protected function addPath($type, $path) { // Just force path to array settype($path, 'array'); if (!isset($this->paths[$type])) { $this->paths[$type] = array(); } // Loop through the path directories foreach ($path as $dir) { // No surrounding spaces allowed! $dir = rtrim(JPath::check($dir, '/'), '/') . '/'; // Add to the top of the search dirs array_unshift($this->paths[$type], $dir); } return $this; } /** * Add one or more view paths to the controller's stack, in LIFO order. * * @param mixed $path The directory (string) or list of directories (array) to add. * * @return JController This object to support chaining. */ public function addViewPath($path) { $this->addPath('view', $path); return $this; } /** * Authorisation check * * @param string $task The ACO Section Value to check access on * * @return boolean True if authorised * * @since 11.1 * * @deprecated 12.1 Use JAuthorise */ public function authorize($task) { JLog::add('JController::authorize() is deprecated.', JLog::WARNING, 'deprecated'); $this->authorise($task); } /** * Authorisation check * * @param string $task The ACO Section Value to check access on. * * @return boolean True if authorised * * @since 11.1 * @deprecated 12.3 */ public function authorise($task) { // Only do access check if the aco section is set if ($this->_acoSection) { // If we have a section value set that trumps the passed task. if ($this->_acoSectionValue) { // We have one, so set it and lets do the check $task = $this->_acoSectionValue; } // Get the JUser object for the current user and return the authorization boolean $user = JFactory::getUser(); return $user->authorise($this->_acoSection, $task); } else { // Nothing set, nothing to check... so obviously it's ok :) return true; } } /** * Method to check whether an ID is in the edit list. * * @param string $context The context for the session storage. * @param integer $id The ID of the record to add to the edit list. * * @return boolean True if the ID is in the edit list. * * @since 11.1 */ protected function checkEditId($context, $id) { if ($id) { $app = JFactory::getApplication(); $values = (array) $app->getUserState($context . '.id'); $result = in_array((int) $id, $values); if (defined('JDEBUG') && JDEBUG) { JLog::add( sprintf( 'Checking edit ID %s.%s: %d %s', $context, $id, (int) $result, str_replace("\n", ' ', print_r($values, 1)) ), JLog::INFO, 'controller' ); } return $result; } else { // No id for a new item. return true; } } /** * Method to load and return a model object. * * @param string $name The name of the model. * @param string $prefix Optional model prefix. * @param array $config Configuration array for the model. Optional. * * @return mixed Model object on success; otherwise null failure. * * @since 11.1 * @note Replaces _createModel. */ protected function createModel($name, $prefix = '', $config = array()) { // Clean the model name $modelName = preg_replace('/[^A-Z0-9_]/i', '', $name); $classPrefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix); $result = JModel::getInstance($modelName, $classPrefix, $config); return $result; } /** * Method to load and return a view object. This method first looks in the * current template directory for a match and, failing that, uses a default * set path to load the view class file. * * Note the "name, prefix, type" order of parameters, which differs from the * "name, type, prefix" order used in related public methods. * * @param string $name The name of the view. * @param string $prefix Optional prefix for the view class name. * @param string $type The type of view. * @param array $config Configuration array for the view. Optional. * * @return mixed View object on success; null or error result on failure. * * @since 11.1 * @note Replaces _createView. */ protected function createView($name, $prefix = '', $type = '', $config = array()) { // Clean the view name $viewName = preg_replace('/[^A-Z0-9_]/i', '', $name); $classPrefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix); $viewType = preg_replace('/[^A-Z0-9_]/i', '', $type); // Build the view class name $viewClass = $classPrefix . $viewName; if (!class_exists($viewClass)) { jimport('joomla.filesystem.path'); $path = JPath::find($this->paths['view'], $this->createFileName('view', array('name' => $viewName, 'type' => $viewType))); if ($path) { require_once $path; if (!class_exists($viewClass)) { JError::raiseError(500, JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_CLASS_NOT_FOUND', $viewClass, $path)); return null; } } else { return null; } } return new $viewClass($config); } /** * Typical view method for MVC based architecture * * This function is provide as a default implementation, in most cases * you will need to override it in your own controllers. * * @param boolean $cachable If true, the view output will be cached * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. * * @return JController A JController object to support chaining. * * @since 11.1 */ public function display($cachable = false, $urlparams = false) { $document = JFactory::getDocument(); $viewType = $document->getType(); $viewName = JRequest::getCmd('view', $this->default_view); $viewLayout = JRequest::getString('layout', 'default'); $view = $this->getView($viewName, $viewType, '', array('base_path' => $this->basePath, 'layout' => $viewLayout)); // Get/Create the model if ($model = $this->getModel($viewName)) { // Push the model into the view (as default) $view->setModel($model, true); } $view->assignRef('document', $document); $conf = JFactory::getConfig(); // Display the view if ($cachable && $viewType != 'feed' && $conf->get('caching') >= 1) { $option = JRequest::getCmd('option'); $cache = JFactory::getCache($option, 'view'); if (is_array($urlparams)) { $app = JFactory::getApplication(); if (!empty($app->registeredurlparams)) { $registeredurlparams = $app->registeredurlparams; } else { $registeredurlparams = new stdClass; } foreach ($urlparams as $key => $value) { // Add your safe url parameters with variable type as value {@see JFilterInput::clean()}. $registeredurlparams->$key = $value; } $app->registeredurlparams = $registeredurlparams; } $cache->get($view, 'display'); } else { $view->display(); } return $this; } /** * Execute a task by triggering a method in the derived class. * * @param string $task The task to perform. If no matching task is found, the '__default' task is executed, if defined. * * @return mixed The value returned by the called method, false in error case. * * @since 11.1 */ public function execute($task) { $this->task = $task; $task = strtolower($task); if (isset($this->taskMap[$task])) { $doTask = $this->taskMap[$task]; } elseif (isset($this->taskMap['__default'])) { $doTask = $this->taskMap['__default']; } else { return JError::raiseError(404, JText::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND', $task)); } // Record the actual task being fired $this->doTask = $doTask; // Make sure we have access if ($this->authorise($doTask)) { $retval = $this->$doTask(); return $retval; } else { return JError::raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); } } /** * Method to get a model object, loading it if required. * * @param string $name The model name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return object The model. * * @since 11.1 */ public function getModel($name = '', $prefix = '', $config = array()) { if (empty($name)) { $name = $this->getName(); } if (empty($prefix)) { $prefix = $this->model_prefix; } if ($model = $this->createModel($name, $prefix, $config)) { // Task is a reserved state $model->setState('task', $this->task); // Let's get the application object and set menu information if it's available $app = JFactory::getApplication(); $menu = $app->getMenu(); if (is_object($menu)) { if ($item = $menu->getActive()) { $params = $menu->getParams($item->id); // Set default state data $model->setState('parameters.menu', $params); } } } return $model; } /** * Method to get the controller name * * The dispatcher name is set by default parsed using the classname, or it can be set * by passing a $config['name'] in the class constructor * * @return string The name of the dispatcher * * @since 11.1 */ public function getName() { if (empty($this->name)) { $r = null; if (!preg_match('/(.*)Controller/i', get_class($this), $r)) { JError::raiseError(500, JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME')); } $this->name = strtolower($r[1]); } return $this->name; } /** * Get the last task that is being performed or was most recently performed. * * @return string The task that is being performed or was most recently performed. * * @since 11.1 */ public function getTask() { return $this->task; } /** * Gets the available tasks in the controller. * * @return array Array[i] of task names. * * @since 11.1 */ public function getTasks() { return $this->methods; } /** * Method to get a reference to the current view and load it if necessary. * * @param string $name The view name. Optional, defaults to the controller name. * @param string $type The view type. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for view. Optional. * * @return object Reference to the view or an error. * * @since 11.1 */ public function getView($name = '', $type = '', $prefix = '', $config = array()) { static $views; if (!isset($views)) { $views = array(); } if (empty($name)) { $name = $this->getName(); } if (empty($prefix)) { $prefix = $this->getName() . 'View'; } if (empty($views[$name])) { if ($view = $this->createView($name, $prefix, $type, $config)) { $views[$name] = & $view; } else { $result = JError::raiseError(500, JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_NOT_FOUND', $name, $type, $prefix)); return $result; } } return $views[$name]; } /** * Method to add a record ID to the edit list. * * @param string $context The context for the session storage. * @param integer $id The ID of the record to add to the edit list. * * @return void * * @since 11.1 */ protected function holdEditId($context, $id) { // Initialise variables. $app = JFactory::getApplication(); $values = (array) $app->getUserState($context . '.id'); // Add the id to the list if non-zero. if (!empty($id)) { array_push($values, (int) $id); $values = array_unique($values); $app->setUserState($context . '.id', $values); if (defined('JDEBUG') && JDEBUG) { JLog::add( sprintf( 'Holding edit ID %s.%s %s', $context, $id, str_replace("\n", ' ', print_r($values, 1)) ), JLog::INFO, 'controller' ); } } } /** * Redirects the browser or returns false if no redirect is set. * * @return boolean False if no redirect exists. * * @since 11.1 */ public function redirect() { if ($this->redirect) { $app = JFactory::getApplication(); $app->redirect($this->redirect, $this->message, $this->messageType); } return false; } /** * Register the default task to perform if a mapping is not found. * * @param string $method The name of the method in the derived class to perform if a named task is not found. * * @return JController A JController object to support chaining. * * @since 11.1 */ public function registerDefaultTask($method) { $this->registerTask('__default', $method); return $this; } /** * Register (map) a task to a method in the class. * * @param string $task The task. * @param string $method The name of the method in the derived class to perform for this task. * * @return JController A JController object to support chaining. * * @since 11.1 */ public function registerTask($task, $method) { if (in_array(strtolower($method), $this->methods)) { $this->taskMap[strtolower($task)] = $method; } return $this; } /** * Unregister (unmap) a task in the class. * * @param string $task The task. * * @return JController This object to support chaining. * * @since 11.1 */ public function unregisterTask($task) { unset($this->taskMap[strtolower($task)]); return $this; } /** * Method to check whether an ID is in the edit list. * * @param string $context The context for the session storage. * @param integer $id The ID of the record to add to the edit list. * * @return void * * @since 11.1 */ protected function releaseEditId($context, $id) { $app = JFactory::getApplication(); $values = (array) $app->getUserState($context . '.id'); // Do a strict search of the edit list values. $index = array_search((int) $id, $values, true); if (is_int($index)) { unset($values[$index]); $app->setUserState($context . '.id', $values); if (defined('JDEBUG') && JDEBUG) { JLog::add( sprintf( 'Releasing edit ID %s.%s %s', $context, $id, str_replace("\n", ' ', print_r($values, 1)) ), JLog::INFO, 'controller' ); } } } /** * Sets the access control levels. * * @param string $section The ACO section (eg, the component). * @param string $value The ACO section value (if using a constant value). * * @return void * * @deprecated 12.1 Use JAccess * @see Jaccess * @since 11.1 */ public function setAccessControl($section, $value = null) { // Deprecation warning. JLog::add('JController::setAccessControl() is deprecated.', JLog::WARNING, 'deprecated'); $this->_acoSection = $section; $this->_acoSectionValue = $value; } /** * Sets the internal message that is passed with a redirect * * @param string $text Message to display on redirect. * @param string $type Message type (since 11.1). Optional, defaults to 'message'. * * @return string Previous message * * @since 11.1 */ public function setMessage($text, $type = 'message') { $previous = $this->message; $this->message = $text; $this->messageType = $type; return $previous; } /** * Sets an entire array of search paths for resources. * * @param string $type The type of path to set, typically 'view' or 'model'. * @param string $path The new set of search paths. If null or false, resets to the current directory only. * * @return void * * @note Replaces _setPath. * @since 11.1 */ protected function setPath($type, $path) { // Clear out the prior search dirs $this->paths[$type] = array(); // Actually add the user-specified directories $this->addPath($type, $path); } /** * Set a URL for browser redirection. * * @param string $url URL to redirect to. * @param string $msg Message to display on redirect. Optional, defaults to value set internally by controller, if any. * @param string $type Message type. Optional, defaults to 'message' or the type set by a previous call to setMessage. * * @return JController This object to support chaining. * * @since 11.1 */ public function setRedirect($url, $msg = null, $type = null) { $this->redirect = $url; if ($msg !== null) { // Controller may have set this directly $this->message = $msg; } // Ensure the type is not overwritten by a previous call to setMessage. if (empty($type)) { if (empty($this->messageType)) { $this->messageType = 'message'; } } // If the type is explicitly set, set it. else { $this->messageType = $type; } return $this; } } controllerform.php000066600000047440151372620460010347 0ustar00option)) { $this->option = 'com_' . strtolower($this->getName()); } // Guess the JText message prefix. Defaults to the option. if (empty($this->text_prefix)) { $this->text_prefix = strtoupper($this->option); } // Guess the context as the suffix, eg: OptionControllerContent. if (empty($this->context)) { $r = null; if (!preg_match('/(.*)Controller(.*)/i', get_class($this), $r)) { JError::raiseError(500, JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME')); } $this->context = strtolower($r[2]); } // Guess the item view as the context. if (empty($this->view_item)) { $this->view_item = $this->context; } // Guess the list view as the plural of the item view. if (empty($this->view_list)) { // @TODO Probably worth moving to an inflector class based on // http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/ // Simple pluralisation based on public domain snippet by Paul Osman // For more complex types, just manually set the variable in your class. $plural = array( array('/(x|ch|ss|sh)$/i', "$1es"), array('/([^aeiouy]|qu)y$/i', "$1ies"), array('/([^aeiouy]|qu)ies$/i', "$1y"), array('/(bu)s$/i', "$1ses"), array('/s$/i', "s"), array('/$/', "s")); // Check for matches using regular expressions foreach ($plural as $pattern) { if (preg_match($pattern[0], $this->view_item)) { $this->view_list = preg_replace($pattern[0], $pattern[1], $this->view_item); break; } } } // Apply, Save & New, and Save As copy should be standard on forms. $this->registerTask('apply', 'save'); $this->registerTask('save2new', 'save'); $this->registerTask('save2copy', 'save'); } /** * Method to add a new record. * * @return mixed True if the record can be added, a JError object if not. * * @since 11.1 */ public function add() { // Initialise variables. $app = JFactory::getApplication(); $context = "$this->option.edit.$this->context"; // Access check. if (!$this->allowAdd()) { // Set the internal error and also the redirect error. $this->setError(JText::_('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED')); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false ) ); return false; } // Clear the record edit information from the session. $app->setUserState($context . '.data', null); // Redirect to the edit screen. $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(), false ) ); return true; } /** * 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. * * @return boolean * * @since 11.1 */ protected function allowAdd($data = array()) { $user = JFactory::getUser(); return ($user->authorise('core.create', $this->option) || count($user->getAuthorisedCategories($this->option, 'core.create'))); } /** * 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 string $key The name of the key for the primary key; default is id. * * @return boolean * * @since 11.1 */ protected function allowEdit($data = array(), $key = 'id') { return JFactory::getUser()->authorise('core.edit', $this->option); } /** * Method to check if you can save a new or existing 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. * * @return boolean * * @since 11.1 */ protected function allowSave($data, $key = 'id') { // Initialise variables. $recordId = isset($data[$key]) ? $data[$key] : '0'; if ($recordId) { return $this->allowEdit($data, $key); } else { return $this->allowAdd($data); } } /** * Method to run batch operations. * * @param JModel $model The model of the component being processed. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 11.1 */ public function batch($model) { // Initialise variables. $input = JFactory::getApplication()->input; $vars = $input->post->get('batch', array(), 'array'); $cid = $input->post->get('cid', array(), 'array'); // 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)) { $this->setMessage(JText::_('JLIB_APPLICATION_SUCCESS_BATCH')); return true; } else { $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_FAILED', $model->getError())); return false; } } /** * Method to cancel an edit. * * @param string $key The name of the primary key of the URL variable. * * @return boolean True if access level checks pass, false otherwise. * * @since 11.1 */ public function cancel($key = null) { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Initialise variables. $app = JFactory::getApplication(); $model = $this->getModel(); $table = $model->getTable(); $checkin = property_exists($table, 'checked_out'); $context = "$this->option.edit.$this->context"; if (empty($key)) { $key = $table->getKeyName(); } $recordId = JRequest::getInt($key); // Attempt to check-in the current record. if ($recordId) { // Check we are holding the id in the edit list. if (!$this->checkEditId($context, $recordId)) { // Somehow the person just went to the form - 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=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false ) ); return false; } if ($checkin) { if ($model->checkin($recordId) === false) { // Check-in failed, go back to the record and display a notice. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false ) ); return false; } } } // Clean the session data and redirect. $this->releaseEditId($context, $recordId); $app->setUserState($context . '.data', null); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false ) ); return true; } /** * 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 boolean True if access level check and checkout passes, false otherwise. * * @since 11.1 */ public function edit($key = null, $urlVar = null) { // Initialise variables. $app = JFactory::getApplication(); $model = $this->getModel(); $table = $model->getTable(); $cid = JRequest::getVar('cid', array(), 'post', 'array'); $context = "$this->option.edit.$this->context"; // Determine the name of the primary key for the data. if (empty($key)) { $key = $table->getKeyName(); } // To avoid data collisions the urlVar may be different from the primary key. if (empty($urlVar)) { $urlVar = $key; } // Get the previous record id (if any) and the current record id. $recordId = (int) (count($cid) ? $cid[0] : JRequest::getInt($urlVar)); $checkin = property_exists($table, 'checked_out'); // Access check. if (!$this->allowEdit(array($key => $recordId), $key)) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED')); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false ) ); return false; } // Attempt to check-out the new record for editing and redirect. if ($checkin && !$model->checkout($recordId)) { // Check-out failed, display a notice but allow the user to see the record. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKOUT_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar), false ) ); return false; } else { // Check-out succeeded, push the new record id into the session. $this->holdEditId($context, $recordId); $app->setUserState($context . '.data', null); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar), false ) ); return true; } } /** * Method to get a model object, loading it if required. * * @param string $name The model name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return object The model. * * @since 11.1 */ public function getModel($name = '', $prefix = '', $config = array('ignore_request' => true)) { if (empty($name)) { $name = $this->context; } return parent::getModel($name, $prefix, $config); } /** * Gets the URL arguments to append to an item redirect. * * @param integer $recordId The primary key id for the item. * @param string $urlVar The name of the URL variable for the id. * * @return string The arguments to append to the redirect URL. * * @since 11.1 */ protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') { $tmpl = JRequest::getCmd('tmpl'); $layout = JRequest::getCmd('layout', 'edit'); $append = ''; // Setup redirect info. if ($tmpl) { $append .= '&tmpl=' . $tmpl; } if ($layout) { $append .= '&layout=' . $layout; } if ($recordId) { $append .= '&' . $urlVar . '=' . $recordId; } return $append; } /** * Gets the URL arguments to append to a list redirect. * * @return string The arguments to append to the redirect URL. * * @since 11.1 */ protected function getRedirectToListAppend() { $tmpl = JRequest::getCmd('tmpl'); $append = ''; // Setup redirect info. if ($tmpl) { $append .= '&tmpl=' . $tmpl; } return $append; } /** * Function that allows child controller access to model data * after the data has been saved. * * @param JModel &$model The data model object. * @param array $validData The validated data. * * @return void * * @since 11.1 */ protected function postSaveHook(JModel &$model, $validData = array()) { } /** * Method to save a record. * * @param string $key The name of the primary key of the URL variable. * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). * * @return boolean True if successful, false otherwise. * * @since 11.1 */ public function save($key = null, $urlVar = null) { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Initialise variables. $app = JFactory::getApplication(); $lang = JFactory::getLanguage(); $model = $this->getModel(); $table = $model->getTable(); $data = JRequest::getVar('jform', array(), 'post', 'array'); $checkin = property_exists($table, 'checked_out'); $context = "$this->option.edit.$this->context"; $task = $this->getTask(); // Determine the name of the primary key for the data. if (empty($key)) { $key = $table->getKeyName(); } // To avoid data collisions the urlVar may be different from the primary key. if (empty($urlVar)) { $urlVar = $key; } $recordId = JRequest::getInt($urlVar); if (!$this->checkEditId($context, $recordId)) { // Somehow the person just went to the form and tried to save 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=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false ) ); return false; } // Populate the row id from the session. $data[$key] = $recordId; // The save2copy task needs to be handled slightly differently. if ($task == 'save2copy') { // Check-in the original row. if ($checkin && $model->checkin($data[$key]) === false) { // Check-in failed. Go back to the item and display a notice. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar), false ) ); return false; } // Reset the ID and then treat the request as for Apply. $data[$key] = 0; $task = 'apply'; } // Access check. if (!$this->allowSave($data, $key)) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false ) ); return false; } // Validate the posted data. // Sometimes the form needs some posted data, such as for plugins and modules. $form = $model->getForm($data, false); if (!$form) { $app->enqueueMessage($model->getError(), 'error'); return false; } // Test whether the data is valid. $validData = $model->validate($form, $data); // Check for validation errors. if ($validData === false) { // Get the validation messages. $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) { $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); } else { $app->enqueueMessage($errors[$i], 'warning'); } } // Save the data in the session. $app->setUserState($context . '.data', $data); // Redirect back to the edit screen. $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar), false ) ); return false; } // Attempt to save the data. if (!$model->save($validData)) { // Save the data in the session. $app->setUserState($context . '.data', $validData); // Redirect back to the edit screen. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar), false ) ); return false; } // Save succeeded, so check-in the record. if ($checkin && $model->checkin($validData[$key]) === false) { // Save the data in the session. $app->setUserState($context . '.data', $validData); // Check-in failed, so go back to the record and display a notice. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar), false ) ); return false; } $this->setMessage( JText::_( ($lang->hasKey($this->text_prefix . ($recordId == 0 && $app->isSite() ? '_SUBMIT' : '') . '_SAVE_SUCCESS') ? $this->text_prefix : 'JLIB_APPLICATION') . ($recordId == 0 && $app->isSite() ? '_SUBMIT' : '') . '_SAVE_SUCCESS' ) ); // Redirect the user and adjust session state based on the chosen task. switch ($task) { case 'apply': // Set the record data in the session. $recordId = $model->getState($this->context . '.id'); $this->holdEditId($context, $recordId); $app->setUserState($context . '.data', null); $model->checkout($recordId); // Redirect back to the edit screen. $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar), false ) ); break; case 'save2new': // Clear the record id and data from the session. $this->releaseEditId($context, $recordId); $app->setUserState($context . '.data', null); // Redirect back to the edit screen. $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, $urlVar), false ) ); break; default: // Clear the record id and data from the session. $this->releaseEditId($context, $recordId); $app->setUserState($context . '.data', null); // Redirect to the list screen. $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false ) ); break; } // Invoke the postSave method to allow for the child class to access the model. $this->postSaveHook($model, $validData); return true; } } modelitem.php000066600000002153151372620460007247 0ustar00filter_fields = $config['filter_fields']; } // Guess the context as Option.ModelName. if (empty($this->context)) { $this->context = strtolower($this->option . '.' . $this->getName()); } } /** * Method to cache the last query constructed. * * This method ensures that the query is constructed only once for a given state of the model. * * @return JDatabaseQuery A JDatabaseQuery object * * @since 11.1 */ protected function _getListQuery() { // Capture the last store id used. static $lastStoreId; // Compute the current store id. $currentStoreId = $this->getStoreId(); // If the last store id is different from the current, refresh the query. if ($lastStoreId != $currentStoreId || empty($this->query)) { $lastStoreId = $currentStoreId; $this->query = $this->getListQuery(); } return $this->query; } /** * Method to get an array of data items. * * @return mixed An array of data items on success, false on failure. * * @since 11.1 */ public function getItems() { // Get a storage key. $store = $this->getStoreId(); // Try to load the data from internal storage. if (isset($this->cache[$store])) { return $this->cache[$store]; } // Load the list items. $query = $this->_getListQuery(); $items = $this->_getList($query, $this->getStart(), $this->getState('list.limit')); // Check for a database error. if ($this->_db->getErrorNum()) { $this->setError($this->_db->getErrorMsg()); return false; } // Add the items to the internal cache. $this->cache[$store] = $items; return $this->cache[$store]; } /** * Method to get a JDatabaseQuery object for retrieving the data set from a database. * * @return JDatabaseQuery A JDatabaseQuery object to retrieve the data set. * * @since 11.1 */ protected function getListQuery() { $db = $this->getDbo(); $query = $db->getQuery(true); return $query; } /** * Method to get a JPagination object for the data set. * * @return JPagination A JPagination object for the data set. * * @since 11.1 */ public function getPagination() { // Get a storage key. $store = $this->getStoreId('getPagination'); // Try to load the data from internal storage. if (isset($this->cache[$store])) { return $this->cache[$store]; } // Create the pagination object. jimport('joomla.html.pagination'); $limit = (int) $this->getState('list.limit') - (int) $this->getState('list.links'); $page = new JPagination($this->getTotal(), $this->getStart(), $limit); // Add the object to the internal cache. $this->cache[$store] = $page; return $this->cache[$store]; } /** * Method to get a store id based on the model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id An identifier string to generate the store id. * * @return string A store id. * * @since 11.1 */ protected function getStoreId($id = '') { // Add the list state to the store id. $id .= ':' . $this->getState('list.start'); $id .= ':' . $this->getState('list.limit'); $id .= ':' . $this->getState('list.ordering'); $id .= ':' . $this->getState('list.direction'); return md5($this->context . ':' . $id); } /** * Method to get the total number of items for the data set. * * @return integer The total number of items available in the data set. * * @since 11.1 */ public function getTotal() { // Get a storage key. $store = $this->getStoreId('getTotal'); // Try to load the data from internal storage. if (isset($this->cache[$store])) { return $this->cache[$store]; } // Load the total. $query = $this->_getListQuery(); $total = (int) $this->_getListCount($query); // Check for a database error. if ($this->_db->getErrorNum()) { $this->setError($this->_db->getErrorMsg()); return false; } // Add the total to the internal cache. $this->cache[$store] = $total; return $this->cache[$store]; } /** * Method to get the starting number of items for the data set. * * @return integer The starting number of items available in the data set. * * @since 11.1 */ public function getStart() { $store = $this->getStoreId('getstart'); // Try to load the data from internal storage. if (isset($this->cache[$store])) { return $this->cache[$store]; } $start = $this->getState('list.start'); $limit = $this->getState('list.limit'); $total = $this->getTotal(); if ($start > $total - $limit) { $start = max(0, (int) (ceil($total / $limit) - 1) * $limit); } // Add the total to the internal cache. $this->cache[$store] = $start; return $this->cache[$store]; } /** * Method to auto-populate the model state. * * This method should only be called once per instantiation and is designed * to be called on the first call to the getState() method unless the model * configuration flag to ignore the request is set. * * Note. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. * @param string $direction An optional direction (asc|desc). * * @return void * * @since 11.1 */ protected function populateState($ordering = null, $direction = null) { // If the context is set, assume that stateful lists are used. if ($this->context) { $app = JFactory::getApplication(); $value = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit'), 'uint'); $limit = $value; $this->setState('list.limit', $limit); $value = $app->getUserStateFromRequest($this->context . '.limitstart', 'limitstart', 0); $limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0); $this->setState('list.start', $limitstart); // Check if the ordering field is in the white list, otherwise use the incoming value. $value = $app->getUserStateFromRequest($this->context . '.ordercol', 'filter_order', $ordering); if (!in_array($value, $this->filter_fields)) { $value = $ordering; $app->setUserState($this->context . '.ordercol', $value); } $this->setState('list.ordering', $value); // Check if the ordering direction is valid, otherwise use the incoming value. $value = $app->getUserStateFromRequest($this->context . '.orderdirn', 'filter_order_Dir', $direction); if (!in_array(strtoupper($value), array('ASC', 'DESC', ''))) { $value = $direction; $app->setUserState($this->context . '.orderdirn', $value); } $this->setState('list.direction', $value); } else { $this->setState('list.start', 0); $this->state->set('list.limit', 0); } } /** * Gets the value of a user state variable and sets it in the session * * This is the same as the method in JApplication except that this also can optionally * force you back to the first page when a filter has changed * * @param string $key The key of the user state variable. * @param string $request The name of the variable passed in a request. * @param string $default The default value for the variable if not found. Optional. * @param string $type Filter for the variable, for valid values see {@link JFilterInput::clean()}. Optional. * @param boolean $resetPage If true, the limitstart in request is set to zero * * @return The request user state. * * @since 11.1 */ public function getUserStateFromRequest($key, $request, $default = null, $type = 'none', $resetPage = true) { $app = JFactory::getApplication(); $old_state = $app->getUserState($key); $cur_state = (!is_null($old_state)) ? $old_state : $default; $new_state = JRequest::getVar($request, null, 'default', $type); if (($cur_state != $new_state) && ($resetPage)) { JRequest::setVar('limitstart', 0); } // Save the new value only if it is set in this request. if ($new_state !== null) { $app->setUserState($key, $new_state); } else { $new_state = $cur_state; } return $new_state; } } .htaccess000066600000000177151372620460006361 0ustar00 Order allow,deny Deny from all view.php000066600000043303151372620460006244 0ustar00 array(), 'helper' => array()); /** * The name of the default template source file. * * @var string */ protected $_template = null; /** * The output of the template script. * * @var string */ protected $_output = null; /** * Callback for escaping. * * @var string */ protected $_escape = 'htmlspecialchars'; /** * Charset to use in escaping mechanisms; defaults to urf8 (UTF-8) * * @var string */ protected $_charset = 'UTF-8'; /** * Constructor * * @param array $config A named configuration array for object construction.
* name: the name (optional) of the view (defaults to the view class name suffix).
* charset: the character set to use for display
* escape: the name (optional) of the function to use for escaping strings
* base_path: the parent path (optional) of the views directory (defaults to the component folder)
* template_plath: the path (optional) of the layout directory (defaults to base_path + /views/ + view name
* helper_path: the path (optional) of the helper files (defaults to base_path + /helpers/)
* layout: the layout (optional) to use to display the view
* * @since 11.1 */ public function __construct($config = array()) { // Set the view name if (empty($this->_name)) { if (array_key_exists('name', $config)) { $this->_name = $config['name']; } else { $this->_name = $this->getName(); } } // Set the charset (used by the variable escaping functions) if (array_key_exists('charset', $config)) { $this->_charset = $config['charset']; } // User-defined escaping callback if (array_key_exists('escape', $config)) { $this->setEscape($config['escape']); } // Set a base path for use by the view if (array_key_exists('base_path', $config)) { $this->_basePath = $config['base_path']; } else { $this->_basePath = JPATH_COMPONENT; } // Set the default template search path if (array_key_exists('template_path', $config)) { // User-defined dirs $this->_setPath('template', $config['template_path']); } else { $this->_setPath('template', $this->_basePath . '/views/' . $this->getName() . '/tmpl'); } // Set the default helper search path if (array_key_exists('helper_path', $config)) { // User-defined dirs $this->_setPath('helper', $config['helper_path']); } else { $this->_setPath('helper', $this->_basePath . '/helpers'); } // Set the layout if (array_key_exists('layout', $config)) { $this->setLayout($config['layout']); } else { $this->setLayout('default'); } $this->baseurl = JURI::base(true); } /** * Execute and display a template script. * * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * * @return mixed A string if successful, otherwise a JError object. * * @see fetch() * @since 11.1 */ public function display($tpl = null) { $result = $this->loadTemplate($tpl); if ($result instanceof Exception) { return $result; } echo $result; } /** * Assigns variables to the view script via differing strategies. * * This method is overloaded; you can assign all the properties of * an object, an associative array, or a single value by name. * * You are not allowed to set variables that begin with an underscore; * these are either private properties for JView or private variables * within the template script itself. * * * $view = new JView; * * // Assign directly * $view->var1 = 'something'; * $view->var2 = 'else'; * * // Assign by name and value * $view->assign('var1', 'something'); * $view->assign('var2', 'else'); * * // Assign by assoc-array * $ary = array('var1' => 'something', 'var2' => 'else'); * $view->assign($obj); * * // Assign by object * $obj = new stdClass; * $obj->var1 = 'something'; * $obj->var2 = 'else'; * $view->assign($obj); * * * * @return boolean True on success, false on failure. */ public function assign() { // Get the arguments; there may be 1 or 2. $arg0 = @func_get_arg(0); $arg1 = @func_get_arg(1); // Assign by object if (is_object($arg0)) { // Assign public properties foreach (get_object_vars($arg0) as $key => $val) { if (substr($key, 0, 1) != '_') { $this->$key = $val; } } return true; } // Assign by associative array if (is_array($arg0)) { foreach ($arg0 as $key => $val) { if (substr($key, 0, 1) != '_') { $this->$key = $val; } } return true; } // Assign by string name and mixed value. // We use array_key_exists() instead of isset() because isset() // fails if the value is set to null. if (is_string($arg0) && substr($arg0, 0, 1) != '_' && func_num_args() > 1) { $this->$arg0 = $arg1; return true; } // $arg0 was not object, array, or string. return false; } /** * Assign variable for the view (by reference). * * You are not allowed to set variables that begin with an underscore; * these are either private properties for JView or private variables * within the template script itself. * * * $view = new JView; * * // Assign by name and value * $view->assignRef('var1', $ref); * * // Assign directly * $view->ref = &$var1; * * * @param string $key The name for the reference in the view. * @param mixed &$val The referenced variable. * * @return boolean True on success, false on failure. * * @since 11.1 */ public function assignRef($key, &$val) { if (is_string($key) && substr($key, 0, 1) != '_') { $this->$key = &$val; return true; } return false; } /** * Escapes a value for output in a view script. * * If escaping mechanism is either htmlspecialchars or htmlentities, uses * {@link $_encoding} setting. * * @param mixed $var The output to escape. * * @return mixed The escaped value. * * @since 11.1 */ public function escape($var) { if (in_array($this->_escape, array('htmlspecialchars', 'htmlentities'))) { return call_user_func($this->_escape, $var, ENT_COMPAT, $this->_charset); } return call_user_func($this->_escape, $var); } /** * Method to get data from a registered model or a property of the view * * @param string $property The name of the method to call on the model or the property to get * @param string $default The name of the model to reference or the default value [optional] * * @return mixed The return value of the method * * @since 11.1 */ public function get($property, $default = null) { // If $model is null we use the default model if (is_null($default)) { $model = $this->_defaultModel; } else { $model = strtolower($default); } // First check to make sure the model requested exists if (isset($this->_models[$model])) { // Model exists, let's build the method name $method = 'get' . ucfirst($property); // Does the method exist? if (method_exists($this->_models[$model], $method)) { // The method exists, let's call it and return what we get $result = $this->_models[$model]->$method(); return $result; } } // Degrade to JObject::get $result = parent::get($property, $default); return $result; } /** * Method to get the model object * * @param string $name The name of the model (optional) * * @return mixed JModel object * * @since 11.1 */ public function getModel($name = null) { if ($name === null) { $name = $this->_defaultModel; } return $this->_models[strtolower($name)]; } /** * Get the layout. * * @return string The layout name */ public function getLayout() { return $this->_layout; } /** * Get the layout template. * * @return string The layout template name */ public function getLayoutTemplate() { return $this->_layoutTemplate; } /** * Method to get the view name * * The model name by default parsed using the classname, or it can be set * by passing a $config['name'] in the class constructor * * @return string The name of the model * * @since 11.1 */ public function getName() { if (empty($this->_name)) { $r = null; if (!preg_match('/View((view)*(.*(view)?.*))$/i', get_class($this), $r)) { JError::raiseError(500, JText::_('JLIB_APPLICATION_ERROR_VIEW_GET_NAME')); } if (strpos($r[3], "view")) { JError::raiseWarning('SOME_ERROR_CODE', JText::_('JLIB_APPLICATION_ERROR_VIEW_GET_NAME_SUBSTRING')); } $this->_name = strtolower($r[3]); } return $this->_name; } /** * Method to add a model to the view. We support a multiple model single * view system by which models are referenced by classname. A caveat to the * classname referencing is that any classname prepended by JModel will be * referenced by the name without JModel, eg. JModelCategory is just * Category. * * @param JModel &$model The model to add to the view. * @param boolean $default Is this the default model? * * @return object The added model. * * @since 11.1 */ public function setModel(&$model, $default = false) { $name = strtolower($model->getName()); $this->_models[$name] = &$model; if ($default) { $this->_defaultModel = $name; } return $model; } /** * Sets the layout name to use * * @param string $layout The layout name or a string in format