public function searchMaterials($page = 1) { // Create condition for searching $conditionOR = new Condition('OR'); $conditionOR->add('Value', '%' . $this->key . '%', dbRelation::LIKE); $words = explode(' ', $this->key); // If we have many words in searching value if (sizeof($words) > 1) { $conditionAnd = new Condition('AND'); foreach ($words as $word) { $conditionAnd->add('Value', '%' . $word . '%', dbRelation::LIKE); } $conditionOR->add($conditionAnd); } if (is_numeric($this->key)) { $conditionOR->add('numeric_value', intval($this->key)); } // Get collection of founded material identifiers $materialIds = dbQuery('materialfield')->cond($conditionOR)->cond('FieldID', $this->searchFields)->cond('Active', 1)->join('material')->cond('material.Active', 1)->cond('material.Published', 1)->cond('material.Draft', 0)->group_by('MaterialID'); // Set external query handler if (isset($this->MatFieldExternalHandler)) { $materialIds->handler($this->MatFieldExternalHandler); } $foundedIds = dbQuery('\\samson\\cms\\CMSMaterial'); // Try to get founded materials $arrayIds = array(); if ($materialIds->fieldsNew('MaterialID', $arrayIds)) { $foundedIds = dbQuery('\\samson\\cms\\CMSMaterial')->cond('MaterialID', $arrayIds)->join('gallery'); if (isset($this->structures)) { $foundedIds->join('\\samson\\cms\\CMSNavMaterial')->cond('structurematerial_StructureID', $this->structures); } } else { // Create 100% empty condition $foundedIds->cond('MaterialID', 0); } $foundedIds = $foundedIds->fieldsNew('MaterialID'); if (sizeof($foundedIds)) { $result = dbQuery('material')->id($foundedIds); // Clone for count query $materialsCount = clone $result; // Create pager $this->pager = new \samson\pager\Pager($page, $this->itemsOnPage, $this->pagerPrefix, null, $this->getParams); $this->pager->update($materialsCount->count()); $result->limit($this->pager->start, $this->pager->end); $response = dbQuery('\\samson\\cms\\CMSMaterial')->id($result->fieldsNew('MaterialID')); // Call external material handler if (isset($this->MaterialExternalHandler)) { $response->handler($this->MaterialExternalHandler); } // Return query result return $response->join('gallery')->exec(); } else { return array(); } }
/** * Constructor * @param Navigation $nav Parent CMSNav to filter materials * @param string $search Keywords to search in materials * @param string $page Current table page number * @param \samson\core\IViewable $renderer Table renderer */ public function __construct(Navigation &$nav = null, $search = null, $page = null, $renderer = null) { // Save parent cmsnav $this->nav =& $nav; // Set current module or use passed renderer $this->renderer = isset($renderer) ? $renderer : m(); // Save search keywords $this->search = $search; $prefix = $this->setPagerPrefix(); // Create pager $this->pager = new \samson\pager\Pager($page, self::ROWS_COUNT, $prefix); // Collection of filtered material identifiers $filteredIDs = array(); $searchOrStructureFlag = false; // If search filter is set - add search condition to query if (isset($this->search[0]) && $this->search != '0') { // Create additional fields query $searchQuery = dbQuery('materialfield')->join('material'); // Create or condition $searchCondition = new Condition('OR'); // Iterate all possible material fields foreach (cms()->material_fields as $f) { // Create special condition for additional field $cg = new Condition('AND'); $cg->add(new Argument('FieldID', $f->FieldID))->add(new Argument('Value', '%' . $search . '%', dbRelation::LIKE)); // Add new condition to group $searchCondition->add($cg); } // Add all search conditions from material table foreach ($this->search_fields as $item) { $searchCondition->add(new Argument('material_' . $item, '%' . $search . '%', dbRelation::LIKE)); } // Set condition $searchQuery->cond($searchCondition); // Get filtered identifiers $filteredIDs = $searchQuery->fieldsNew('MaterialID'); $searchOrStructureFlag = true; } // Create DB query object $this->query = dbQuery('\\samson\\activerecord\\material')->cond('parent_id', 0)->cond('Draft', 0)->cond('Active', 1)->own_order_by('Modyfied', 'DESC'); // Perform query by structure-material and get material ids $ids = array(); if (isset($nav) && dbQuery('samson\\cms\\CMSNavMaterial')->cond('StructureID', $nav->id)->cond('Active', 1)->fields('MaterialID', $ids)) { // Set corresponding material ids related to specified navigation if (sizeof($filteredIDs)) { $filteredIDs = array_intersect($filteredIDs, $ids); } else { $filteredIDs = $ids; } $searchOrStructureFlag = true; } // If we have filtration identifiers if (sizeof($filteredIDs)) { // Add the, to query $this->query->id($filteredIDs); } elseif ($searchOrStructureFlag) { $this->query->id(0); } $this->queryHandler(); // Call parent constructor parent::__construct($this->query, $this->pager, $this->renderer); }
/** * @param \samson\activerecord\filter $filter * @param int $filterType Filter type of $filter parameter * @return \samson\activerecord\Condition Condition object created due to filter type */ private static function getFilterCondition($filter, $filterType = 1) { /** @var \samson\activerecord\Condition $condition */ $condition = new Condition(); // Try to determine type of filter switch ($filterType) { case '1': $condition->add(new Argument('FieldID', $filter->field_id))->add(new Argument('Value', $filter->value)); break; case '2': $condition->add(new Argument('FieldID', $filter->field_id))->add(new Argument('Value', $filter->value, dbRelation::NOT_EQUAL)); break; case '3': $condition->add(new Argument('FieldID', $filter->field_id))->add(new Argument('Value', $filter->value, dbRelation::LOWER)); break; case '4': $condition->add(new Argument('FieldID', $filter->field_id))->add(new Argument('Value', $filter->value, dbRelation::GREATER)); break; } return $condition; }
/** * Function to retrieve this material table by specified field * @param string $tableSelector Selector to identify table structure * @param string $selector Database field by which search is performed * @param array $tableColumns Columns names list * @param string $externalHandler External handler to perform some extra code * @param array $params External handler params * @return array Collection of collections of table cells, represented as materialfield objects * @deprecated Use new \samsoncms\api\FieldTable() */ public function getTable($tableSelector, $selector = 'StructureID', &$tableColumns = null, $externalHandler = null, $params = array()) { /** @var array $resultTable Collection of collections of field cells */ $resultTable = array(); /** @var array $dbTableFieldsIds Array of table structure column identifiers */ $dbTableFieldsIds = array(); // Get structure object if we need to search it by other fields if ($selector != 'StructureID') { $structure = dbQuery('structure')->cond($selector, $tableSelector)->first(); $tableSelector = $structure->id; } /** If this table has columns */ if (dbQuery('structurefield')->cond("StructureID", $tableSelector)->fields('FieldID', $dbTableFieldsIds)) { // Get localized and not localized fields $localizedFields = array(); $unlocalizedFields = array(); /** @var \samson\cms\CMSField $dbTableField Table column */ foreach (dbQuery('field')->order_by('priority')->cond('FieldID', $dbTableFieldsIds)->exec() as $field) { /** Add table columns names */ $tableColumns[] = $field->Name; if ($field->local == 1) { $localizedFields[] = $field->id; } else { $unlocalizedFields[] = $field->id; } } // Query to get table rows(table materials) $tableQuery = dbQuery('material')->cond('parent_id', $this->MaterialID)->cond('Active', '1')->join('structurematerial')->cond('structurematerial_StructureID', $tableSelector)->order_by('priority'); // Call user function if exists if (is_callable($externalHandler)) { // Give it query as parameter call_user_func_array($externalHandler, array_merge(array(&$tableQuery), $params)); } // Get table row materials $tableMaterialIds = array(); if ($tableQuery->fields('MaterialID', $tableMaterialIds)) { // Create field condition $localizationFieldCond = new Condition('or'); // Create localized condition if (sizeof($localizedFields)) { $localizedFieldCond = new Condition('and'); $localizedFieldCond->add('materialfield_FieldID', $localizedFields)->add('materialfield_locale', locale()); // Add this condition to condition group $localizationFieldCond->add($localizedFieldCond); } // Create not localized condition if (sizeof($unlocalizedFields)) { $localizationFieldCond->add('materialfield_FieldID', $unlocalizedFields); } // Create db query $materialFieldQuery = dbQuery('materialfield')->cond('MaterialID', $tableMaterialIds)->cond($localizationFieldCond); // Flip field identifiers as keys $tableColumnIds = array_flip($dbTableFieldsIds); $resultTable = array_flip($tableMaterialIds); /** @var \samson\activerecord\material $dbTableRow Material object (table row) */ foreach ($materialFieldQuery->exec() as $mf) { if (!is_array($resultTable[$mf['MaterialID']])) { $resultTable[$mf['MaterialID']] = array(); } $resultTable[$mf['MaterialID']][$tableColumnIds[$mf->FieldID]] = !empty($mf->Value) ? $mf->Value : (!empty($mf->numeric_value) ? $mf->numeric_value : $mf->key_value); } } } return array_values($resultTable); }
/** * Try to find all materials which have fields similar to search strings * * @param array $filteredIds Collection of filtered material identifiers * @return bool True if ALL field filtering succeeded or there was no filtering at all otherwise false */ protected function applySearchFilter(&$filteredIds = array()) { /** @var array $fields Variable to store all fields related to set navigation */ $fields = array(); /** @var array $navigationArray Array of set navigation identifiers */ $navigationArray = array(); /** @var array $fieldFilter Array of filtered material identifiers via materialfield table */ $fieldFilter = array(); /** @var array $materialFilter Array of filtered material identifiers via material table */ $materialFilter = array(); // If there are at least one search string if (!empty($this->search)) { // Create array containing all navigation identifiers foreach ($this->navigation as $navigation) { $navigationArray = array_merge($navigationArray, $navigation); } // Get all related fields $this->query->className('structurefield')->cond('StructureID', $navigationArray)->group_by('FieldID')->fields('FieldID', $fields); // Iterate over search strings foreach ($this->search as $searchString) { // Try to find search value in materialfield table $this->query->className('materialfield')->cond('FieldID', $fields)->cond('MaterialID', $filteredIds)->cond('Value', '%' . $searchString . '%', dbRelation::LIKE)->cond('Active', 1)->group_by('MaterialID')->fields('MaterialID', $fieldFilter); // TODO: Add generic support for all native fields or their configuration // Condition to search in material table by Name and URL $materialCondition = new Condition('OR'); $materialCondition->add('Name', '%' . $searchString . '%', dbRelation::LIKE)->add('Url', '%' . $searchString . '%', dbRelation::LIKE); // Try to find search value in material table $this->query->className('material')->cond('MaterialID', $filteredIds)->cond($materialCondition)->cond('Active', 1)->fields('MaterialID', $materialFilter); // If there are no materials with specified conditions if (empty($materialFilter) && empty($fieldFilter)) { // Filter applying failed return false; } else { // Otherwise set filtered material identifiers $filteredIds = array_unique(array_merge($materialFilter, $fieldFilter)); } } } // We have no search collection filters return true; }