/** * 2016-07-28 * @see dfp_by_trans() * @param OP|int $payment * @param string $type * @return T|null */ function df_trans_by_payment($payment, $type) { return dfcf(function ($paymentId, $type) { /** @var \Magento\Framework\DB\Select $select */ $select = df_db_from('sales_payment_transaction', 'transaction_id'); $select->where('? = payment_id', $paymentId); /** * 2016-08-17 * Раньше здесь стояло условие * $select->where('parent_txn_id IS NULL'); * потому что код использовался только для получения первой (родительской) транзакции. * Убрал это условие, потому что даже для первой транзакции оно не нужно: * ниже ведь используется операция order, и транзакция с минимальным идентификатором * и будет родительской. * Для функции же @used-by df_trans_by_payment_last() условие * $select->where('parent_txn_id IS NULL'); * и вовсе ошибочно: оно отбраковывает все дочерние транзакции. */ /** * 2016-07-28 * Раньше стояла проверка: df_assert_eq(1, count($txnIds)); * Однако при разработке платёжных модулей бывает, * что у первых транзакций данные не всегда корректны. * Негоже из-за этого падать, лучше вернуть просто первую транзакцию, как нас и просят. */ $select->order('transaction_id ' . ('first' === $type ? 'asc' : 'desc')); /** @var int $id */ $id = df_conn()->fetchOne($select, 'transaction_id'); return !$id ? null : df_trans_r()->get($id); }, [df_idn($payment), $type]); }
/** * 2015-10-10 * @param string $name * @param string $label * @return void */ protected final function attribute($name, $label) { /** @var int $ordering */ static $ordering = 1000; df_eav_setup()->addAttribute('customer', $name, ['type' => 'static', 'label' => "{$this->labelPrefix()} {$label}", 'input' => 'text', 'sort_order' => $ordering, 'position' => $ordering++, 'visible' => false, 'system' => false, 'required' => false]); /** @var int $attributeId */ $attributeId = df_first(df_fetch_col('eav_attribute', 'attribute_id', 'attribute_code', $name)); df_conn()->insert(df_table('customer_form_attribute'), ['form_code' => 'adminhtml_customer', 'attribute_id' => $attributeId]); }
/** * 2015-04-12 * @used-by df_table_delete_not() * @used-by Df_Bundle_Model_Resource_Bundle::deleteAllOptions() * @used-by Df_Tax_Setup_3_0_0::customerClassId() * @used-by Df_Tax_Setup_3_0_0::deleteDemoData() * @used-by Df_Cms_Model_Resource_Hierarchy_Node::deleteNodesByPageId() * @used-by Df_Cms_Model_Resource_Hierarchy_Node::dropNodes() * @used-by Df_Directory_Setup_Processor_InstallRegions::regionsDelete() * @used-by Df_PromoGift_Model_Resource_Indexer::deleteGiftsForProduct() * @used-by Df_PromoGift_Model_Resource_Indexer::deleteGiftsForRule() * @used-by Df_PromoGift_Model_Resource_Indexer::deleteGiftsForWebsite() * @used-by Df_Reward_Setup_1_0_0::_process() * @used-by Df_YandexMarket_Setup_2_42_1::_process() * @param string $table * @param string $columnName * @param int|string|int[]|string[] $values * @param bool $not [optional] * @return void */ function df_table_delete($table, $columnName, $values, $not = false) { /** @var string $condition */ $condition = df_sql_predicate_simple($values, $not); df_conn()->delete(df_table($table), ["{$columnName} {$condition}" => $values]); }
/** * 2016-01-28 * @override * @see \Magento\Framework\Model\ResourceModel\AbstractResource::getConnection() * @return \Magento\Framework\DB\Adapter\AdapterInterface */ protected function getConnection() { return df_conn(); }
/** * 2016-03-15 * How to programmatically check whether a customer is new or returning? https://mage2.pro/t/1617 * @param int|null $id * @return bool */ function df_customer_is_new($id) { return dfcf(function ($id) { return !$id || !df_conn()->fetchOne(df_db_from('sales_order', 'COUNT(*)')->where('? = customer_id', $id)->where('state IN (?)', [O::STATE_COMPLETE, O::STATE_PROCESSING])); }, [$id]); }
/** * @used-by execute() * @return MC|null * 2016-12-01 * Отныне метод может (и будет) возвращать null в том случае, * когда учётная запись покупателя отсутствует в Magento, * а метод @see canRegister() вернул false (случай Blackbaud NetCommunity). */ private function mc() { return dfc($this, function () { /** @var MCR $resource */ $resource = df_customer_resource(); /** @var \Magento\Framework\DB\Select $select */ $select = df_db_from($resource, $resource->getEntityIdField()); /** * 2015-10-10 * 1) Полученный нами от браузера идентификатор пользователя Facebook * не является глобальным: он разный для разных приложений. * 2) Я так понял, что нельзя использовать одно и то же приложение Facebook * сразу на нескольких доменах. * 3) Из пунктов 1 и 2 следует, что нам нельзя идентифицировать пользователя Facebook * по его идентификатору: ведь Magento — многодоменная система. * * Есть выход: token_for_business * https://developers.facebook.com/docs/apps/upgrading#upgrading_v2_0_user_ids * https://developers.facebook.com/docs/apps/for-business * https://business.facebook.com/ */ // 2016-11-21 // Добавил возможность идентификации покупателей по email. // Вроде бы Discourse поступает аналогично. $select->where(df_db_or(df_db_quote_into("? = {$this->fId()}", $this->c()->id()), !$this->c()->email() ? null : ['? = email', $this->c()->email()])); /** * @see \Magento\Customer\Model\ResourceModel\Customer::loadByEmail() * https://github.com/magento/magento2/blob/2e2785cc6a78dc073a4d5bb5a88bd23161d3835c/app/code/Magento/Customer/Model/Resource/Customer.php#L215 */ if (!df_are_customers_global()) { /** * @see \Magento\Customer\Model\CustomerRegistry::retrieveByEmail() * https://github.com/magento/magento2/blob/2e2785cc6a78dc073a4d5bb5a88bd23161d3835c/app/code/Magento/Customer/Model/CustomerRegistry.php#L104 * @see \Magento\Customer\Model\ResourceModel\Customer::loadByEmail() * https://github.com/magento/magento2/blob/2e2785cc6a78dc073a4d5bb5a88bd23161d3835c/app/code/Magento/Customer/Model/Resource/Customer.php#L222 */ $select->where('? = website_id', df_store_m()->getStore()->getWebsiteId()); } /** * 2016-03-01 * @uses \Zend_Db_Adapter_Abstract::fetchOne() возвращает false при пустом результате запроса. * https://mage2.pro/t/853 * @var int|false $customerId */ $customerId = df_conn()->fetchOne($select); /** @var MC|null $result */ if ($result = !$customerId && !$this->canRegister() ? null : df_om()->create(MC::class)) { if (!$customerId) { $this->register($result); } else { $resource->load($result, $customerId); // Обновляем в нашей БД полученую от сервиса авторизации информацию о покупателе. $result->addData(dfa_select($this->customerData(), $this->customerFieldsToSync())); $result->save(); } /** * 2015-10-08 * Ядро здесь делает так: * $customerModel = $this->customerFactory->create()->updateData($customer); * @see \Magento\Customer\Model\AccountManagement::authenticate() * https://github.com/magento/magento2/blob/2.0.0/app/code/Magento/Customer/Model/AccountManagement.php#L381 * Я так понимаю, ядро так делает потому, что выше там код: * $customer = $this->customerRepository->get($username); * и этот код необязательно возвращает объект класса @see \Magento\Customer\Model\Customer * а может вернуть что-то другое, поддерживающее интерфейс * @see \Magento\Customer\Api\Data\CustomerInterface * @see \Magento\Customer\Api\CustomerRepositoryInterface::get() */ /** * По аналогии с @see \Magento\Customer\Model\AccountManagement::authenticate() * https://github.com/magento/magento2/blob/2.0.0/app/code/Magento/Customer/Model/AccountManagement.php#L382-L385 */ df_dispatch('customer_customer_authenticated', ['model' => $result, 'password' => '']); /** * 2015-10-08 * Не знаю, нужно ли это на самом деле. * Сделал по аналогии с @see \Magento\Customer\Model\CustomerRegistry::retrieveByEmail() * https://github.com/magento/magento2/blob/2.0.0/app/code/Magento/Customer/Model/CustomerRegistry.php#L133-L134 * * 2016-12-01 * Однозначно нужно. */ df_customer_registry()->push($result); // 2015-12-10 // Иначе новый покупатель не попадает в таблицу «customer_grid_flat». $result->reindex(); } return $result; }); }
/** * 2016-11-04 * «How to rename a database column?» https://mage2.pro/t/2240 * Unfortunatyly, MySQL does not allow to rename a database column * without repeating the column's definition: http://stackoverflow.com/questions/8553130 * The Magento 2 core classes do not have such method too. * So, we implement such function ourself. * @param string $table * @param string $from The column should exist in the table! * @param string $to * @return void */ function df_db_column_rename($table, $from, $to) { /** * 2016-11-04 * @uses df_table() call is required here, * because @uses \Magento\Framework\DB\Adapter\Pdo\Mysql methods * does not add the custom table prefix to the $name. * The custom table prefix could be set my a Magento 2 administrator * during Magento 2 intallation (see the «table_prefix» key in the app/etc/env.php file). */ $table = df_table($table); /** @var array(string => string|int|null) $definitionRaw */ $definitionRaw = df_db_column_describe($table, $from); /** * 2016-11-04 * @var array(string => string|int|null) $definition * Got an array like: { "name": "test_7781", "type": "text", "length": "255", "options": [], "comment": "Test 7781" } */ $definition = df_conn()->getColumnCreateByDescribe($definitionRaw); /** * 2016-11-04 * The @uses \Magento\Framework\DB\Adapter\Pdo\Mysql::getColumnCreateByDescribe() method * sets the table's name as the table's comment: * https://github.com/magento/magento2/blob/2.1.2/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php#L1600 * We remove this comment, because the table will be renamed. */ unset($definition['comment']); df_conn()->changeColumn($table, $from, $to, $definition); /** * 2016-11-04 * @see \Magento\Framework\DB\Adapter\Pdo\Mysql::resetDdlCache() call is not needed here, * because it has already been called * from @uses \Magento\Framework\DB\Adapter\Pdo\Mysql::changeColumn() * https://github.com/magento/magento2/blob/2.1.2/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php#L1010 */ }