/** * $request is the web request, for historical bc reasons. $options can currently * contain 'blogItemsOnly' => true to avoid returning the associated pages, useful * when we are just making a calendar with no titles etc. */ protected function buildQuery($request, $options = array()) { // We already know what page ids are relevant, now we're fetching author // information etc. per post. There's another method implicitly called later to populate // all of the blog content for the posts $q = Doctrine::getTable($this->modelClass)->createQuery()->leftJoin($this->modelClass . '.Author a'); $blogItemsOnly = isset($options['blogItemsOnly']) && $options['blogItemsOnly']; if (count($this->info['pageIds'])) { // We have page ids, so we need a join to figure out which blog items we want. // Doctrine doesn't have a withIn mechanism that takes a nice clean array, but we // know these are clean IDs $q->innerJoin($this->modelClass . '.Page p WITH p.id IN (' . implode(',', $this->info['pageIds']) . ')'); $q->leftJoin($this->modelClass . '.Categories c'); // Oops: there is NO ordering with an IN clause alone, you must make that explicit if ($blogItemsOnly) { $q->select($q->getRootAlias() . '.*'); } aDoctrine::orderByList($q, $this->info['pageIds'], 'p'); // When you call aDoctrine::orderByList you must have an explicit select clause of your own as the // default 'select everything' behavior of Doctrine goes away as soon as that method calls addSelect if (!$blogItemsOnly) { $q->addSelect($q->getRootAlias() . '.*, a.*, p.*, c.*'); } } else { $q->where('0 <> 0'); } return $q; }
public function getQuery() { // Explicit select() mandatory with orderByList $q = Doctrine::getTable($this->modelClass)->createQuery()->leftJoin($this->modelClass . '.Author a')->leftJoin($this->modelClass . '.Categories c')->select($this->modelClass . '.*, a.*, c.*'); Doctrine::getTable($this->modelClass)->addPublished($q); if (isset($this->values['title_or_tag']) && $this->values['title_or_tag'] === 'title') { $this->handSelected = true; if (isset($this->values['blog_posts']) && count($this->values['blog_posts'])) { $q->andWhereIn('id', $this->values['blog_posts']); $q = aDoctrine::orderByList($q, $this->values['blog_posts']); } else { $q->andWhere('0 <> 0'); } // Works way better when you actually return it! return $q; } else { if (isset($this->values['categories_list']) && count($this->values['categories_list']) > 0) { $q->andWhereIn('c.id', $this->values['categories_list']); } if (isset($this->values['tags_list']) && strlen($this->values['tags_list']) > 0) { PluginTagTable::getObjectTaggedWithQuery($q->getRootAlias(), $this->values['tags_list'], $q, array('nb_common_tags' => 1)); } if (!isset($this->values['count'])) { $this->values['count'] = 3; } $q->limit($this->values['count']); $q->orderBy('published_at desc'); return $q; } }
public function configure() { // ADD YOUR FIELDS HERE $this->widgetSchema['count'] = new sfWidgetFormInput(array(), array('size' => 2)); $this->validatorSchema['count'] = new sfValidatorNumber(array('min' => 1, 'max' => 10)); $this->widgetSchema->setHelp('count', '<span class="a-help-arrow"></span> Set the number of events to display – 10 max.'); if (!$this->hasDefault('count')) { $this->setDefault('count', 3); } $choices = array('title' => 'By Title', 'tags' => 'By Category And Tag'); $this->setWidget('title_or_tag', new sfWidgetFormChoice(array('choices' => $choices))); if (!$this->hasDefault('title_or_tag')) { $this->setDefault('title_or_tag', 'tags'); } $this->setValidator('title_or_tag', new sfValidatorChoice(array('choices' => array_keys($choices)))); // We'll progressively enhance this with autocomplete so no data is needed here... // except that we do need choices matching the previously saved values, otherwise // the Symfony widget has no idea how to render them // On the rendering pass we fetch the event titles already selected. // On the validation pass there will be no defaults, so we won't have to, // and shouldn't do a bad whereIn query that matches everything etc. $ids = $this->getDefault('blog_posts'); $choices = array(); if (count($ids)) { $q = Doctrine::getTable('aBlogItem')->createQuery('p')->select('p.*')->whereIn('p.id', $ids); aDoctrine::orderByList($q, $ids); $items = $q->execute(); // Crucial to get the latest versions of titles and avoid expensive single queries aBlogItemTable::populatePages($items); foreach ($items as $item) { $choices[$item->id] = $item->getTitle(); } } $this->setWidget('blog_posts', new sfWidgetFormChoice(array('multiple' => true, 'expanded' => false, 'choices' => $choices))); // TODO: really should be specific to events, requires adding a custom query $this->validatorSchema['blog_posts'] = new sfValidatorDoctrineChoice(array('model' => 'aBlogItem', 'multiple' => true, 'required' => false)); $this->widgetSchema['categories_list'] = new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'aCategory')); $this->validatorSchema['categories_list'] = new sfValidatorDoctrineChoice(array('model' => 'aCategory', 'multiple' => true, 'required' => false)); $this->widgetSchema->setHelp('categories_list', '<span class="a-help-arrow"></span> Filter Events by Category'); $this->getWidget('categories_list')->setOption('query', Doctrine::getTable('aCategory')->createQuery()->orderBy('aCategory.name asc')); $this->widgetSchema['tags_list'] = new sfWidgetFormInput(array(), array('class' => 'tag-input', 'autocomplete' => 'off')); $this->validatorSchema['tags_list'] = new sfValidatorString(array('required' => false)); $this->widgetSchema->setHelp('tags_list', '<span class="a-help-arrow"></span> Filter Events by Tag'); // Ensures unique IDs throughout the page $this->widgetSchema->setNameFormat('slot-form-' . $this->id . '[%s]'); // You don't have to use our form formatter, but it makes things nice $this->widgetSchema->setFormFormatterName('aAdmin'); }
public function executeEdit(sfRequest $request) { $this->logMessage("====== in aSlideshowSlotActions::executeEdit", "info"); if ($request->getParameter('aMediaCancel')) { return $this->redirectToPage(); } $this->editSetup(); $ids = preg_split('/,/', $request->getParameter('aMediaIds')); $q = Doctrine::getTable('aMediaItem')->createQuery('m')->select('m.*')->whereIn('m.id', $ids)->andWhere('m.type = "image"'); // Let the query preserve order for us $items = aDoctrine::orderByList($q, $ids)->execute(); $this->slot->unlink('MediaItems'); $links = aArray::getIds($items); $this->slot->link('MediaItems', $links); // Save just the order in the value field. Use a hash so we can add // other metadata later $this->slot->value = serialize(array('order' => $links)); $this->editSave(); }
public function getQuery() { // Explicit select() mandatory with orderByList $q = Doctrine::getTable($this->modelClass)->createQuery()->leftJoin($this->modelClass . '.Author a')->leftJoin($this->modelClass . '.Categories c')->select($this->modelClass . '.*, a.*, c.*'); Doctrine::getTable($this->modelClass)->addPublished($q); if (isset($this->values['title_or_tag']) && $this->values['title_or_tag'] === 'title') { $this->handSelected = true; if (isset($this->values['blog_posts']) && count($this->values['blog_posts'])) { $q->andWhereIn('id', $this->values['blog_posts']); $q = aDoctrine::orderByList($q, $this->values['blog_posts']); } else { $q->andWhere('0 <> 0'); } // Works way better when you actually return it! return $q; } else { if (isset($this->values['categories_list']) && count($this->values['categories_list']) > 0) { // This doesn't cut it because we wind up not knowing about the // other categories of each post, which breaks our "link to best page // for this post" algorithm // $q->andWhereIn('c.id', $this->values['categories_list']); // This would be nice but Doctrine croaks parsing it // $q->andWhere($this->modelClass . '.id IN (SELECT iblog.id FROM ' . $this->modelClass . ' iblog INNER JOIN iblog.Categories ic WITH ic.id IN ?)', array($this->values['categories_list'])); // Let's cheat and use aMysql to pull the blog item IDs that have the relevant categories in a lightweight way, // then do a whereIn clause. It's not ideal, but it works well in practice $sql = new aMysql(); $blogItemsForCategories = $sql->queryScalar('SELECT i.id FROM a_blog_item i INNER JOIN a_blog_item_to_category ic ON i.id = ic.blog_item_id AND ic.category_id IN :category_ids', array('category_ids' => $this->values['categories_list'])); // So we use this after all, but we'll fetch all the categories for the posts in a second pass, sigh $q->andWhereIn($this->modelClass . '.id', $blogItemsForCategories); } if (isset($this->values['tags_list']) && strlen($this->values['tags_list']) > 0) { PluginTagTable::getObjectTaggedWithQuery($q->getRootAlias(), $this->values['tags_list'], $q, array('nb_common_tags' => 1)); } if (!isset($this->values['count'])) { $this->values['count'] = 3; } $q->limit($this->values['count']); $q->orderBy('published_at desc'); return $q; } }
/** * DOCUMENT ME * @param sfRequest $request * @return mixed */ public function executeEdit(sfRequest $request) { $this->logMessage("====== in aSlideshowSlotActions::executeEdit", "info"); if ($request->getParameter('aMediaCancel')) { return $this->redirectToPage(); } $this->editSetup(); if ($request->hasParameter('aMediaIds')) { $ids = preg_split('/,/', $request->getParameter('aMediaIds')); $q = Doctrine::getTable('aMediaItem')->createQuery('m')->select('m.*')->whereIn('m.id', $ids)->andWhere('m.type = "image"'); // Let the query preserve order for us $items = aDoctrine::orderByList($q, $ids)->execute(); $this->slot->unlink('MediaItems'); $links = aArray::getIds($items); $this->slot->link('MediaItems', $links); // This isn't a normal form submission, but the act of selecting items for a // slideshow implies we picked the 'selected' radio button, so just save 'form' as if // that choice had been saved normally $this->slot->value = serialize(array('form' => array('type' => 'selected'), 'order' => $links)); return $this->editSave(); } }
public function executeEdit(sfRequest $request) { $this->logMessage("====== in aSlideshowSlotActions::executeEdit", "info"); if ($request->getParameter('aMediaCancel')) { return $this->redirectToPage(); } $this->editSetup(); $ids = preg_split('/,/', $request->getParameter('aMediaIds')); $q = Doctrine::getTable('aMediaItem')->createQuery('m')->select('m.*')->whereIn('m.id', $ids)->andWhere('m.type = "image"'); // Let the query preserve order for us $items = aDoctrine::orderByList($q, $ids)->execute(); $this->slot->unlink('MediaItems'); $links = aArray::getIds($items); $this->slot->link('MediaItems', $links); // Save just the order in the value field. Use a hash so we can add // other metadata later // Use getArrayValue and setArrayValue so that any additional fields that have been // added at the app level don't get smooshed $value = $this->slot->getArrayValue(); $value['order'] = $links; $this->slot->setArrayValue($value); $this->editSave(); }
public static function addSearchQueryWithScores(Doctrine_Table $table, Doctrine_Query $q = null, $luceneQuery, $culture, &$scores) { $name = $table->getOption('name'); if (is_null($q)) { $q = Doctrine_Query::create()->from($name); } $scores = $table->searchLuceneWithScores($luceneQuery, $culture); $results = array_keys($scores); if (count($results)) { $alias = $q->getRootAlias(); // Contrary to Jobeet the above is NOT enough, the results will // not be in Lucene result order. Use aDoctrine::orderByList to fix // that up in a portable way with a SQL92-compatible CASE statement. // Call addSelect so that we don't trash existing queries. $q->addSelect($alias . '.*'); aDoctrine::orderByList($q, $results); $q->whereIn($alias . '.id', $results); $q->orderBy('field'); } else { // Don't just let everything through when there are no hits! // Don't use just 'false', that is not guaranteed to be cross-database compatible. $q->andWhere('0 = 1'); } return $q; }
/** * Retrieves media items matching the supplied array of ids, in the same order as the ids * (a simple whereIn does not do this). We must use an explicit select when using * aDoctrine::orderByList. * @param mixed $ids * @return mixed */ public function findByIdsInOrder($ids) { if (empty($ids)) { // Doctrine doesn't generate any clause at all for WHERE IN if an array if false. This is a bug, but // it doesn't seem to be getting fixed at the Doctrine level return Doctrine::getTable('aMediaItem')->createQuery('m')->select('m.*')->where('1 = 0'); } $q = Doctrine::getTable('aMediaItem')->createQuery('m')->select('m.*')->whereIn('m.id', $ids); // Don't forget to put them in order! return aDoctrine::orderByList($q, $ids)->execute(); }