/** * Constructor. * * @param string $name The event name. * @param array $arguments The event arguments. * * @throws BadMethodCallException * * @since __DEPLOY_VERSION__ */ public function __construct($name, array $arguments = array()) { if ($this->constructed) { throw new BadMethodCallException(sprintf('Cannot reconstruct the AbstractImmutableEvent %s.', $this->name)); } $this->constructed = true; parent::__construct($name, $arguments); }
/** * Method to store a node in the database table. * * @param boolean $updateNulls True to update null values as well. * * @return boolean True on success. * * @since 11.1 */ public function store($updateNulls = false) { $k = $this->_tbl_key; // Pre-processing by observers $event = AbstractEvent::create('onTableBeforeStore', ['subject' => $this, 'updateNulls' => $updateNulls, 'k' => $k]); $this->getDispatcher()->dispatch('onTableBeforeStore', $event); // @codeCoverageIgnoreStart if ($this->_debug) { echo "\n" . get_class($this) . "::store\n"; $this->_logtable(true, false); } // @codeCoverageIgnoreEnd /* * If the primary key is empty, then we assume we are inserting a new node into the * tree. From this point we would need to determine where in the tree to insert it. */ if (empty($this->{$k})) { /* * We are inserting a node somewhere in the tree with a known reference * node. We have to make room for the new node and set the left and right * values before we insert the row. */ if ($this->_location_id >= 0) { // Lock the table for writing. if (!$this->_lock()) { // Error message set in lock method. return false; } // We are inserting a node relative to the last root node. if ($this->_location_id == 0) { // Get the last root node as the reference node. $query = $this->_db->getQuery(true)->select($this->_tbl_key . ', parent_id, level, lft, rgt')->from($this->_tbl)->where('parent_id = 0')->order('lft DESC'); $this->_db->setQuery($query, 0, 1); $reference = $this->_db->loadObject(); // @codeCoverageIgnoreStart if ($this->_debug) { $this->_logtable(false); } // @codeCoverageIgnoreEnd } else { // Get the reference node by primary key. if (!($reference = $this->_getNode($this->_location_id))) { // Error message set in getNode method. $this->_unlock(); return false; } } // Get the reposition data for shifting the tree and re-inserting the node. if (!($repositionData = $this->_getTreeRepositionData($reference, 2, $this->_location))) { // Error message set in getNode method. $this->_unlock(); return false; } // Create space in the tree at the new location for the new node in left ids. $query = $this->_db->getQuery(true)->update($this->_tbl)->set('lft = lft + 2')->where($repositionData->left_where); $this->_runQuery($query, 'JLIB_DATABASE_ERROR_STORE_FAILED'); // Create space in the tree at the new location for the new node in right ids. $query->clear()->update($this->_tbl)->set('rgt = rgt + 2')->where($repositionData->right_where); $this->_runQuery($query, 'JLIB_DATABASE_ERROR_STORE_FAILED'); // Set the object values. $this->parent_id = $repositionData->new_parent_id; $this->level = $repositionData->new_level; $this->lft = $repositionData->new_lft; $this->rgt = $repositionData->new_rgt; } else { // Negative parent ids are invalid $e = new UnexpectedValueException(sprintf('%s::store() used a negative _location_id', get_class($this))); $this->setError($e); return false; } } else { // If the location has been set, move the node to its new location. if ($this->_location_id > 0) { if (!$this->moveByReference($this->_location_id, $this->_location, $this->{$k})) { // Error message set in move method. return false; } } // Lock the table for writing. if (!$this->_lock()) { // Error message set in lock method. return false; } } // We do not want parent::store to update observers since tables are locked and we are updating it from this // level of store(): $oldDispatcher = clone $this->getDispatcher(); $blankDispatcher = new Dispatcher(); $this->setDispatcher($blankDispatcher); $result = parent::store($updateNulls); $this->setDispatcher($oldDispatcher); if ($result) { // @codeCoverageIgnoreStart if ($this->_debug) { $this->_logtable(); } // @codeCoverageIgnoreEnd } // Unlock the table for writing. $this->_unlock(); // Post-processing by observers $event = AbstractEvent::create('onTableAfterStore', ['subject' => $this, 'result' => &$result]); $this->getDispatcher()->dispatch('onTableAfterStore', $event); return $result; }
/** * Method to set the publishing state for a row or list of rows in the database table. * * The method respects checked out rows by other users and will attempt to checkin rows that it can after adjustments are made. * * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] * @param integer $userId The user ID of the user performing the operation. * * @return boolean True on success; false if $pks is empty. * * @since 11.1 */ public function publish($pks = null, $state = 1, $userId = 0) { // Sanitize input $userId = (int) $userId; $state = (int) $state; // Pre-processing by observers $event = AbstractEvent::create('onTableBeforePublish', ['subject' => $this, 'pks' => $pks, 'state' => $state, 'userId' => $userId]); $this->getDispatcher()->dispatch('onTableBeforePublish', $event); if (!is_null($pks)) { if (!is_array($pks)) { $pks = array($pks); } foreach ($pks as $key => $pk) { if (!is_array($pk)) { $pks[$key] = array($this->_tbl_key => $pk); } } } // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { $pk = array(); foreach ($this->_tbl_keys as $key) { if ($this->{$key}) { $pk[$key] = $this->{$key}; } else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } $pks = array($pk); } $publishedField = $this->getColumnAlias('published'); $checkedOutField = $this->getColumnAlias('checked_out'); foreach ($pks as $pk) { // Update the publishing state for rows with the given primary keys. $query = $this->_db->getQuery(true)->update($this->_tbl)->set($this->_db->quoteName($publishedField) . ' = ' . (int) $state); // If publishing, set published date/time if not previously set if ($state && property_exists($this, 'publish_up') && (int) $this->publish_up == 0) { $nowDate = $this->_db->quote(JFactory::getDate()->toSql()); $query->set($this->_db->quoteName($this->getColumnAlias('publish_up')) . ' = ' . $nowDate); } // Determine if there is checkin support for the table. if (property_exists($this, 'checked_out') || property_exists($this, 'checked_out_time')) { $query->where('(' . $this->_db->quoteName($checkedOutField) . ' = 0 OR ' . $this->_db->quoteName($checkedOutField) . ' = ' . (int) $userId . ')'); $checkin = true; } else { $checkin = false; } // Build the WHERE clause for the primary keys. $this->appendPrimaryKeys($query, $pk); $this->_db->setQuery($query); try { $this->_db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // If checkin is supported and all rows were adjusted, check them in. if ($checkin && count($pks) == $this->_db->getAffectedRows()) { $this->checkin($pk); } // If the JTable instance value is in the list of primary keys that were set, set the instance. $ours = true; foreach ($this->_tbl_keys as $key) { if ($this->{$key} != $pk[$key]) { $ours = false; } } if ($ours) { $this->{$publishedField} = $state; } } $this->setError(''); // Pre-processing by observers $event = AbstractEvent::create('onTableAfterPublish', ['subject' => $this, 'pks' => $pks, 'state' => $state, 'userId' => $userId]); $this->getDispatcher()->dispatch('onTableAfterPublish', $event); return true; }
/** * Execute the application. * * @return void * * @since 3.2 */ public function execute() { JPluginHelper::importPlugin('system'); // Trigger the onBeforeExecute event. $this->triggerEvent('onBeforeExecute', AbstractEvent::create('onBeforeExecute', ['subject' => $this, 'eventClass' => BeforeExecuteEvent::class])); // Mark beforeExecute in the profiler. JDEBUG ? $this->profiler->mark('beforeExecute event dispatched') : null; // Perform application routines. $this->doExecute(); // If we have an application document object, render it. if ($this->document instanceof JDocument) { // Render the application output. $this->render(); } // If gzip compression is enabled in configuration and the server is compliant, compress the output. if ($this->get('gzip') && !ini_get('zlib.output_compression') && ini_get('output_handler') != 'ob_gzhandler') { $this->compress(); // Trigger the onAfterCompress event. $this->triggerEvent('onAfterCompress'); } // Send the application response. $this->respond(); // Trigger the onAfterRespond event. $this->triggerEvent('onAfterRespond'); }