Public Member Functions | |
rebuildIndex ($storeId=null, $productIds=null) | |
resetSearchResults () | |
cleanIndex ($storeId=null, $productId=null) | |
prepareResult ($object, $queryText, $query) | |
getEavConfig () | |
Protected Member Functions | |
_construct () | |
_rebuildStoreIndex ($storeId, $productIds=null) | |
_getSearchableProducts ($storeId, array $staticFields, $productIds=null, $lastProductId=0, $limit=100) | |
_getSearchableAttributes ($backendType=null) | |
_getSearchableAttribute ($attribute) | |
_getProductAttributes ($storeId, array $productIds, array $atributeTypes) | |
_getProductTypeInstance ($typeId) | |
_getProductChildIds ($productId, $typeId) | |
_getProductEmulator () | |
_prepareProductIndex ($indexData, $productData, $storeId) | |
_getAttributeValue ($attributeId, $value, $storeId) | |
_saveProductIndex ($productId, $storeId, $index) | |
_saveProductIndexes ($storeId, $productIndexes) | |
Protected Attributes | |
$_searchableAttributes = null | |
$_separator = ' ' | |
$_productTypes = array() |
Definition at line 34 of file Fulltext.php.
_construct | ( | ) | [protected] |
Init resource model
Reimplemented from Mage_Core_Model_Resource_Abstract.
Definition at line 60 of file Fulltext.php.
00061 { 00062 $this->_init('catalogsearch/fulltext', 'product_id'); 00063 }
_getAttributeValue | ( | $ | attributeId, | |
$ | value, | |||
$ | storeId | |||
) | [protected] |
Retrieve attribute source value for search
int | $attributeId | |
mixed | $value |
Definition at line 538 of file Fulltext.php.
00539 { 00540 $attribute = $this->_getSearchableAttribute($attributeId); 00541 if (!$attribute->getIsSearchable()) { 00542 return null; 00543 } 00544 if ($attribute->usesSource()) { 00545 $attribute->setStoreId($storeId); 00546 $value = $attribute->getSource()->getOptionText($value); 00547 } 00548 00549 if (is_array($value)) { 00550 $value = implode($this->_separator, $value); 00551 } 00552 00553 return preg_replace("#\s+#si", " ", trim(strip_tags($value))); 00554 }
Load product(s) attributes
int | $storeId | |
array | $productIds | |
array | $atributeTypes |
Definition at line 403 of file Fulltext.php.
00404 { 00405 $result = array(); 00406 $selects = array(); 00407 foreach ($atributeTypes as $backendType => $attributeIds) { 00408 if ($attributeIds) { 00409 $tableName = $this->getTable('catalog/product') . '_' . $backendType; 00410 $selects[] = $this->_getReadAdapter()->select() 00411 ->from( 00412 array('t_default' => $tableName), 00413 array('entity_id', 'attribute_id')) 00414 ->joinLeft( 00415 array('t_store' => $tableName), 00416 $this->_getReadAdapter()->quoteInto("t_default.entity_id=t_store.entity_id AND t_default.attribute_id=t_store.attribute_id AND t_store.store_id=?", $storeId), 00417 array('value'=>'IFNULL(t_store.value, t_default.value)')) 00418 ->where('t_default.store_id=?', 0) 00419 ->where('t_default.attribute_id IN(?)', $attributeIds) 00420 ->where('t_default.entity_id IN(?)', $productIds); 00421 } 00422 } 00423 00424 if ($selects) { 00425 $select = '('.join(')UNION(', $selects).')'; 00426 $query = $this->_getReadAdapter()->query($select); 00427 while ($row = $query->fetch()) { 00428 $result[$row['entity_id']][$row['attribute_id']] = $row['value']; 00429 } 00430 } 00431 00432 return $result; 00433 }
_getProductChildIds | ( | $ | productId, | |
$ | typeId | |||
) | [protected] |
Return all product children ids
int | $productId Product Entity Id | |
string | $typeId Super Product Link Type |
Definition at line 460 of file Fulltext.php.
00461 { 00462 $typeInstance = $this->_getProductTypeInstance($typeId); 00463 $relation = $typeInstance->isComposite() 00464 ? $typeInstance->getRelationInfo() 00465 : false; 00466 00467 if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()) { 00468 $select = $this->_getReadAdapter()->select() 00469 ->from( 00470 array('main' => $this->getTable($relation->getTable())), 00471 array($relation->getChildFieldName())) 00472 ->where("{$relation->getParentFieldName()}=?", $productId); 00473 if (!is_null($relation->getWhere())) { 00474 $select->where($relation->getWhere()); 00475 } 00476 return $this->_getReadAdapter()->fetchCol($select); 00477 } 00478 00479 return null; 00480 }
_getProductEmulator | ( | ) | [protected] |
Retrieve Product Emulator (Varien Object)
Definition at line 487 of file Fulltext.php.
00488 { 00489 $productEmulator = new Varien_Object(); 00490 $productEmulator->setIdFieldName('entity_id'); 00491 return $productEmulator; 00492 }
_getProductTypeInstance | ( | $ | typeId | ) | [protected] |
Retrieve Product Type Instance
string | $typeId |
Definition at line 441 of file Fulltext.php.
00442 { 00443 if (!isset($this->_productTypes[$typeId])) { 00444 $productEmulator = $this->_getProductEmulator(); 00445 $productEmulator->setTypeId($typeId); 00446 00447 $this->_productTypes[$typeId] = Mage::getSingleton('catalog/product_type') 00448 ->factory($productEmulator); 00449 } 00450 return $this->_productTypes[$typeId]; 00451 }
_getSearchableAttribute | ( | $ | attribute | ) | [protected] |
Retrieve searchable attribute by Id or code
int|string | $attribute |
Definition at line 376 of file Fulltext.php.
00377 { 00378 $attributes = $this->_getSearchableAttributes(); 00379 if (is_numeric($attribute)) { 00380 if (isset($attributes[$attribute])) { 00381 return $attributes[$attribute]; 00382 } 00383 } 00384 elseif (is_string($attribute)) { 00385 foreach ($attributes as $attributeModel) { 00386 if ($attributeModel->getAttributeCode() == $attribute) { 00387 return $attributeModel; 00388 } 00389 } 00390 } 00391 return $this->getEavConfig()->getAttribute('catalog_product', $attribute); 00392 }
_getSearchableAttributes | ( | $ | backendType = null |
) | [protected] |
Retrieve Searchable attributes
Definition at line 332 of file Fulltext.php.
00333 { 00334 if (is_null($this->_searchableAttributes)) { 00335 $this->_searchableAttributes = array(); 00336 $entityType = $this->getEavConfig()->getEntityType('catalog_product'); 00337 $entity = $entityType->getEntity(); 00338 00339 $whereCond = array( 00340 $this->_getReadAdapter()->quoteInto('is_searchable=?', 1), 00341 $this->_getReadAdapter()->quoteInto('attribute_code IN(?)', array('status', 'visibility')) 00342 ); 00343 00344 $select = $this->_getReadAdapter()->select() 00345 ->from($this->getTable('eav/attribute')) 00346 ->where('entity_type_id=?', $entityType->getEntityTypeId()) 00347 ->where(join(' OR ', $whereCond)); 00348 $attributesData = $this->_getReadAdapter()->fetchAll($select); 00349 $this->getEavConfig()->importAttributesData($entityType, $attributesData); 00350 foreach ($attributesData as $attributeData) { 00351 $attributeCode = $attributeData['attribute_code']; 00352 $attribute = $this->getEavConfig()->getAttribute($entityType, $attributeCode); 00353 $attribute->setEntity($entity); 00354 $this->_searchableAttributes[$attribute->getId()] = $attribute; 00355 } 00356 unset($attributesData); 00357 } 00358 if (!is_null($backendType)) { 00359 $attributes = array(); 00360 foreach ($this->_searchableAttributes as $attribute) { 00361 if ($attribute->getBackendType() == $backendType) { 00362 $attributes[$attribute->getId()] = $attribute; 00363 } 00364 } 00365 return $attributes; 00366 } 00367 return $this->_searchableAttributes; 00368 }
_getSearchableProducts | ( | $ | storeId, | |
array $ | staticFields, | |||
$ | productIds = null , |
|||
$ | lastProductId = 0 , |
|||
$ | limit = 100 | |||
) | [protected] |
Retrieve searchable products per store
int | $storeId | |
array | $staticFields | |
array|int | $productIds | |
int | $lastProductId | |
int | $limit |
Definition at line 180 of file Fulltext.php.
00181 { 00182 $entityType = $this->getEavConfig()->getEntityType('catalog_product'); 00183 $store = Mage::app()->getStore($storeId); 00184 00185 $select = $this->_getReadAdapter()->select() 00186 ->from( 00187 array('e' => $this->getTable('catalog/product')), 00188 array_merge(array('entity_id', 'type_id'), $staticFields)) 00189 ->joinInner( 00190 array('website' => $this->getTable('catalog/product_website')), 00191 $this->_getReadAdapter()->quoteInto('website.product_id=e.entity_id AND website.website_id=?', $store->getWebsiteId()), 00192 array() 00193 ); 00194 00195 if (!is_null($productIds)) { 00196 $select->where('e.entity_id IN(?)', $productIds); 00197 } 00198 00199 $select->where('e.entity_id>?', $lastProductId) 00200 ->limit($limit) 00201 ->order('e.entity_id'); 00202 00203 return $this->_getReadAdapter()->fetchAll($select); 00204 }
_prepareProductIndex | ( | $ | indexData, | |
$ | productData, | |||
$ | storeId | |||
) | [protected] |
Prepare Fulltext index value for product
array | $indexData | |
array | $productData |
Definition at line 501 of file Fulltext.php.
00502 { 00503 $index = array(); 00504 foreach ($this->_getSearchableAttributes('static') as $attribute) { 00505 if (isset($productData[$attribute->getAttributeCode()])) { 00506 if ($value = $this->_getAttributeValue($attribute->getId(), $productData[$attribute->getAttributeCode()], $storeId)) { 00507 $index[] = $value; 00508 } 00509 } 00510 } 00511 foreach ($indexData as $attributeData) { 00512 foreach ($attributeData as $attributeId => $attributeValue) { 00513 if ($value = $this->_getAttributeValue($attributeId, $attributeValue, $storeId)) { 00514 $index[] = $value; 00515 } 00516 } 00517 } 00518 00519 $product = $this->_getProductEmulator() 00520 ->setId($productData['entity_id']) 00521 ->setTypeId($productData['type_id']) 00522 ->setStoreId($storeId); 00523 $typeInstance = $this->_getProductTypeInstance($productData['type_id']); 00524 if ($data = $typeInstance->getSearchableData($product)) { 00525 $index = array_merge($index, $data); 00526 } 00527 00528 return join($this->_separator, $index); 00529 }
_rebuildStoreIndex | ( | $ | storeId, | |
$ | productIds = null | |||
) | [protected] |
Regenerate search index for specific store
int | $storeId Store View Id | |
int|array | $productIds Product Entity Id |
Definition at line 91 of file Fulltext.php.
00092 { 00093 $this->cleanIndex($storeId, $productIds); 00094 00095 // preparesearchable attributes 00096 $staticFields = array(); 00097 foreach ($this->_getSearchableAttributes('static') as $attribute) { 00098 $staticFields[] = $attribute->getAttributeCode(); 00099 } 00100 $dynamicFields = array( 00101 'int' => array_keys($this->_getSearchableAttributes('int')), 00102 'varchar' => array_keys($this->_getSearchableAttributes('varchar')), 00103 'text' => array_keys($this->_getSearchableAttributes('text')), 00104 ); 00105 00106 // status and visibility filter 00107 $visibility = $this->_getSearchableAttribute('visibility'); 00108 $status = $this->_getSearchableAttribute('status'); 00109 $visibilityVals = Mage::getSingleton('catalog/product_visibility')->getVisibleInSearchIds(); 00110 $statusVals = Mage::getSingleton('catalog/product_status')->getVisibleStatusIds(); 00111 00112 $lastProductId = 0; 00113 while (true) { 00114 $products = $this->_getSearchableProducts($storeId, $staticFields, $productIds, $lastProductId); 00115 if (!$products) { 00116 break; 00117 } 00118 00119 $productAttributes = array(); 00120 $productRelations = array(); 00121 foreach ($products as $productData) { 00122 $lastProductId = $productData['entity_id']; 00123 $productAttributes[$productData['entity_id']] = $productData['entity_id']; 00124 $productChilds = $this->_getProductChildIds($productData['entity_id'], $productData['type_id']); 00125 $productRelations[$productData['entity_id']] = $productChilds; 00126 if ($productChilds) { 00127 foreach ($productChilds as $productChildId) { 00128 $productAttributes[$productChildId] = $productChildId; 00129 } 00130 } 00131 } 00132 00133 $productIndexes = array(); 00134 $productAttributes = $this->_getProductAttributes($storeId, $productAttributes, $dynamicFields); 00135 foreach ($products as $productData) { 00136 if (!isset($productAttributes[$productData['entity_id']])) { 00137 continue; 00138 } 00139 $protductAttr = $productAttributes[$productData['entity_id']]; 00140 if (!isset($protductAttr[$visibility->getId()]) || !in_array($protductAttr[$visibility->getId()], $visibilityVals)) { 00141 continue; 00142 } 00143 if (!isset($protductAttr[$status->getId()]) || !in_array($protductAttr[$status->getId()], $statusVals)) { 00144 continue; 00145 } 00146 00147 $productIndex = array( 00148 $productData['entity_id'] => $protductAttr 00149 ); 00150 if ($productChilds = $productRelations[$productData['entity_id']]) { 00151 foreach ($productChilds as $productChildId) { 00152 if (isset($productAttributes[$productChildId])) { 00153 $productIndex[$productChildId] = $productAttributes[$productChildId]; 00154 } 00155 } 00156 } 00157 00158 $index = $this->_prepareProductIndex($productIndex, $productData, $storeId); 00159 $productIndexes[$productData['entity_id']] = $index; 00160 //$this->_saveProductIndex($productData['entity_id'], $storeId, $index); 00161 } 00162 $this->_saveProductIndexes($storeId, $productIndexes); 00163 } 00164 00165 $this->resetSearchResults(); 00166 00167 return $this; 00168 }
_saveProductIndex | ( | $ | productId, | |
$ | storeId, | |||
$ | index | |||
) | [protected] |
Save Product index
int | $productId | |
int | $storeId | |
string | $index |
Definition at line 564 of file Fulltext.php.
00565 { 00566 $this->_getWriteAdapter()->insert($this->getMainTable(), array( 00567 'product_id' => $productId, 00568 'store_id' => $storeId, 00569 'data_index' => $index 00570 )); 00571 return $this; 00572 }
_saveProductIndexes | ( | $ | storeId, | |
$ | productIndexes | |||
) | [protected] |
Save Multiply Product indexes
int | $storeId | |
array | $productIndexes |
Definition at line 581 of file Fulltext.php.
00582 { 00583 $values = array(); 00584 $bind = array(); 00585 foreach ($productIndexes as $productId => &$index) { 00586 $values[] = sprintf('(%s,%s,%s)', 00587 $this->_getWriteAdapter()->quoteInto('?', $productId), 00588 $this->_getWriteAdapter()->quoteInto('?', $storeId), 00589 '?' 00590 ); 00591 $bind[] = $index; 00592 } 00593 00594 if ($values) { 00595 $sql = "REPLACE INTO `{$this->getMainTable()}` VALUES" 00596 . join(',', $values); 00597 $this->_getWriteAdapter()->query($sql, $bind); 00598 } 00599 00600 return $this; 00601 }
cleanIndex | ( | $ | storeId = null , |
|
$ | productId = null | |||
) |
Delete search index data for store
int | $storeId Store View Id | |
int | $productId Product Entity Id |
Definition at line 237 of file Fulltext.php.
00238 { 00239 $where = array(); 00240 00241 if (!is_null($storeId)) { 00242 $where[] = $this->_getWriteAdapter()->quoteInto('store_id=?', $storeId); 00243 } 00244 if (!is_null($productId)) { 00245 $where[] = $this->_getWriteAdapter()->quoteInto('product_id IN(?)', $productId); 00246 } 00247 00248 $this->_getWriteAdapter()->delete($this->getMainTable(), join(' AND ', $where)); 00249 return $this; 00250 }
getEavConfig | ( | ) |
Retrieve EAV Config Singleton
Definition at line 322 of file Fulltext.php.
00323 { 00324 return Mage::getSingleton('eav/config'); 00325 }
prepareResult | ( | $ | object, | |
$ | queryText, | |||
$ | query | |||
) |
Prepare results for query
Mage_CatalogSearch_Model_Fulltext | $object | |
string | $queryText | |
Mage_CatalogSearch_Model_Query | $query |
Definition at line 260 of file Fulltext.php.
00261 { 00262 if (!$query->getIsProcessed()) { 00263 $searchType = $object->getSearchType($query->getStoreId()); 00264 00265 $stringHelper = Mage::helper('core/string'); 00266 /* @var $stringHelper Mage_Core_Helper_String */ 00267 00268 $bind = array( 00269 ':query' => $queryText 00270 ); 00271 $like = array(); 00272 00273 $fulltextCond = ''; 00274 $likeCond = ''; 00275 $separateCond = ''; 00276 00277 if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE 00278 || $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) { 00279 $words = $stringHelper->splitWords($queryText, true, $query->getMaxQueryWords()); 00280 $likeI = 0; 00281 foreach ($words as $word) { 00282 $like[] = '`s`.`data_index` LIKE :likew' . $likeI; 00283 $bind[':likew' . $likeI] = '%' . $word . '%'; 00284 $likeI ++; 00285 } 00286 if ($like) { 00287 $likeCond = '(' . join(' AND ', $like) . ')'; 00288 } 00289 } 00290 if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_FULLTEXT 00291 || $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) { 00292 $fulltextCond = 'MATCH (`s`.`data_index`) AGAINST (:query IN BOOLEAN MODE)'; 00293 } 00294 if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE && $likeCond) { 00295 $separateCond = ' OR '; 00296 } 00297 00298 $sql = sprintf("REPLACE INTO `{$this->getTable('catalogsearch/result')}` " 00299 . "(SELECT '%d', `s`.`product_id`, MATCH (`s`.`data_index`) AGAINST (:query IN BOOLEAN MODE) " 00300 . "FROM `{$this->getMainTable()}` AS `s` INNER JOIN `{$this->getTable('catalog/product')}` AS `e`" 00301 . "ON `e`.`entity_id`=`s`.`product_id` WHERE (%s%s%s) AND `s`.`store_id`='%d')", 00302 $query->getId(), 00303 $fulltextCond, 00304 $separateCond, 00305 $likeCond, 00306 $query->getStoreId() 00307 ); 00308 00309 $this->_getWriteAdapter()->query($sql, $bind); 00310 00311 $query->setIsProcessed(1); 00312 } 00313 00314 return $this; 00315 }
rebuildIndex | ( | $ | storeId = null , |
|
$ | productIds = null | |||
) |
Regenerate search index for store(s)
int | $storeId Store View Id | |
int|array | $productIds Product Entity Id(s) |
Definition at line 72 of file Fulltext.php.
00073 { 00074 if (is_null($storeId)) { 00075 foreach (Mage::app()->getStores(false) as $store) { 00076 $this->_rebuildStoreIndex($store->getId(), $productIds); 00077 } 00078 } else { 00079 $this->_rebuildStoreIndex($storeId, $productIds); 00080 } 00081 return $this; 00082 }
resetSearchResults | ( | ) |
Reset search results
Definition at line 211 of file Fulltext.php.
00212 { 00213 $this->beginTransaction(); 00214 try { 00215 $this->_getWriteAdapter()->update($this->getTable('catalogsearch/search_query'), array('is_processed' => 0)); 00216 $this->_getWriteAdapter()->query("TRUNCATE TABLE {$this->getTable('catalogsearch/result')}"); 00217 00218 $this->commit(); 00219 } 00220 catch (Exception $e) { 00221 $this->rollBack(); 00222 throw $e; 00223 } 00224 00225 Mage::dispatchEvent('catalogsearch_reset_search_result'); 00226 00227 return $this; 00228 }
$_productTypes = array() [protected] |
Definition at line 55 of file Fulltext.php.
$_searchableAttributes = null [protected] |
Definition at line 41 of file Fulltext.php.
$_separator = ' ' [protected] |
Definition at line 48 of file Fulltext.php.