Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Subscription.php
Go to the documentation of this file.
1 <?php
8 
12 
19 {
25  protected $connection;
26 
30  protected $triggerFactory;
31 
35  protected $viewCollection;
36 
40  protected $view;
41 
45  protected $tableName;
46 
50  protected $columnName;
51 
57  protected $linkedViews = [];
58 
65  private $ignoredUpdateColumns = [];
66 
70  protected $resource;
71 
81  public function __construct(
83  \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory,
85  \Magento\Framework\Mview\ViewInterface $view,
86  $tableName,
88  $ignoredUpdateColumns = []
89  ) {
90  $this->connection = $resource->getConnection();
91  $this->triggerFactory = $triggerFactory;
92  $this->viewCollection = $viewCollection;
93  $this->view = $view;
94  $this->tableName = $tableName;
95  $this->columnName = $columnName;
96  $this->resource = $resource;
97  $this->ignoredUpdateColumns = $ignoredUpdateColumns;
98  }
99 
105  public function create()
106  {
107  foreach (Trigger::getListOfEvents() as $event) {
108  $triggerName = $this->getAfterEventTriggerName($event);
110  $trigger = $this->triggerFactory->create()
111  ->setName($triggerName)
112  ->setTime(Trigger::TIME_AFTER)
113  ->setEvent($event)
114  ->setTable($this->resource->getTableName($this->tableName));
115 
116  $trigger->addStatement($this->buildStatement($event, $this->getView()->getChangelog()));
117 
118  // Add statements for linked views
119  foreach ($this->getLinkedViews() as $view) {
121  $trigger->addStatement($this->buildStatement($event, $view->getChangelog()));
122  }
123 
124  $this->connection->dropTrigger($trigger->getName());
125  $this->connection->createTrigger($trigger);
126  }
127 
128  return $this;
129  }
130 
136  public function remove()
137  {
138  foreach (Trigger::getListOfEvents() as $event) {
139  $triggerName = $this->getAfterEventTriggerName($event);
141  $trigger = $this->triggerFactory->create()
142  ->setName($triggerName)
143  ->setTime(Trigger::TIME_AFTER)
144  ->setEvent($event)
145  ->setTable($this->resource->getTableName($this->getTableName()));
146 
147  // Add statements for linked views
148  foreach ($this->getLinkedViews() as $view) {
150  $trigger->addStatement($this->buildStatement($event, $view->getChangelog()));
151  }
152 
153  $this->connection->dropTrigger($trigger->getName());
154 
155  // Re-create trigger if trigger used by linked views
156  if ($trigger->getStatements()) {
157  $this->connection->createTrigger($trigger);
158  }
159  }
160 
161  return $this;
162  }
163 
169  protected function getLinkedViews()
170  {
171  if (!$this->linkedViews) {
172  $viewList = $this->viewCollection->getViewsByStateMode(StateInterface::MODE_ENABLED);
173 
174  foreach ($viewList as $view) {
176  // Skip the current view
177  if ($view->getId() == $this->getView()->getId()) {
178  continue;
179  }
180  // Search in view subscriptions
181  foreach ($view->getSubscriptions() as $subscription) {
182  if ($subscription['name'] != $this->getTableName()) {
183  continue;
184  }
185  $this->linkedViews[] = $view;
186  }
187  }
188  }
189  return $this->linkedViews;
190  }
191 
199  protected function buildStatement($event, $changelog)
200  {
201  switch ($event) {
202  case Trigger::EVENT_INSERT:
203  $trigger = "INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);";
204  break;
205  case Trigger::EVENT_UPDATE:
206  $tableName = $this->resource->getTableName($this->getTableName());
207  $trigger = "INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);";
208  if ($this->connection->isTableExists($tableName) &&
209  $describe = $this->connection->describeTable($tableName)
210  ) {
211  $columnNames = array_column($describe, 'COLUMN_NAME');
212  $columnNames = array_diff($columnNames, $this->ignoredUpdateColumns);
213  if ($columnNames) {
214  $columns = [];
215  foreach ($columnNames as $columnName) {
216  $columns[] = sprintf(
217  'NEW.%1$s <=> OLD.%1$s',
218  $this->connection->quoteIdentifier($columnName)
219  );
220  }
221  $trigger = sprintf(
222  "IF (%s) THEN %s END IF;",
223  implode(' OR ', $columns),
224  $trigger
225  );
226  }
227  }
228  break;
229  case Trigger::EVENT_DELETE:
230  $trigger = "INSERT IGNORE INTO %s (%s) VALUES (OLD.%s);";
231  break;
232  default:
233  return '';
234  }
235  return sprintf(
236  $trigger,
237  $this->connection->quoteIdentifier($this->resource->getTableName($changelog->getName())),
238  $this->connection->quoteIdentifier($changelog->getColumnName()),
239  $this->connection->quoteIdentifier($this->getColumnName())
240  );
241  }
242 
250  private function getAfterEventTriggerName($event)
251  {
252  return $this->resource->getTriggerName(
253  $this->resource->getTableName($this->getTableName()),
254  Trigger::TIME_AFTER,
255  $event
256  );
257  }
258 
265  public function getView()
266  {
267  return $this->view;
268  }
269 
276  public function getTableName()
277  {
278  return $this->tableName;
279  }
280 
287  public function getColumnName()
288  {
289  return $this->columnName;
290  }
291 }
__construct(ResourceConnection $resource, \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory, \Magento\Framework\Mview\View\CollectionInterface $viewCollection, \Magento\Framework\Mview\ViewInterface $view, $tableName, $columnName, $ignoredUpdateColumns=[])
$columns
Definition: default.phtml:15
$trigger
Definition: trigger.php:27