/** * DOCUMENT ME * @param mixed $arguments * @param mixed $options */ protected function execute($arguments = array(), $options = array()) { // initialize the database connection $databaseManager = new sfDatabaseManager($this->configuration); $connection = $databaseManager->getDatabase($options['connection'] ? $options['connection'] : null)->getConnection(); // PDO connection not so useful, get the doctrine one $conn = Doctrine_Manager::connection(); if ($options['table'] === 'aPage') { $q = Doctrine::getTable('aLuceneUpdate')->createQuery('u'); } else { $q = Doctrine::getTable($options['table'])->createQuery('o')->where('o.lucene_dirty IS TRUE'); } if ($options['limit'] !== false) { $q->limit($options['limit'] + 0); } $updates = $q->execute(); $i = 0; foreach ($updates as $update) { $i++; if ($options['table'] === 'aPage') { $page = aPageTable::retrieveByIdWithSlots($update->page_id, $update->culture); // Careful, pages die if ($page) { $page->updateLuceneIndex(); } $update->delete(); } else { // The actual object $update->updateLuceneIndex(); $update->lucene_dirty = false; $update->save(); } } }
public static function preExecute($actions) { $request = $actions->getRequest(); // Figure out where we are all over again, because there seems to be no clean way // to get the same controller-free URL that the routing engine gets. TODO: // ask Fabien how we can do that. $uri = $actions->getRequest()->getUri(); $uriPrefix = $actions->getRequest()->getUriPrefix(); $uri = substr($uri, strlen($uriPrefix)); if (preg_match("/^\\/[^\\/]+\\.php(.*)\$/", $uri, $matches)) { $uri = $matches[1]; } // This will quickly fetch a result that was already cached when we // ran through the routing table (unless we hit the routing table cache, // in which case we're looking it up for the first time, also OK) $page = aPageTable::getMatchingEnginePage($uri, $remainder); if (!$page) { throw new sfException('Attempt to access engine action without a page'); } $page = aPageTable::retrieveByIdWithSlots($page->id); // We want to do these things the same way executeShow would aTools::validatePageAccess($actions, $page); aTools::setPageEnvironment($actions, $page); // Convenient access to the current page for the subclass $actions->page = $page; }
/** * Poor man's multiple inheritance. This allows us to subclass an existing * actions class in order to create an engine version of it. See aEngineActions * for the call to add to your own preExecute method * @param mixed $actions */ public static function preExecute($actions) { $request = $actions->getRequest(); // Figure out where we are all over again, because there seems to be no clean way // to get the same controller-free URL that the routing engine gets. TODO: // ask Fabien how we can do that. $uri = urldecode($actions->getRequest()->getUri()); $rr = preg_quote(sfContext::getInstance()->getRequest()->getRelativeUrlRoot(), '/'); if (preg_match("/^(?:https?:\\/\\/[^\\/]+)?{$rr}(?:\\/[^\\/]+\\.php)?(.*)\$/", $uri, $matches)) { $uri = $matches[1]; } else { throw new sfException("Unable to parse engine URL {$uri}"); } // This will quickly fetch a result that was already cached when we // ran through the routing table (unless we hit the routing table cache, // in which case we're looking it up for the first time, also OK) $page = aPageTable::getMatchingEnginePageInfo($uri, $remainder); if (!$page) { throw new sfException('Attempt to access engine action without a page'); } $page = aPageTable::retrieveByIdWithSlots($page['id']); // We want to do these things the same way executeShow would aTools::validatePageAccess($actions, $page); aTools::setPageEnvironment($actions, $page); // Convenient access to the current page for the subclass $actions->page = $page; // If your engine supports allowing the user to choose from several page types // to distinguish different ways of using your engine, then you'll need to // return the template name from your show and index actions (and perhaps // others as appropriate). You can pull that information straight from // $this->page->template, or you can take advantage of $this->pageTemplate which // is ready to return as the result of an action (default has been changed // to Success, other values have their first letter capitalized) $templates = aTools::getTemplates(); // originalTemplate is what's in the template field of the page, except that // nulls and empty strings from pre-1.5 Apostrophe have been converted to 'default' // for consistency $actions->originalTemplate = $page->template; if (!strlen($actions->originalTemplate)) { // Compatibility with 1.4 templates and reasonable Symfony expectations $actions->originalTemplate = 'default'; } // pageTemplate is suitable to return from an action. 'default' becomes 'Success' // (the Symfony standard for a "normal" template's suffix) and other values have // their first letter capitalized if ($actions->originalTemplate === 'default') { $actions->pageTemplate = 'Success'; } else { $actions->pageTemplate = ucfirst($actions->originalTemplate); } }
protected function execute($arguments = array(), $options = array()) { // initialize the database connection $databaseManager = new sfDatabaseManager($this->configuration); $connection = $databaseManager->getDatabase($options['connection'] ? $options['connection'] : null)->getConnection(); // PDO connection not so useful, get the doctrine one $conn = Doctrine_Manager::connection(); $updates = $conn->getTable("aLuceneUpdate")->findAll(); foreach ($updates as $update) { $page = aPageTable::retrieveByIdWithSlots($update->page_id, $update->culture); // Careful, pages die if ($page) { $page->updateLuceneIndex(); } $update->delete(); } }
/** * Rights to edit an area are determined at rendering time and then cached in the session. * This allows an edit option to be passed to a_slot and a_area which is crucial for the * proper functioning of virtual pages that edit areas related to concepts external to the * CMS, such as user biographies * @return mixed */ protected function retrievePageForAreaEditing() { $id = $this->getRequestParameter('id'); $page = aPageTable::retrieveByIdWithSlots($id); $this->flunkUnless($page); $name = $this->getRequestParameter('name'); $options = $this->getUser()->getAttribute("area-options-{$id}-{$name}", null, 'apostrophe'); $this->flunkUnless(isset($options['edit']) && $options['edit']); $this->page = $page; $this->name = $name; return $page; }
public function newAreaVersion($name, $action, $params = false) { $diff = ''; if ($params === false) { $params = array(); } $this->begin(); // We use the slots already queried as a basis for the new version, // because that makes rollback easy to implement etc. But we // MUST fetch the latest copy of the area object to make sure // we don't create duplicate versions. // When we're adding a new slot to an area we need to make sure it // it is first in the hash so it gets ranked first if ($action === 'add') { $diff = '<strong>' . aString::limitCharacters($params['slot']->getSearchText(), 20) . "</strong>"; $newSlots = $this->getArea($name, $params['slot'], true); } else { $newSlots = $this->getArea($name); } $area = aAreaTable::retrieveOrCreateByPageIdAndName($this->id, $name); if (!$area->id) { // We need an ID established $area->save(); } $areaVersion = new aAreaVersion(); $areaVersion->area_id = $area->id; $areaVersion->version = $area->latest_version + 1; // Don't crash on an anon edit, it's odd but you could authorize it with the 'edit' option if (sfContext::getInstance() && sfContext::getInstance()->getUser()->getGuardUser()) { $areaVersion->author_id = sfContext::getInstance()->getUser()->getGuardUser()->getId(); } if ($action === 'delete') { if (isset($newSlots[$params['permid']])) { $diff = '<strike>' . aString::limitCharacters($newSlots[$params['permid']]->getSearchText(), 20) . '</strike>'; unset($newSlots[$params['permid']]); } } elseif ($action === 'update') { $oldText = ''; if (isset($newSlots[$params['permid']])) { $oldText = $newSlots[$params['permid']]->getSearchText(); } $newText = $params['slot']->getSearchText(); $fullDiff = aString::diff($oldText, $newText); $diff = ''; if (!empty($fullDiff['onlyin1'])) { $diff .= '<strike>' . aString::limitCharacters($fullDiff['onlyin1'][0], 20) . '</strike>'; } if (!empty($fullDiff['onlyin2'])) { $diff .= '<strong>' . aString::limitCharacters($fullDiff['onlyin2'][0], 20) . '</strong>'; } $newSlots[$params['permid']] = $params['slot']; } elseif ($action === 'variant') { $newSlot = $newSlots[$params['permid']]->copy(); if (!$newSlot) { throw new sfException('Slot does not exist'); } $variants = sfConfig::get('app_a_slot_variants'); if (!isset($variants[$newSlot->type][$params['variant']])) { throw new sfException('Variant not defined for this slot type'); } $newSlot->variant = $params['variant']; // Must have an id before we can make an AreaVersionSlot referencing it $newSlot->save(); $newSlots[$params['permid']] = $newSlot; $diff = $newSlot->variant; } elseif ($action === 'add') { // We took care of this in the getArea call } elseif ($action === 'sort') { $diff = '[Reordered slots]'; $newerSlots = array(); foreach ($params['permids'] as $permid) { $newerSlots[$permid] = $newSlots[$permid]; } $newSlots = $newerSlots; } elseif ($action === 'revert') { // TODO: actually represent the changes carried out by the reversion // in the diff. That's rather expensive because many slots in the area // may have changed all at once. $diff = '[Reverted to older version]'; # We just want whatever is in the slot cache copied to a new version } $areaVersion->diff = $diff; $areaVersion->save(); $rank = 1; foreach ($newSlots as $permid => $slot) { // After unset, foreach shows keys but has null values if (!$slot) { continue; } $areaVersionSlot = new aAreaVersionSlot(); $areaVersionSlot->slot_id = $slot->id; $areaVersionSlot->permid = $permid; $areaVersionSlot->area_version_id = $areaVersion->id; $areaVersionSlot->rank = $rank++; $areaVersionSlot->save(); } $area->latest_version++; $area->save(); if (sfConfig::get('app_a_defer_search_updates', false)) { // Deferred updates are sometimes nice for performance... aLuceneUpdateTable::requestUpdate($this); } else { // ... But the average developer hates cron. // Without this the changes we just made aren't visible to getSearchText, // we need to trigger a thorough recaching aPageTable::retrieveByIdWithSlots($this->id); $this->updateLuceneIndex(); } $this->end(); }
protected function editAjax($editorOpen) { // Refetch the page to reflect these changes before we // rerender the slot aTools::setCurrentPage(aPageTable::retrieveByIdWithSlots($this->page->id)); // Symfony 1.2 can return partials rather than templates... // which gets us out of the "we need a template from some other // module" bind $variant = $this->slot->getEffectiveVariant($this->options); return $this->renderPartial("a/ajaxUpdateSlot", array("name" => $this->name, "type" => $this->type, "permid" => $this->permid, "options" => $this->options, "editorOpen" => $editorOpen, "pageid" => $this->page->id, "variant" => $variant, "validationData" => $this->validationData)); }
/** * DOCUMENT ME * @param mixed $allcultures */ public function requestSearchUpdate($allcultures = false) { // we want to build an array so we can map the Lucene update across all elements $aPages = array($this); if ($allcultures) { $aPages = array(); $cultures = array(); $page = Doctrine::getTable('aPage')->createQuery('p')->where('p.id = ?', $this->id)->leftJoin('p.Areas a')->fetchOne(array(), Doctrine::HYDRATE_ARRAY); foreach ($page['Areas'] as $area) { $cultures[$area['culture']] = true; } $cultures = array_keys($cultures); foreach ($cultures as $culture) { $aPages[] = aPageTable::retrieveByIdWithSlots($this->id, $culture); } } // save a variable for the update function if (sfConfig::get('app_a_defer_search_updates', false)) { // Deferred updates are sometimes nice for performance... foreach ($aPages as $page) { aLuceneUpdateTable::requestUpdate($page); } } else { // ... But the average developer hates cron. // Without this the changes we just made aren't visible to getSearchText, // we need to trigger a thorough recaching foreach ($aPages as $page) { aPageTable::retrieveByIdWithSlots($page->id); $page->updateLuceneIndex(); } } }
/** * DOCUMENT ME * @return mixed */ protected function editSave() { $this->slot->save(); $this->page->newAreaVersion($this->name, $this->newSlot ? 'add' : 'update', array('permid' => $this->permid, 'slot' => $this->slot, 'top' => sfConfig::get('app_a_new_slots_top', true))); // Refetch the page to reflect these changes before we // rerender the slot aTools::setCurrentPage(aPageTable::retrieveByIdWithSlots($this->page->id)); if ($this->getRequestParameter('noajax')) { return $this->redirectToPage(); } else { return $this->editAjax(false); } }
public function requestSearchUpdate() { if (sfConfig::get('app_a_defer_search_updates', false)) { // Deferred updates are sometimes nice for performance... aLuceneUpdateTable::requestUpdate($this); } else { // ... But the average developer hates cron. // Without this the changes we just made aren't visible to getSearchText, // we need to trigger a thorough recaching aPageTable::retrieveByIdWithSlots($this->id); $this->updateLuceneIndex(); } }