/administrator/components/com_modules/models/module.php
PHP | 741 lines | 442 code | 101 blank | 198 comment | 68 complexity | 424cb8931044be8616b8f5dbc73db83b MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
- <?php
- /**
- * @version $Id$
- * @package Joomla.Administrator
- * @subpackage Modules
- * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
- * @license GNU General Public License version 2 or later; see LICENSE.txt
- */
- // No direct access.
- defined('_JEXEC') or die;
- jimport('joomla.application.component.modelform');
- /**
- * Module model.
- *
- * @package Joomla.Administrator
- * @subpackage com_modules
- * @since 1.6
- */
- class ModulesModelModule extends JModelForm
- {
- /**
- * Item cache.
- */
- private $_cache = array();
- /**
- * Method to auto-populate the model state.
- */
- protected function _populateState()
- {
- $app = JFactory::getApplication('administrator');
- // Load the User state.
- if (!($pk = (int) $app->getUserState('com_modules.edit.module.id')))
- {
- if ($extensionId = (int) $app->getUserState('com_modules.add.module.extension_id'))
- {
- $this->setState('extension.id', $extensionId);
- }
- else
- {
- $pk = (int) JRequest::getInt('id');
- }
- }
- $this->setState('module.id', $pk);
- // Load the parameters.
- $params = JComponentHelper::getParams('com_modules');
- $this->setState('params', $params);
- }
- /**
- * Prepare and sanitise the table prior to saving.
- */
- protected function _prepareTable(&$table)
- {
- jimport('joomla.filter.output');
- $date = JFactory::getDate();
- $user = JFactory::getUser();
- $table->title = htmlspecialchars_decode($table->title, ENT_QUOTES);
- if (empty($table->id)) {
- // Set the values
- //$table->created = $date->toMySQL();
- }
- else {
- // Set the values
- //$table->modified = $date->toMySQL();
- //$table->modified_by = $user->get('id');
- }
- }
- /**
- * Returns a reference to the a Table object, always creating it.
- *
- * @param type $type The table type to instantiate
- * @param string $prefix A prefix for the table class name. Optional.
- * @param array $options Configuration array for model. Optional.
- * @return JTable A database object
- */
- public function getTable($type = 'Module', $prefix = 'JTable', $config = array())
- {
- return JTable::getInstance($type, $prefix, $config);
- }
- /**
- * Method to override check-out a row for editing.
- *
- * @param int The ID of the primary key.
- * @return boolean
- */
- public function checkout($pk = null)
- {
- // Initialise variables.
- $pk = (!empty($pk)) ? $pk : (int) $this->getState('module.id');
- return parent::checkout($pk);
- }
- /**
- * Method to checkin a row.
- *
- * @param integer The ID of the primary key.
- *
- * @return boolean
- */
- public function checkin($pk = null)
- {
- // Initialise variables.
- $pk = (!empty($pk)) ? $pk : (int) $this->getState('module.id');
- return parent::checkin($pk);
- }
- /**
- * Method to get a single record.
- *
- * @param integer The id of the primary key.
- *
- * @return mixed Object on success, false on failure.
- */
- public function &getItem($pk = null)
- {
- // Initialise variables.
- $pk = (!empty($pk)) ? (int) $pk : (int) $this->getState('module.id');
- if (!isset($this->_cache[$pk])) {
- $false = false;
- // Get a row instance.
- $table = &$this->getTable();
- // Attempt to load the row.
- $return = $table->load($pk);
- // Check for a table object error.
- if ($return === false && $error = $table->getError()) {
- $this->setError($error);
- return $false;
- }
- // Check if we are creating a new extension.
- if (empty($pk)) {
- if ($extensionId = (int) $this->getState('extension.id')) {
- jimport('joomla.database.query');
- $query = new JQuery;
- $query->select('element, client_id');
- $query->from('#__extensions');
- $query->where('extension_id = '.$extensionId);
- $query->where('type = '.$this->_db->quote('module'));
- $this->_db->setQuery($query);
- $extension = $this->_db->loadObject();
- if (empty($extension)) {
- if ($error = $this->_db->getErrorMsg()) {
- $this->setError($error);
- } else {
- $this->setError('Modules_Error_Cannot_find_extension');
- }
- return false;
- }
- // Extension found, prime some module values.
- $table->module = $extension->element;
- $table->client_id = $extension->client_id;
- } else {
- $this->setError('Modules_Error_Cannot_get_item');
- return false;
- }
- }
- // Convert to the JObject before adding other data.
- $this->_cache[$pk] = JArrayHelper::toObject($table->getProperties(1), 'JObject');
- // Convert the params field to an array.
- $registry = new JRegistry;
- $registry->loadJSON($table->params);
- $this->_cache[$pk]->params = $registry->toArray();
- // Determine the page assignment mode.
- $this->_db->setQuery(
- 'SELECT menuid' .
- ' FROM #__modules_menu' .
- ' WHERE moduleid = '.$pk
- );
- $assigned = $this->_db->loadResultArray();
- if (empty($pk)) {
- // If this is a new module, assign to all pages.
- $assignment = 0;
- } else if (empty($assigned)) {
- // For an existing module it is assigned to none.
- $assignment = '-';
- }
- else {
- if ($assigned[0] > 0) {
- $assignment = +1;
- } else if ($assigned[0] < 0) {
- $assignment = -1;
- } else {
- $assignment = 0;
- }
- }
- $this->_cache[$pk]->assigned = $assigned;
- $this->_cache[$pk]->assignment = $assignment;
- // Get the module XML.
- $client = JApplicationHelper::getClientInfo($table->client_id);
- $path = JPath::clean($client->path.'/modules/'.$table->module.'/'.$table->module.'.xml');
- if (file_exists($path)) {
- $this->_cache[$pk]->xml = simplexml_load_file($path);
- } else {
- $this->_cache[$pk]->xml = null;
- }
- }
- return $this->_cache[$pk];
- }
- /**
- * Method to get the client object
- *
- * @since 1.6
- */
- function &getClient()
- {
- return $this->_client;
- }
- /**
- * Method to get the record form.
- *
- * @return mixed JForm object on success, false on failure.
- */
- public function getForm()
- {
- // Initialise variables.
- $app = JFactory::getApplication();
- // Get the form.
- $form = parent::getForm('module', 'com_modules.module', array('array' => 'jform', 'event' => 'onPrepareForm'));
- // Check for an error.
- if (JError::isError($form)) {
- $this->setError($form->getMessage());
- return false;
- }
- // Check the session for previously entered form data.
- $data = $app->getUserState('com_modules.edit.module.data', array());
- // Bind the form data if present.
- if (!empty($data)) {
- $form->bind($data);
- }
- return $form;
- }
- /**
- * Method to get a form object for the module params.
- *
- * @param string An optional module folder.
- * @param int An client id.
- *
- * @return mixed A JForm object on success, false on failure.
- */
- public function getParamsForm($module = null, $clientId = null)
- {
- jimport('joomla.filesystem.file');
- jimport('joomla.filesystem.folder');
- // Initialise variables.
- $lang = JFactory::getLanguage();
- $form = null;
- $formName = 'com_modules.module.params';
- $formOptions = array('array' => 'jformparams', 'event' => 'onPrepareForm');
- if (empty($module) && is_null($clientId))
- {
- $item = $this->getItem();
- $clientId = $item->client_id;
- $module = $item->module;
- }
- $client = JApplicationHelper::getClientInfo($clientId);
- $formFile = JPath::clean($client->path.'/modules/'.$module.'/'.$module.'.xml');
- // Load the core and/or local language file(s).
- $lang->load($module, $client->path.'/modules/'.$module);
- $lang->load($module, $client->path);
- if (file_exists($formFile))
- {
- // If an XML file was found in the component, load it first.
- // We need to qualify the full path to avoid collisions with component file names.
- $form = parent::getForm($formFile, $formName, $formOptions, true);
- // Check for an error.
- if (JError::isError($form)) {
- $this->setError($form->getMessage());
- return false;
- }
- }
- return $form;
- }
- /**
- * Method to save the form data.
- *
- * @param array The form data.
- * @return boolean True on success.
- */
- public function save($data)
- {
- // Initialise variables;
- $dispatcher = JDispatcher::getInstance();
- $table = $this->getTable();
- $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('module.id');
- $isNew = true;
- // Include the content modules for the onSave events.
- JPluginHelper::importPlugin('content');
- // 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(JText::sprintf('JTable_Error_Bind_failed', $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 onBeforeSaveContent event.
- $result = $dispatcher->trigger('onBeforeContentSave', array(&$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;
- }
- //
- // Process the menu link mappings.
- //
- $assignment = isset($data['assignment']) ? $data['assignment'] : 0;
- // Delete old module to menu item associations
- // $this->_db->setQuery(
- // 'DELETE FROM #__modules_menu'.
- // ' WHERE moduleid = '.(int) $table->id
- // );
-
- $query = new JQuery;
- $query->delete();
- $query->from('#__modules_menu');
- $query->where('moduleid='.(int)$table->id);
- $this->_db->setQuery((string)$query);
- $this->_db->query();
-
- if (!$this->_db->query())
- {
- $this->setError($this->_db->getErrorMsg());
- return false;
- }
- // If the assignment is numeric, then something is selected (otherwise it's none).
- if (is_numeric($assignment))
- {
- // Variable is numeric, but could be a string.
- $assignment = (int) $assignment;
- // Check needed to stop a module being assigned to `All`
- // and other menu items resulting in a module being displayed twice.
- if ($assignment === 0)
- {
- // assign new module to `all` menu item associations
- // $this->_db->setQuery(
- // 'INSERT INTO #__modules_menu'.
- // ' SET moduleid = '.(int) $table->id.', menuid = 0'
- // );
-
- $query = new JQuery;
- $query->insert('#__modules_menu');
- $query->set('moduleid='.(int)$table->id);
- $query->set('menuid=0');
- $this->_db->setQuery((string)$query);
- if (!$this->_db->query())
- {
- $this->setError($this->_db->getErrorMsg());
- return false;
- }
- }
- else if (!empty($data['assigned']))
- {
- // Get the sign of the number.
- $sign = $assignment < 0 ? -1 : +1;
- // Preprocess the assigned array.
- $tuples = array();
- foreach ($data['assigned'] as &$pk)
- {
- $tuples[] = '('.(int) $table->id.','.(int) $pk * $sign.')';
- }
- $this->_db->setQuery(
- 'INSERT INTO #__modules_menu (moduleid, menuid) VALUES '.
- implode(',', $tuples)
- );
- if (!$this->_db->query())
- {
- $this->setError($this->_db->getErrorMsg());
- return false;
- }
- }
- }
- // Clean the cache.
- $cache = JFactory::getCache('com_modules');
- $cache->clean();
- // Trigger the onAfterContentSave event.
- $dispatcher->trigger('onAfterContentSave', array(&$table, $isNew));
- $this->setState('module.id', $table->id);
- return true;
- }
- /**
- * Method to delete rows.
- *
- * @param array An array of item ids.
- *
- * @return boolean Returns true on success, false on failure.
- */
- public function delete(&$pks)
- {
- // Initialise variables.
- $pks = (array) $pks;
- $user = JFactory::getUser();
- $table = $this->getTable();
- // Iterate the items to delete each one.
- foreach ($pks as $i => $pk)
- {
- if ($table->load($pk))
- {
- // Access checks.
- if (!$user->authorise('core.delete', 'com_modules'))
- {
- throw new Exception(JText::_('JError_Core_Delete_not_permitted'));
- }
- if (!$table->delete($pk))
- {
- throw new Exception($table->getError());
- } else {
- // Delete the menu assignments
- $query = new JQuery;
- $query->delete();
- $query->from('#__modules_menu');
- $query->where('moduleid='.(int)$pk);
- $this->_db->setQuery((string)$query);
- $this->_db->query();
- }
- }
- else
- {
- throw new Exception($table->getError());
- }
- }
- return true;
- }
- /**
- * Method to publish records.
- *
- * @param array The ids of the items to publish.
- * @param int The value of the published state
- *
- * @return boolean True on success.
- */
- function publish(&$pks, $value = 1)
- {
- // Initialise variables.
- $user = JFactory::getUser();
- $table = $this->getTable();
- $pks = (array) $pks;
- // Access checks.
- foreach ($pks as $i => $pk)
- {
- if ($table->load($pk))
- {
- $allow = $user->authorise('core.edit.state', 'com_modules');
- if (!$allow)
- {
- // Prune items that you can't change.
- unset($pks[$i]);
- JError::raiseWarning(403, JText::_('JError_Core_Edit_State_not_permitted'));
- }
- }
- }
- // Attempt to change the state of the records.
- if (!$table->publish($pks, $value, $user->get('id'))) {
- $this->setError($table->getError());
- return false;
- }
- return true;
- }
- /**
- * Method to duplicate modules.
- *
- * @param array An array of primary key IDs.
- *
- * @return boolean True if successful.
- * @throws Exception
- */
- public function duplicate(&$pks)
- {
- // Initialise variables.
- $user = JFactory::getUser();
- $db = $this->getDbo();
- // Access checks.
- if (!$user->authorise('core.create', 'com_modules'))
- {
- throw new Exception(JText::_('JError_Core_Create_not_permitted'));
- }
- $table = $this->getTable();
- foreach ($pks as $pk)
- {
- if ($table->load($pk, true))
- {
- // Reset the id to create a new record.
- $table->id = 0;
- // Alter the title.
- $m = null;
- if (preg_match('#\((\d+)\)$#', $table->title, $m))
- {
- $table->title = preg_replace('#\(\d+\)$#', '('.($m[1] + 1).')', $table->title);
- }
- else
- {
- $table->title .= ' (2)';
- }
- if (!$table->check() || !$table->store()) {
- throw new Exception($table->getError());
- }
- // $query = 'SELECT menuid'
- // . ' FROM #__modules_menu'
- // . ' WHERE moduleid = '.(int) $pk
- // ;
-
- $query = new JQuery;
- $query->select('menuid');
- $query->from('#__modules_menu');
- $query->where('moduleid='.(int)$pk);
-
- $this->_db->setQuery((string)$query);
- $rows = $this->_db->loadResultArray();
- foreach ($rows as $menuid) {
- $tuples[] = '('.(int) $table->id.','.(int) $menuid.')';
- }
- }
- else
- {
- throw new Exception($table->getError());
- }
- }
- if (!empty($tuples))
- {
- // Module-Menu Mapping: Do it in one query
- $query = 'INSERT INTO #__modules_menu (moduleid,menuid) VALUES '.implode(',', $tuples);
- $this->_db->setQuery($query);
- if (!$this->_db->query()) {
- return JError::raiseWarning(500, $row->getError());
- }
- }
- return true;
- }
- /**
- * Method to adjust the ordering of a row.
- *
- * @param int The ID of the primary key to move.
- * @param integer Increment, usually +1 or -1
- * @return boolean False on failure or error, true otherwise.
- */
- public function reorder($pks, $delta = 0)
- {
- // Initialise variables.
- $user = JFactory::getUser();
- $table = $this->getTable();
- $pks = (array) $pks;
- $result = true;
- // Access checks.
- $allow = $user->authorise('core.edit', 'com_modules');
- if (!$allow)
- {
- $this->setError(JText::_('JError_Core_Edit_not_permitted'));
- return false;
- }
- foreach ($pks as $i => $pk)
- {
- $table->reset();
- if ($table->load($pk) && $this->checkout($pk))
- {
- $table->ordering += $delta;
- if (!$table->store())
- {
- $this->setError($table->getError());
- unset($pks[$i]);
- $result = false;
- }
- }
- else
- {
- $this->setError($table->getError());
- unset($pks[$i]);
- $result = false;
- }
- }
- return $result;
- }
- /**
- * Saves the manually set order of records.
- *
- * @param array An array of primary key ids.
- * @param int +/-1
- */
- function saveorder($pks, $order)
- {
- // Initialise variables.
- $table = $this->getTable();
- $conditions = array();
- if (empty($pks)) {
- return JError::raiseWarning(500, JText::_('JError_No_items_selected'));
- }
- // update ordering values
- foreach ($pks as $i => $pk)
- {
- $table->load((int) $pk);
- // Access checks.
- $allow = $user->authorise('core.edit.state', 'com_modules');
- if (!$allow)
- {
- // Prune items that you can't change.
- unset($pks[$i]);
- JError::raiseWarning(403, JText::_('JError_Core_Edit_State_not_permitted'));
- }
- else if ($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[] = 'client_id = '.(int) $table->client_id;
- $condition[] = 'position = '.(int) $table->position;
- $found = false;
- foreach ($conditions as $cond)
- {
- if ($cond[1] == $condition)
- {
- $found = true;
- break;
- }
- }
- if (!$found) {
- $conditions[] = array ($table->id, $condition);
- }
- }
- }
- // Execute reorder for each category.
- foreach ($conditions as $cond)
- {
- $table->load($cond[0]);
- $table->reorder($cond[1]);
- }
- // Clear the component's cache
- $cache = JFactory::getCache('com_modules');
- $cache->clean();
- return true;
- }
- }