123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\DB;
- use Magento\Framework\Api\CriteriaInterface;
- use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
- use Magento\Framework\Data\ObjectFactory;
- use Magento\Framework\DB\Adapter\AdapterInterface;
- use Psr\Log\LoggerInterface as Logger;
- /**
- * Class AbstractMapper
- * @package Magento\Framework\DB
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- abstract class AbstractMapper implements MapperInterface
- {
- /**
- * Resource model name
- *
- * @var string
- */
- protected $resourceModel;
- /**
- * Resource instance
- *
- * @var \Magento\Framework\Model\ResourceModel\Db\AbstractDb
- */
- protected $resource;
- /**
- * Store joined tables here
- *
- * @var array
- */
- protected $joinedTables = [];
- /**
- * DB connection
- *
- * @var AdapterInterface
- */
- protected $connection;
- /**
- * Select object
- *
- * @var Select
- */
- protected $select;
- /**
- * @var Logger
- */
- protected $logger;
- /**
- * @var FetchStrategyInterface
- */
- protected $fetchStrategy;
- /**
- * @var ObjectFactory
- */
- protected $objectFactory;
- /**
- * @var MapperFactory
- */
- protected $mapperFactory;
- /**
- * Fields and filters map
- *
- * @var array
- */
- protected $map = [];
- /**
- * @param Logger $logger
- * @param FetchStrategyInterface $fetchStrategy
- * @param ObjectFactory $objectFactory
- * @param MapperFactory $mapperFactory
- * @param Select $select
- */
- public function __construct(
- Logger $logger,
- FetchStrategyInterface $fetchStrategy,
- ObjectFactory $objectFactory,
- MapperFactory $mapperFactory,
- Select $select = null
- ) {
- $this->logger = $logger;
- $this->fetchStrategy = $fetchStrategy;
- $this->objectFactory = $objectFactory;
- $this->mapperFactory = $mapperFactory;
- $this->select = $select;
- $this->init();
- }
- /**
- * Set initial conditions
- *
- * @return void
- */
- abstract protected function init();
- /**
- * Map criteria to Select Query Object
- *
- * @param CriteriaInterface $criteria
- * @return Select
- */
- public function map(CriteriaInterface $criteria)
- {
- $criteriaParts = $criteria->toArray();
- foreach ($criteriaParts as $key => $value) {
- $camelCaseKey = \Magento\Framework\Api\SimpleDataObjectConverter::snakeCaseToUpperCamelCase($key);
- $mapperMethod = 'map' . $camelCaseKey;
- if (method_exists($this, $mapperMethod)) {
- if (!is_array($value)) {
- throw new \InvalidArgumentException('Wrong type of argument, expecting array for '. $mapperMethod);
- }
- call_user_func_array([$this, $mapperMethod], $value);
- }
- }
- return $this->select;
- }
- /**
- * Add attribute expression (SUM, COUNT, etc)
- * Example: ('sub_total', 'SUM({{attribute}})', 'revenue')
- * Example: ('sub_total', 'SUM({{revenue}})', 'revenue')
- * For some functions like SUM use groupByAttribute.
- *
- * @param string $alias
- * @param string $expression
- * @param array|string $fields
- * @return void
- */
- public function addExpressionFieldToSelect($alias, $expression, $fields)
- {
- // validate alias
- if (!is_array($fields)) {
- $fields = [$fields => $fields];
- }
- $fullExpression = $expression;
- foreach ($fields as $fieldKey => $fieldItem) {
- $fullExpression = str_replace('{{' . $fieldKey . '}}', $fieldItem, $fullExpression);
- }
- $this->getSelect()->columns([$alias => $fullExpression]);
- }
- /**
- * @inheritdoc
- */
- public function addFieldToFilter($field, $condition = null)
- {
- if (is_array($field)) {
- $conditions = [];
- foreach ($field as $key => $value) {
- $conditions[] = $this->translateCondition($value, isset($condition[$key]) ? $condition[$key] : null);
- }
- $resultCondition = '(' . implode(') ' . \Magento\Framework\DB\Select::SQL_OR . ' (', $conditions) . ')';
- } else {
- $resultCondition = $this->translateCondition($field, $condition);
- }
- $this->select->where($resultCondition, null, Select::TYPE_CONDITION);
- }
- /**
- * @inheritdoc
- */
- public function reset()
- {
- $this->getSelect()->reset();
- }
- /**
- * Set resource model name
- *
- * @param string $model
- * @return void
- */
- protected function setResourceModelName($model)
- {
- $this->resourceModel = $model;
- }
- /**
- * Retrieve resource model name
- *
- * @return string
- */
- protected function getResourceModelName()
- {
- return $this->resourceModel;
- }
- /**
- * Get resource instance
- *
- * @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
- */
- public function getResource()
- {
- if (empty($this->resource)) {
- $this->resource = \Magento\Framework\App\ObjectManager::getInstance()->create(
- $this->getResourceModelName()
- );
- }
- return $this->resource;
- }
- /**
- * Standard query builder initialization
- *
- * @param string $resourceInterface
- * @return void
- */
- protected function initResource($resourceInterface)
- {
- $this->setResourceModelName($resourceInterface);
- $this->setConnection($this->getResource()->getConnection());
- if (!$this->select) {
- $this->select = $this->getConnection()->select();
- $this->initSelect();
- }
- }
- /**
- * Init collection select
- *
- * @return void
- */
- protected function initSelect()
- {
- $this->getSelect()->from(['main_table' => $this->getResource()->getMainTable()]);
- }
- /**
- * Join table to collection select
- *
- * @param string $table
- * @param string $condition
- * @param string $cols
- * @return void
- */
- protected function join($table, $condition, $cols = '*')
- {
- if (is_array($table)) {
- foreach ($table as $k => $v) {
- $alias = $k;
- $table = $v;
- break;
- }
- } else {
- $alias = $table;
- }
- if (!isset($this->joinedTables[$table])) {
- $this->getSelect()->join([$alias => $this->getTable($table)], $condition, $cols);
- $this->joinedTables[$alias] = true;
- }
- }
- /**
- * Retrieve connection object
- *
- * @return AdapterInterface
- */
- protected function getConnection()
- {
- return $this->connection;
- }
- /**
- * Set database connection adapter
- *
- * @param AdapterInterface $connection
- * @return void
- * @throws \InvalidArgumentException
- */
- protected function setConnection($connection)
- {
- if (!$connection instanceof \Magento\Framework\DB\Adapter\AdapterInterface) {
- throw new \InvalidArgumentException(
- (string)new \Magento\Framework\Phrase(
- 'dbModel read resource does not implement \Magento\Framework\DB\Adapter\AdapterInterface'
- )
- );
- }
- $this->connection = $connection;
- }
- /**
- * Build sql where condition part
- *
- * @param string|array $field
- * @param null|string|array $condition
- * @return string
- */
- protected function translateCondition($field, $condition)
- {
- $field = $this->getMappedField($field);
- return $this->getConditionSql($this->getConnection()->quoteIdentifier($field), $condition);
- }
- /**
- * Try to get mapped field name for filter to collection
- *
- * @param string $field
- * @return string
- */
- protected function getMappedField($field)
- {
- $mapper = $this->getMapper();
- if (isset($mapper['fields'][$field])) {
- $mappedField = $mapper['fields'][$field];
- } else {
- $mappedField = $field;
- }
- return $mappedField;
- }
- /**
- * Retrieve mapper data
- *
- * @return array|bool|null
- */
- protected function getMapper()
- {
- if (isset($this->map)) {
- return $this->map;
- } else {
- return false;
- }
- }
- /**
- * Build SQL statement for condition
- *
- * If $condition integer or string - exact value will be filtered ('eq' condition)
- *
- * If $condition is array - one of the following structures is expected:
- * - array("from" => $fromValue, "to" => $toValue)
- * - array("eq" => $equalValue)
- * - array("neq" => $notEqualValue)
- * - array("like" => $likeValue)
- * - array("in" => array($inValues))
- * - array("nin" => array($notInValues))
- * - array("notnull" => $valueIsNotNull)
- * - array("null" => $valueIsNull)
- * - array("moreq" => $moreOrEqualValue)
- * - array("gt" => $greaterValue)
- * - array("lt" => $lessValue)
- * - array("gteq" => $greaterOrEqualValue)
- * - array("lteq" => $lessOrEqualValue)
- * - array("finset" => $valueInSet)
- * - array("regexp" => $regularExpression)
- * - array("seq" => $stringValue)
- * - array("sneq" => $stringValue)
- *
- * If non matched - sequential array is expected and OR conditions
- * will be built using above mentioned structure
- *
- * @param string $fieldName
- * @param integer|string|array $condition
- * @return string
- */
- protected function getConditionSql($fieldName, $condition)
- {
- return $this->getConnection()->prepareSqlCondition($fieldName, $condition);
- }
- /**
- * Return the field name for the condition.
- *
- * @param string $fieldName
- * @return string
- */
- protected function getConditionFieldName($fieldName)
- {
- return $fieldName;
- }
- /**
- * Hook for operations before rendering filters
- * @return void
- */
- protected function renderFiltersBefore()
- {
- }
- /**
- * Retrieve table name
- *
- * @param string $table
- * @return string
- */
- protected function getTable($table)
- {
- return $this->getResource()->getTable($table);
- }
- /**
- * Get \Magento\Framework\DB\Select object instance
- *
- * @return Select
- */
- protected function getSelect()
- {
- return $this->select;
- }
- }
|