Initial commit

This commit is contained in:
2020-10-07 10:37:15 +02:00
commit ce5f440392
28157 changed files with 4429172 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
2014-04-17 11:40:33 +0200 Bug fix (PS 1.5): ps_version_compliancy removed
2014-04-15 18:54:08 +0200 [*] hookDisplayLeftColumnProduct() added
2014-04-09 18:28:59 +0200 Fix #PSCSX-1684, display correct date format
2014-03-21 10:55:15 +0100 Initial commit

View File

@@ -0,0 +1,22 @@
GitHub contributors:
--------------------------------
- AlexEven
- Damien Metzger
- Francois Gaillard
- Gregory Roussac
- Jerome Nadaud
- Jérôme Nadaud
- Maxime Biloé
- Oksydan
- PierreRambaud
- aleeks
- clarkdave
- eternoendless
- gRoussac
- gaillafr
- indesign47
- jolelievre
- julienbourdeau
- maximebiloe
- sfroment
- xBorderie

View File

@@ -0,0 +1,47 @@
Academic Free License ("AFL") v. 3.0
This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
Licensed under the Academic Free License version 3.0
1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
a) to reproduce the Original Work in copies, either alone or as part of a collective work;
b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
c) to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License;
d) to perform the Original Work publicly; and
e) to display the Original Work publicly.
2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
5) External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
9) Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
12) Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
13) Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
16) Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.

View File

@@ -0,0 +1,459 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class ProductComment extends ObjectModel
{
public $id;
/** @var int Product's id */
public $id_product;
/** @var int Customer's id */
public $id_customer;
/** @var int Guest's id */
public $id_guest;
/** @var int Customer name */
public $customer_name;
/** @var string Title */
public $title;
/** @var string Content */
public $content;
/** @var int Grade */
public $grade;
/** @var bool Validate */
public $validate = 0;
public $deleted = 0;
/** @var string Object creation date */
public $date_add;
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => 'product_comment',
'primary' => 'id_product_comment',
'fields' => array(
'id_product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'id_customer' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'id_guest' => array('type' => self::TYPE_INT),
'customer_name' => array('type' => self::TYPE_STRING),
'title' => array('type' => self::TYPE_STRING),
'content' => array('type' => self::TYPE_STRING, 'validate' => 'isMessage', 'size' => 65535, 'required' => true),
'grade' => array('type' => self::TYPE_FLOAT, 'validate' => 'isFloat'),
'validate' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'deleted' => array('type' => self::TYPE_BOOL),
'date_add' => array('type' => self::TYPE_DATE),
),
);
/**
* Get comments by IdProduct
*
* @return array Comments
*/
public static function getByProduct($id_product, $p = 1, $n = null, $id_customer = null)
{
if (!Validate::isUnsignedId($id_product)) {
return false;
}
$validate = Configuration::get('PRODUCT_COMMENTS_MODERATE');
$p = (int) $p;
$n = (int) $n;
if ($p <= 1) {
$p = 1;
}
if ($n != null && $n <= 0) {
$n = 5;
}
$cache_id = 'ProductComment::getByProduct_' . (int) $id_product . '-' . (int) $p . '-' . (int) $n . '-' . (int) $id_customer . '-' . (bool) $validate;
if (!Cache::isStored($cache_id)) {
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT pc.`id_product_comment`,
(SELECT count(*) FROM `' . _DB_PREFIX_ . 'product_comment_usefulness` pcu WHERE pcu.`id_product_comment` = pc.`id_product_comment` AND pcu.`usefulness` = 1) as total_useful,
(SELECT count(*) FROM `' . _DB_PREFIX_ . 'product_comment_usefulness` pcu WHERE pcu.`id_product_comment` = pc.`id_product_comment`) as total_advice, ' .
((int) $id_customer ? '(SELECT count(*) FROM `' . _DB_PREFIX_ . 'product_comment_usefulness` pcuc WHERE pcuc.`id_product_comment` = pc.`id_product_comment` AND pcuc.id_customer = ' . (int) $id_customer . ') as customer_advice, ' : '') .
((int) $id_customer ? '(SELECT count(*) FROM `' . _DB_PREFIX_ . 'product_comment_report` pcrc WHERE pcrc.`id_product_comment` = pc.`id_product_comment` AND pcrc.id_customer = ' . (int) $id_customer . ') as customer_report, ' : '') . '
IF(c.id_customer, CONCAT(c.`firstname`, \' \', LEFT(c.`lastname`, 1)), pc.customer_name) customer_name, pc.`content`, pc.`grade`, pc.`date_add`, pc.title
FROM `' . _DB_PREFIX_ . 'product_comment` pc
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON c.`id_customer` = pc.`id_customer`
WHERE pc.`id_product` = ' . (int) ($id_product) . ($validate == '1' ? ' AND pc.`validate` = 1' : '') . '
ORDER BY pc.`date_add` DESC
' . ($n ? 'LIMIT ' . (int) (($p - 1) * $n) . ', ' . (int) ($n) : ''));
Cache::store($cache_id, $result);
}
return Cache::retrieve($cache_id);
}
/**
* Return customer's comment
*
* @return arrayComments
*/
public static function getByCustomer($id_product, $id_customer, $get_last = false, $id_guest = false)
{
$cache_id = 'ProductComment::getByCustomer_' . (int) $id_product . '-' . (int) $id_customer . '-' . (bool) $get_last . '-' . (int) $id_guest;
if (!Cache::isStored($cache_id)) {
$results = Db::getInstance()->executeS('
SELECT *
FROM `' . _DB_PREFIX_ . 'product_comment` pc
WHERE pc.`id_product` = ' . (int) $id_product . '
AND ' . (!$id_guest ? 'pc.`id_customer` = ' . (int) $id_customer : 'pc.`id_guest` = ' . (int) $id_guest) . '
ORDER BY pc.`date_add` DESC '
. ($get_last ? 'LIMIT 1' : '')
);
if ($get_last && count($results)) {
$results = array_shift($results);
}
Cache::store($cache_id, $results);
}
return Cache::retrieve($cache_id);
}
/**
* Get Grade By product
*
* @return array Grades
*/
public static function getGradeByProduct($id_product, $id_lang)
{
if (!Validate::isUnsignedId($id_product) ||
!Validate::isUnsignedId($id_lang)) {
return false;
}
$validate = Configuration::get('PRODUCT_COMMENTS_MODERATE');
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT pc.`id_product_comment`, pcg.`grade`, pccl.`name`, pcc.`id_product_comment_criterion`
FROM `' . _DB_PREFIX_ . 'product_comment` pc
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_grade` pcg ON (pcg.`id_product_comment` = pc.`id_product_comment`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_criterion` pcc ON (pcc.`id_product_comment_criterion` = pcg.`id_product_comment_criterion`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_lang` pccl ON (pccl.`id_product_comment_criterion` = pcg.`id_product_comment_criterion`)
WHERE pc.`id_product` = ' . (int) $id_product . '
AND pccl.`id_lang` = ' . (int) $id_lang .
($validate == '1' ? ' AND pc.`validate` = 1' : ''));
}
public static function getRatings($id_product)
{
$validate = Configuration::get('PRODUCT_COMMENTS_MODERATE');
$sql = 'SELECT (SUM(pc.`grade`) / COUNT(pc.`grade`)) AS avg,
MIN(pc.`grade`) AS min,
MAX(pc.`grade`) AS max
FROM `' . _DB_PREFIX_ . 'product_comment` pc
WHERE pc.`id_product` = ' . (int) $id_product . '
AND pc.`deleted` = 0' .
($validate == '1' ? ' AND pc.`validate` = 1' : '');
return Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);
}
public static function getAverageGrade($id_product)
{
$validate = Configuration::get('PRODUCT_COMMENTS_MODERATE');
return Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
SELECT (SUM(pc.`grade`) / COUNT(pc.`grade`)) AS grade
FROM `' . _DB_PREFIX_ . 'product_comment` pc
WHERE pc.`id_product` = ' . (int) $id_product . '
AND pc.`deleted` = 0' .
($validate == '1' ? ' AND pc.`validate` = 1' : ''));
}
public static function getAveragesByProduct($id_product, $id_lang)
{
/* Get all grades */
$grades = ProductComment::getGradeByProduct((int) $id_product, (int) $id_lang);
$total = ProductComment::getGradedCommentNumber((int) $id_product);
if (!count($grades) || (!$total)) {
return array();
}
/* Addition grades for each criterion */
$criterionsGradeTotal = array();
$count_grades = count($grades);
for ($i = 0; $i < $count_grades; ++$i) {
if (array_key_exists($grades[$i]['id_product_comment_criterion'], $criterionsGradeTotal) === false) {
$criterionsGradeTotal[$grades[$i]['id_product_comment_criterion']] = (int) ($grades[$i]['grade']);
} else {
$criterionsGradeTotal[$grades[$i]['id_product_comment_criterion']] += (int) ($grades[$i]['grade']);
}
}
/* Finally compute the averages */
$averages = array();
foreach ($criterionsGradeTotal as $key => $criterionGradeTotal) {
$averages[(int) ($key)] = (int) ($total) ? ((int) ($criterionGradeTotal) / (int) ($total)) : 0;
}
return $averages;
}
/**
* Return number of comments and average grade by products
*
* @return array Info
*/
public static function getCommentNumber($id_product)
{
if (!Validate::isUnsignedId($id_product)) {
return false;
}
$validate = (int) Configuration::get('PRODUCT_COMMENTS_MODERATE');
$cache_id = 'ProductComment::getCommentNumber_' . (int) $id_product . '-' . $validate;
if (!Cache::isStored($cache_id)) {
$result = (int) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT COUNT(`id_product_comment`) AS "nbr"
FROM `' . _DB_PREFIX_ . 'product_comment` pc
WHERE `id_product` = ' . (int) ($id_product) . ($validate == '1' ? ' AND `validate` = 1' : ''));
Cache::store($cache_id, $result);
}
return Cache::retrieve($cache_id);
}
/**
* Return number of comments and average grade by products
*
* @return array Info
*/
public static function getGradedCommentNumber($id_product)
{
if (!Validate::isUnsignedId($id_product)) {
return false;
}
$validate = (int) Configuration::get('PRODUCT_COMMENTS_MODERATE');
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
SELECT COUNT(pc.`id_product`) AS nbr
FROM `' . _DB_PREFIX_ . 'product_comment` pc
WHERE `id_product` = ' . (int) ($id_product) . ($validate == '1' ? ' AND `validate` = 1' : '') . '
AND `grade` > 0');
return (int) ($result['nbr']);
}
/**
* Get comments by Validation
*
* @return array Comments
*/
public static function getByValidate($validate = '0', $deleted = false)
{
$sql = '
SELECT pc.`id_product_comment`, pc.`id_product`, IF(c.id_customer, CONCAT(c.`firstname`, \' \', c.`lastname`), pc.customer_name) customer_name, pc.`title`, pc.`content`, pc.`grade`, pc.`date_add`, pl.`name`
FROM `' . _DB_PREFIX_ . 'product_comment` pc
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = pc.`id_customer`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.`id_product` = pc.`id_product` AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . Shop::addSqlRestrictionOnLang('pl') . ')
WHERE pc.`validate` = ' . (int) $validate;
$sql .= ' ORDER BY pc.`date_add` DESC';
return Db::getInstance()->executeS($sql);
}
/**
* Get all comments
*
* @return array Comments
*/
public static function getAll()
{
return Db::getInstance()->executeS('
SELECT pc.`id_product_comment`, pc.`id_product`, IF(c.id_customer, CONCAT(c.`firstname`, \' \', c.`lastname`), pc.customer_name) customer_name, pc.`content`, pc.`grade`, pc.`date_add`, pl.`name`
FROM `' . _DB_PREFIX_ . 'product_comment` pc
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = pc.`id_customer`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.`id_product` = pc.`id_product` AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . Shop::addSqlRestrictionOnLang('pl') . ')
ORDER BY pc.`date_add` DESC');
}
/**
* Validate a comment
*
* @return bool succeed
*/
public function validate($validate = '1')
{
if (!Validate::isUnsignedId($this->id)) {
return false;
}
$success = (Db::getInstance()->execute('
UPDATE `' . _DB_PREFIX_ . 'product_comment` SET
`validate` = ' . (int) $validate . '
WHERE `id_product_comment` = ' . (int) $this->id));
Hook::exec('actionObjectProductCommentValidateAfter', array('object' => $this));
return $success;
}
/**
* Delete a comment, grade and report data
*
* @return bool succeed
*/
public function delete()
{
parent::delete();
ProductComment::deleteGrades($this->id);
ProductComment::deleteReports($this->id);
ProductComment::deleteUsefulness($this->id);
}
/**
* Delete Grades
*
* @return bool succeed
*/
public static function deleteGrades($id_product_comment)
{
if (!Validate::isUnsignedId($id_product_comment)) {
return false;
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_grade`
WHERE `id_product_comment` = ' . (int) $id_product_comment);
}
/**
* Delete Reports
*
* @return bool succeed
*/
public static function deleteReports($id_product_comment)
{
if (!Validate::isUnsignedId($id_product_comment)) {
return false;
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_report`
WHERE `id_product_comment` = ' . (int) $id_product_comment);
}
/**
* Delete usefulness
*
* @return bool succeed
*/
public static function deleteUsefulness($id_product_comment)
{
if (!Validate::isUnsignedId($id_product_comment)) {
return false;
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_usefulness`
WHERE `id_product_comment` = ' . (int) $id_product_comment);
}
/**
* Report comment
*
* @return bool
*/
public static function reportComment($id_product_comment, $id_customer)
{
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_report` (`id_product_comment`, `id_customer`)
VALUES (' . (int) $id_product_comment . ', ' . (int) $id_customer . ')');
}
/**
* Comment already report
*
* @return bool
*/
public static function isAlreadyReport($id_product_comment, $id_customer)
{
return (bool) Db::getInstance()->getValue('
SELECT COUNT(*)
FROM `' . _DB_PREFIX_ . 'product_comment_report`
WHERE `id_customer` = ' . (int) $id_customer . '
AND `id_product_comment` = ' . (int) $id_product_comment);
}
/**
* Set comment usefulness
*
* @return bool
*/
public static function setCommentUsefulness($id_product_comment, $usefulness, $id_customer)
{
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_usefulness` (`id_product_comment`, `usefulness`, `id_customer`)
VALUES (' . (int) $id_product_comment . ', ' . (int) $usefulness . ', ' . (int) $id_customer . ')');
}
/**
* Usefulness already set
*
* @return bool
*/
public static function isAlreadyUsefulness($id_product_comment, $id_customer)
{
return (bool) Db::getInstance()->getValue('
SELECT COUNT(*)
FROM `' . _DB_PREFIX_ . 'product_comment_usefulness`
WHERE `id_customer` = ' . (int) $id_customer . '
AND `id_product_comment` = ' . (int) $id_product_comment);
}
/**
* Get reported comments
*
* @return array Comments
*/
public static function getReportedComments()
{
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT DISTINCT(pc.`id_product_comment`), pc.`id_product`, IF(c.id_customer, CONCAT(c.`firstname`, \' \', c.`lastname`), pc.customer_name) customer_name, pc.`content`, pc.`grade`, pc.`date_add`, pl.`name`, pc.`title`
FROM `' . _DB_PREFIX_ . 'product_comment_report` pcr
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment` pc
ON pcr.id_product_comment = pc.id_product_comment
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = pc.`id_customer`)
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.`id_product` = pc.`id_product` AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . ' AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . Shop::addSqlRestrictionOnLang('pl') . ')
ORDER BY pc.`date_add` DESC');
}
}

View File

@@ -0,0 +1,284 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
class ProductCommentCriterion extends ObjectModel
{
const NAME_MAX_LENGTH = 64;
public $id;
public $id_product_comment_criterion_type;
public $name;
public $active = true;
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => 'product_comment_criterion',
'primary' => 'id_product_comment_criterion',
'multilang' => true,
'fields' => array(
'id_product_comment_criterion_type' => array('type' => self::TYPE_INT),
'active' => array('type' => self::TYPE_BOOL),
// Lang fields
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => self::NAME_MAX_LENGTH),
),
);
public function delete()
{
if (!parent::delete()) {
return false;
}
if ($this->id_product_comment_criterion_type == 2) {
if (!Db::getInstance()->execute('
DELETE FROM ' . _DB_PREFIX_ . 'product_comment_criterion_category
WHERE id_product_comment_criterion=' . (int) $this->id)) {
return false;
}
} elseif ($this->id_product_comment_criterion_type == 3) {
if (!Db::getInstance()->execute('
DELETE FROM ' . _DB_PREFIX_ . 'product_comment_criterion_product
WHERE id_product_comment_criterion=' . (int) $this->id)) {
return false;
}
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_grade`
WHERE `id_product_comment_criterion` = ' . (int) $this->id);
}
public function update($nullValues = false)
{
$previousUpdate = new self((int) $this->id);
if (!parent::update($nullValues)) {
return false;
}
if ($previousUpdate->id_product_comment_criterion_type != $this->id_product_comment_criterion_type) {
if ($previousUpdate->id_product_comment_criterion_type == 2) {
return Db::getInstance()->execute('
DELETE FROM ' . _DB_PREFIX_ . 'product_comment_criterion_category
WHERE id_product_comment_criterion = ' . (int) $previousUpdate->id);
} elseif ($previousUpdate->id_product_comment_criterion_type == 3) {
return Db::getInstance()->execute('
DELETE FROM ' . _DB_PREFIX_ . 'product_comment_criterion_product
WHERE id_product_comment_criterion = ' . (int) $previousUpdate->id);
}
}
return true;
}
/**
* Link a Comment Criterion to a product
*
* @return bool succeed
*/
public function addProduct($id_product)
{
if (!Validate::isUnsignedId($id_product)) {
die(Tools::displayError());
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_criterion_product` (`id_product_comment_criterion`, `id_product`)
VALUES(' . (int) $this->id . ',' . (int) $id_product . ')
');
}
/**
* Link a Comment Criterion to a category
*
* @return bool succeed
*/
public function addCategory($id_category)
{
if (!Validate::isUnsignedId($id_category)) {
die(Tools::displayError());
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_criterion_category` (`id_product_comment_criterion`, `id_category`)
VALUES(' . (int) $this->id . ',' . (int) $id_category . ')
');
}
/**
* Add grade to a criterion
*
* @return bool succeed
*/
public function addGrade($id_product_comment, $grade)
{
if (!Validate::isUnsignedId($id_product_comment)) {
die(Tools::displayError());
}
if ($grade < 0) {
$grade = 0;
} elseif ($grade > 10) {
$grade = 10;
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_grade`
(`id_product_comment`, `id_product_comment_criterion`, `grade`) VALUES(
' . (int) ($id_product_comment) . ',
' . (int) $this->id . ',
' . (int) ($grade) . ')');
}
/**
* Get criterion by Product
*
* @return array Criterion
*/
public static function getByProduct($id_product, $id_lang)
{
if (!Validate::isUnsignedId($id_product) ||
!Validate::isUnsignedId($id_lang)) {
die(Tools::displayError());
}
$alias = 'p';
$table = '';
// check if version > 1.5 to add shop association
if (version_compare(_PS_VERSION_, '1.5', '>')) {
$table = '_shop';
$alias = 'ps';
}
$cache_id = 'ProductCommentCriterion::getByProduct_' . (int) $id_product . '-' . (int) $id_lang;
if (!Cache::isStored($cache_id)) {
$result = Db::getInstance()->executeS('
SELECT pcc.`id_product_comment_criterion`, pccl.`name`
FROM `' . _DB_PREFIX_ . 'product_comment_criterion` pcc
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_lang` pccl
ON (pcc.id_product_comment_criterion = pccl.id_product_comment_criterion)
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_product` pccp
ON (pcc.`id_product_comment_criterion` = pccp.`id_product_comment_criterion` AND pccp.`id_product` = ' . (int) $id_product . ')
LEFT JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_category` pccc
ON (pcc.`id_product_comment_criterion` = pccc.`id_product_comment_criterion`)
LEFT JOIN `' . _DB_PREFIX_ . 'product' . $table . '` ' . $alias . '
ON (' . $alias . '.id_category_default = pccc.id_category AND ' . $alias . '.id_product = ' . (int) $id_product . ')
WHERE pccl.`id_lang` = ' . (int) ($id_lang) . '
AND (
pccp.id_product IS NOT NULL
OR ps.id_product IS NOT NULL
OR pcc.id_product_comment_criterion_type = 1
)
AND pcc.active = 1
GROUP BY pcc.id_product_comment_criterion
');
Cache::store($cache_id, $result);
}
return Cache::retrieve($cache_id);
}
/**
* Get Criterions
*
* @return array Criterions
*/
public static function getCriterions($id_lang, $type = false, $active = false)
{
if (!Validate::isUnsignedId($id_lang)) {
die(Tools::displayError());
}
$sql = '
SELECT pcc.`id_product_comment_criterion`, pcc.id_product_comment_criterion_type, pccl.`name`, pcc.active
FROM `' . _DB_PREFIX_ . 'product_comment_criterion` pcc
JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_lang` pccl ON (pcc.id_product_comment_criterion = pccl.id_product_comment_criterion)
WHERE pccl.`id_lang` = ' . (int) $id_lang . ($active ? ' AND active = 1' : '') . ($type ? ' AND id_product_comment_criterion_type = ' . (int) $type : '') . '
ORDER BY pccl.`name` ASC';
$criterions = Db::getInstance()->executeS($sql);
$types = self::getTypes();
foreach ($criterions as $key => $data) {
$criterions[$key]['type_name'] = $types[$data['id_product_comment_criterion_type']];
}
return $criterions;
}
public function getProducts()
{
$res = Db::getInstance()->executeS('
SELECT pccp.id_product, pccp.id_product_comment_criterion
FROM `' . _DB_PREFIX_ . 'product_comment_criterion_product` pccp
WHERE pccp.id_product_comment_criterion = ' . (int) $this->id);
$products = array();
if ($res) {
foreach ($res as $row) {
$products[] = (int) $row['id_product'];
}
}
return $products;
}
public function getCategories()
{
$res = Db::getInstance()->executeS('
SELECT pccc.id_category, pccc.id_product_comment_criterion
FROM `' . _DB_PREFIX_ . 'product_comment_criterion_category` pccc
WHERE pccc.id_product_comment_criterion = ' . (int) $this->id);
$criterions = array();
if ($res) {
foreach ($res as $row) {
$criterions[] = (int) $row['id_category'];
}
}
return $criterions;
}
public function deleteCategories()
{
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_category`
WHERE `id_product_comment_criterion` = ' . (int) $this->id);
}
public function deleteProducts()
{
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_product`
WHERE `id_product_comment_criterion` = ' . (int) $this->id);
}
public static function getTypes()
{
// Instance of module class for translations
$module = new ProductComments();
return array(
1 => $module->getTranslator()->trans('Valid for the entire catalog', [], 'Modules.Productcomments.Admin'),
2 => $module->getTranslator()->trans('Restricted to some categories', [], 'Modules.Productcomments.Admin'),
3 => $module->getTranslator()->trans('Restricted to some products', [], 'Modules.Productcomments.Admin'),
);
}
}

View File

@@ -0,0 +1,192 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
class ProductCommentCriterion
{
/**
* Add a Comment Criterion
*
* @return bool succeed
*/
public static function add($id_lang, $name)
{
if (!Validate::isUnsignedId($id_lang) ||
!Validate::isMessage($name)) {
die(Tools::displayError());
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_criterion`
(`id_lang`, `name`) VALUES(
' . (int) ($id_lang) . ',
\'' . pSQL($name) . '\')');
}
/**
* Link a Comment Criterion to a product
*
* @return bool succeed
*/
public static function addToProduct($id_product_comment_criterion, $id_product)
{
if (!Validate::isUnsignedId($id_product_comment_criterion) ||
!Validate::isUnsignedId($id_product)) {
die(Tools::displayError());
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_criterion_product`
(`id_product_comment_criterion`, `id_product`) VALUES(
' . (int) ($id_product_comment_criterion) . ',
' . (int) ($id_product) . ')');
}
/**
* Add grade to a criterion
*
* @return bool succeed
*/
public static function addGrade($id_product_comment, $id_product_comment_criterion, $grade)
{
if (!Validate::isUnsignedId($id_product_comment) ||
!Validate::isUnsignedId($id_product_comment_criterion)) {
die(Tools::displayError());
}
if ($grade < 0) {
$grade = 0;
} elseif ($grade > 10) {
$grade = 10;
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'product_comment_grade`
(`id_product_comment`, `id_product_comment_criterion`, `grade`) VALUES(
' . (int) ($id_product_comment) . ',
' . (int) ($id_product_comment_criterion) . ',
' . (int) ($grade) . ')');
}
/**
* Update criterion
*
* @return bool succeed
*/
public static function update($id_product_comment_criterion, $id_lang, $name)
{
if (!Validate::isUnsignedId($id_product_comment_criterion) ||
!Validate::isUnsignedId($id_lang) ||
!Validate::isMessage($name)) {
die(Tools::displayError());
}
return Db::getInstance()->execute('
UPDATE `' . _DB_PREFIX_ . 'product_comment_criterion` SET
`name` = \'' . pSQL($name) . '\'
WHERE `id_product_comment_criterion` = ' . (int) ($id_product_comment_criterion) . ' AND
`id_lang` = ' . (int) ($id_lang));
}
/**
* Get criterion by Product
*
* @return array Criterion
*/
public static function getByProduct($id_product, $id_lang)
{
if (!Validate::isUnsignedId($id_product) ||
!Validate::isUnsignedId($id_lang)) {
die(Tools::displayError());
}
return Db::getInstance()->executeS('
SELECT pcc.`id_product_comment_criterion`, pcc.`name`
FROM `' . _DB_PREFIX_ . 'product_comment_criterion` pcc
INNER JOIN `' . _DB_PREFIX_ . 'product_comment_criterion_product` pccp ON pcc.`id_product_comment_criterion` = pccp.`id_product_comment_criterion`
WHERE pccp.`id_product` = ' . (int) ($id_product) . ' AND
pcc.`id_lang` = ' . (int) ($id_lang));
}
/**
* Get Criterions
*
* @return array Criterions
*/
public static function get($id_lang)
{
if (!Validate::isUnsignedId($id_lang)) {
die(Tools::displayError());
}
return Db::getInstance()->executeS('
SELECT pcc.`id_product_comment_criterion`, pcc.`name`
FROM `' . _DB_PREFIX_ . 'product_comment_criterion` pcc
WHERE pcc.`id_lang` = ' . (int) ($id_lang) . '
ORDER BY pcc.`name` ASC');
}
/**
* Delete product criterion by product
*
* @return bool succeed
*/
public static function deleteByProduct($id_product)
{
if (!Validate::isUnsignedId($id_product)) {
die(Tools::displayError());
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_product`
WHERE `id_product` = ' . (int) ($id_product));
}
/**
* Delete all reference of a criterion
*
* @return bool succeed
*/
public static function delete($id_product_comment_criterion)
{
if (!Validate::isUnsignedId($id_product_comment_criterion)) {
die(Tools::displayError());
}
$result = Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_grade`
WHERE `id_product_comment_criterion` = ' . (int) ($id_product_comment_criterion));
if ($result === false) {
return $result;
}
$result = Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_product`
WHERE `id_product_comment_criterion` = ' . (int) ($id_product_comment_criterion));
if ($result === false) {
return $result;
}
return Db::getInstance()->execute('
DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion`
WHERE `id_product_comment_criterion` = ' . (int) ($id_product_comment_criterion));
}
}

View File

@@ -0,0 +1,42 @@
# Product Comments
## About
Allows users to post reviews and rate products on specific criteria.
## Multistore compatibility
This module is partially compatible with the multistore feature. Some of its options might not be available.
### Update dependency
The only dependency for this module (for now) is https://github.com/flaviusmatis/simplePagination.js.git
You can install/update it by launching the command
```
# yarn install
```
(We use yarn because this library is not served as a package for npm).
This will install the library js in views/js folder.
## Reporting issues
You can report issues with this module in the main PrestaShop repository. [Click here to report an issue][report-issue].
## Contributing
PrestaShop modules are open source extensions to the [PrestaShop e-commerce platform][prestashop]. Everyone is welcome and even encouraged to contribute with their own improvements!
Just make sure to follow our [contribution guidelines][contribution-guidelines].
## License
This module is released under the [Academic Free License 3.0][AFL-3.0]
[report-issue]: https://github.com/PrestaShop/PrestaShop/issues/new/choose
[prestashop]: https://www.prestashop.com/
[contribution-guidelines]: https://devdocs.prestashop.com/1.7/contribute/contribution-guidelines/project-modules/
[AFL-3.0]: https://opensource.org/licenses/AFL-3.0

View File

@@ -0,0 +1,40 @@
{
"name": "prestashop/productcomments",
"description": "PrestaShop module productcomments",
"homepage": "https://github.com/PrestaShop/productcomments",
"license": "AFL-3.0",
"authors": [
{
"name": "PrestaShop SA",
"email": "contact@prestashop.com"
}
],
"require": {
"php": ">=5.6.0",
"prestashop/circuit-breaker": "^3.0.0",
"doctrine/cache": "^1.6",
"symfony/css-selector": "^3.4 || ^4.4 || ^5.0",
"guzzlehttp/cache-subscriber": "^0.2.0"
},
"repositories": [
{
"type": "vcs",
"url": "git@github.com:jolelievre/circuit-breaker.git"
}
],
"autoload": {
"psr-4": {
"PrestaShop\\Module\\ProductComment\\": "src/"
},
"classmap": ["productcomments.php"],
"exclude-from-classmap": []
},
"config": {
"preferred-install": "dist",
"prepend-autoloader": false,
"platform": {
"php": "5.6"
}
},
"type": "prestashop-module"
}

456
modules/productcomments/composer.lock generated Normal file
View File

@@ -0,0 +1,456 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0231a703ab1f62ec17708f21bdfe7f40",
"packages": [
{
"name": "doctrine/cache",
"version": "v1.6.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/eb152c5100571c7a45470ff2a35095ab3f3b900b",
"reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b",
"shasum": ""
},
"require": {
"php": "~5.5|~7.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"phpunit/phpunit": "~4.8|~5.0",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
],
"time": "2017-07-22T12:49:21+00:00"
},
{
"name": "guzzlehttp/cache-subscriber",
"version": "0.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/cache-subscriber.git",
"reference": "8c766ba399e4c46383e3eaa220201be62abd101e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/cache-subscriber/zipball/8c766ba399e4c46383e3eaa220201be62abd101e",
"reference": "8c766ba399e4c46383e3eaa220201be62abd101e",
"shasum": ""
},
"require": {
"doctrine/cache": "~1.3",
"guzzlehttp/guzzle": "~5.0",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.2-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Subscriber\\Cache\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle HTTP cache subscriber",
"homepage": "http://guzzlephp.org/",
"keywords": [
"Guzzle",
"cache"
],
"time": "2019-09-16T13:44:55+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "5.3.4",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "b87eda7a7162f95574032da17e9323c9899cb6b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/b87eda7a7162f95574032da17e9323c9899cb6b2",
"reference": "b87eda7a7162f95574032da17e9323c9899cb6b2",
"shasum": ""
},
"require": {
"guzzlehttp/ringphp": "^1.1",
"php": ">=5.4.0",
"react/promise": "^2.2"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.0"
},
"type": "library",
"autoload": {
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"rest",
"web service"
],
"time": "2019-10-30T09:32:00+00:00"
},
{
"name": "guzzlehttp/ringphp",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/RingPHP.git",
"reference": "5e2a174052995663dd68e6b5ad838afd47dd615b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/5e2a174052995663dd68e6b5ad838afd47dd615b",
"reference": "5e2a174052995663dd68e6b5ad838afd47dd615b",
"shasum": ""
},
"require": {
"guzzlehttp/streams": "~3.0",
"php": ">=5.4.0",
"react/promise": "~2.0"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "~4.0"
},
"suggest": {
"ext-curl": "Guzzle will use specific adapters if cURL is present"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Ring\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
"abandoned": true,
"time": "2018-07-31T13:22:33+00:00"
},
{
"name": "guzzlehttp/streams",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/streams.git",
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Stream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Provides a simple abstraction over streams of data",
"homepage": "http://guzzlephp.org/",
"keywords": [
"Guzzle",
"stream"
],
"abandoned": true,
"time": "2014-10-12T19:18:40+00:00"
},
{
"name": "prestashop/circuit-breaker",
"version": "v3.0.0",
"source": {
"type": "git",
"url": "https://github.com/PrestaShop/circuit-breaker.git",
"reference": "8764540d470b533c9484534343688733bc363f77"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PrestaShop/circuit-breaker/zipball/8764540d470b533c9484534343688733bc363f77",
"reference": "8764540d470b533c9484534343688733bc363f77",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^5",
"php": ">=5.6"
},
"require-dev": {
"doctrine/cache": "^1.6.0",
"friendsofphp/php-cs-fixer": "^2.12",
"phpunit/phpunit": "^5.7.0",
"squizlabs/php_codesniffer": "3.*",
"symfony/cache": "^3.4.0",
"symfony/event-dispatcher": "^3.4",
"vimeo/psalm": "^1.1"
},
"suggest": {
"doctrine/cache": "Allows use of Doctrine Cache adapters to store transactions",
"ext-apcu": "Allows use of APCu adapter (performant) to store transactions",
"guzzlehttp/cache-subscriber": "Allow use of Guzzle cache (use dev-master for most recent changes)",
"symfony/cache": "Allows use of Symfony Cache adapters to store transactions"
},
"type": "library",
"autoload": {
"psr-4": {
"PrestaShop\\CircuitBreaker\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PrestaShop SA",
"email": "contact@prestashop.com"
},
{
"name": "PrestaShop Community",
"homepage": "http://contributors.prestashop.com/"
}
],
"description": "A circuit breaker implementation for PHP",
"time": "2019-06-13T10:50:14+00:00"
},
{
"name": "react/promise",
"version": "v2.7.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
"reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8"
},
"type": "library",
"autoload": {
"psr-4": {
"React\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com"
}
],
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
"keywords": [
"promise",
"promises"
],
"time": "2019-01-07T21:25:54+00:00"
},
{
"name": "symfony/css-selector",
"version": "v3.4.37",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5",
"reference": "e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2020-01-01T11:03:25+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.6.0"
},
"platform-dev": [],
"platform-overrides": {
"php": "5.6"
}
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>productcomments</name>
<displayName><![CDATA[Product Comments]]></displayName>
<version><![CDATA[4.1.0]]></version>
<description><![CDATA[Allows users to post reviews and rate products on specific criteria.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[front_office_features]]></tab>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,2 @@
imports:
- { resource: ../common.yml }

View File

@@ -0,0 +1,17 @@
services:
_defaults:
public: true
product_comment_criterion_repository:
class: PrestaShop\Module\ProductComment\Repository\ProductCommentCriterionRepository
arguments:
- '@doctrine.dbal.default_connection'
- '%database_prefix%'
product_comment_repository:
class: PrestaShop\Module\ProductComment\Repository\ProductCommentRepository
arguments:
- '@doctrine.dbal.default_connection'
- '%database_prefix%'
- '@=service("prestashop.adapter.legacy.configuration").get("PRODUCT_COMMENTS_ALLOW_GUESTS")'
- '@=service("prestashop.adapter.legacy.configuration").get("PRODUCT_COMMENTS_MINIMAL_TIME")'

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,2 @@
imports:
- { resource: ../common.yml }

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>productcomments</name>
<displayName><![CDATA[Avis Clients]]></displayName>
<version><![CDATA[4.1.0]]></version>
<description><![CDATA[Autoriser les utilisateurs &agrave; publier des avis et &agrave; noter les produits sur des crit&egrave;res sp&eacute;cifiques.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[front_office_features]]></tab>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,58 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use PrestaShop\Module\ProductComment\Repository\ProductCommentRepository;
class ProductCommentsCommentGradeModuleFrontController extends ModuleFrontController
{
public function display()
{
$idProducts = Tools::getValue('id_products');
/** @var ProductCommentRepository $productCommentRepository */
if (!is_array($idProducts)) {
return $this->ajaxRender(null);
}
$productCommentRepository = $this->context->controller->getContainer()->get('product_comment_repository');
$productsCommentsNb = $productCommentRepository->getCommentsNumberForProducts($idProducts, Configuration::get('PRODUCT_COMMENTS_MODERATE'));
$averageGrade = $productCommentRepository->getAverageGrades($idProducts, Configuration::get('PRODUCT_COMMENTS_MODERATE'));
$resultFormated = [];
foreach ($idProducts as $i => $id) {
$resultFormated []= [
'id_product' => $id,
'comments_nb' => $productsCommentsNb[$id],
'average_grade' => $averageGrade[$id]
];
}
$this->ajaxRender(json_encode([
'products' => $resultFormated
]));
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use PrestaShop\Module\ProductComment\Repository\ProductCommentRepository;
class ProductCommentsListCommentsModuleFrontController extends ModuleFrontController
{
public function display()
{
$idProduct = Tools::getValue('id_product');
$page = Tools::getValue('page', 1);
$isLastNameAnynomus = Configuration::get('PRODUCT_COMMENTS_ANONYMISATION');
/** @var ProductCommentRepository $productCommentRepository */
$productCommentRepository = $this->context->controller->getContainer()->get('product_comment_repository');
$productComments = $productCommentRepository->paginate(
$idProduct,
$page,
Configuration::get('PRODUCT_COMMENTS_COMMENTS_PER_PAGE'),
Configuration::get('PRODUCT_COMMENTS_MODERATE')
);
$productCommentsNb = $productCommentRepository->getCommentsNumber($idProduct, Configuration::get('PRODUCT_COMMENTS_MODERATE'));
$responseArray = [
'comments_nb' => $productCommentsNb,
'comments_per_page' => Configuration::get('PRODUCT_COMMENTS_COMMENTS_PER_PAGE'),
'comments' => [],
];
foreach ($productComments as $productComment) {
$dateAdd = new \DateTime($productComment['date_add'], new \DateTimeZone('UTC'));
$dateAdd->setTimezone(new \DateTimeZone(date_default_timezone_get()));
$dateFormatter = new \IntlDateFormatter(
$this->context->language->locale,
\IntlDateFormatter::SHORT,
\IntlDateFormatter::SHORT
);
$productComment['customer_name'] = htmlentities($productComment['customer_name']);
$productComment['title'] = htmlentities($productComment['title']);
$productComment['content'] = htmlentities($productComment['content']);
$productComment['date_add'] = $dateFormatter->format($dateAdd);
if($isLastNameAnynomus) {
$productComment['lastname'] = substr($productComment['lastname'], 0, 1) . '.';
}
$usefulness = $productCommentRepository->getProductCommentUsefulness($productComment['id_product_comment']);
$productComment = array_merge($productComment, $usefulness);
if (empty($productComment['customer_name']) && !isset($productComment['firstname']) && !isset($productComment['lastname'])) {
$productComment['customer_name'] = $this->trans('Deleted account', [], 'Modules.Productcomments.Shop');
}
$responseArray['comments'][] = $productComment;
}
$this->ajaxRender(json_encode($responseArray));
}
}

View File

@@ -0,0 +1,159 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use PrestaShop\Module\ProductComment\Entity\ProductComment;
use PrestaShop\Module\ProductComment\Entity\ProductCommentCriterion;
use PrestaShop\Module\ProductComment\Entity\ProductCommentGrade;
use Doctrine\ORM\EntityManagerInterface;
use PrestaShop\Module\ProductComment\Repository\ProductCommentRepository;
class ProductCommentsPostCommentModuleFrontController extends ModuleFrontController
{
public function display()
{
if (!(int) $this->context->cookie->id_customer && !Configuration::get('PRODUCT_COMMENTS_ALLOW_GUESTS')) {
$this->ajaxRender(json_encode([
'success' => false,
'error' => $this->trans(
'You need to be [1]logged in[/1] or [2]create an account[/2] to post your review.',
[
'[1]' => '<a href="' . $this->context->link->getPageLink('my-account') . '">',
'[/1]' => '</a>',
'[2]' => '<a href="' . $this->context->link->getPageLink('authentication&create_account=1') . '">',
'[/2]' => '</a>',
],
'Modules.Productcomments.Shop'
),
]));
return false;
}
$id_product = (int) Tools::getValue('id_product');
$comment_title = Tools::getValue('comment_title');
$comment_content = Tools::getValue('comment_content');
$customer_name = Tools::getValue('customer_name');
$criterions = Tools::getValue('criterion');
/** @var ProductCommentRepository $productCommentRepository */
$productCommentRepository = $this->context->controller->getContainer()->get('product_comment_repository');
$isPostAllowed = $productCommentRepository->isPostAllowed($id_product, (int) $this->context->cookie->id_customer, (int) $this->context->cookie->id_guest);
if (!$isPostAllowed) {
$this->ajaxRender(json_encode([
'success' => false,
'error' => $this->trans('You are not allowed to post a review at the moment, please try again later.', [], 'Modules.Productcomments.Shop'),
]));
return false;
}
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
//Create product comment
$productComment = new ProductComment();
$productComment
->setProductId($id_product)
->setTitle($comment_title)
->setContent($comment_content)
->setCustomerName($customer_name)
->setCustomerId($this->context->cookie->id_customer)
->setGuestId($this->context->cookie->id_guest)
->setDateAdd(new \DateTime('now', new \DateTimeZone('UTC')))
;
$entityManager->persist($productComment);
$this->addCommentGrades($productComment, $criterions);
//Validate comment
if (!empty($errors = $this->validateComment($productComment))) {
$this->ajaxRender(json_encode([
'success' => false,
'errors' => $errors,
]));
return false;
}
$entityManager->flush();
$this->ajaxRender(json_encode([
'success' => true,
'product_comment' => $productComment->toArray(),
]));
}
/**
* @param ProductComment $productComment
* @param array $criterions
*
* @throws Exception
*/
private function addCommentGrades(ProductComment $productComment, array $criterions)
{
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
$criterionRepository = $entityManager->getRepository(ProductCommentCriterion::class);
$averageGrade = 0;
foreach ($criterions as $criterionId => $grade) {
$criterion = $criterionRepository->findOneById($criterionId);
$criterionGrade = new ProductCommentGrade(
$productComment,
$criterion,
$grade
);
$entityManager->persist($criterionGrade);
$averageGrade += $grade;
}
$averageGrade /= count($criterions);
$productComment->setGrade($averageGrade);
}
/**
* Manual validation for now, this would be nice to use Symfony validator with the annotation
*
* @param ProductComment $productComment
*
* @return array
*/
private function validateComment(ProductComment $productComment)
{
$errors = [];
if (empty($productComment->getTitle())) {
$errors[] = $this->trans('Title cannot be empty', [], 'Modules.Productcomments.Shop');
} elseif (strlen($productComment->getTitle()) > ProductComment::TITLE_MAX_LENGTH) {
$errors[] = $this->trans('Title cannot be more than %s characters', [ProductComment::TITLE_MAX_LENGTH], 'Modules.Productcomments.Shop');
}
if (!$productComment->getCustomerId()) {
if (empty($productComment->getCustomerName())) {
$errors[] = $this->trans('Customer name cannot be empty', [], 'Modules.Productcomments.Shop');
} elseif (strlen($productComment->getCustomerName()) > ProductComment::CUSTOMER_NAME_MAX_LENGTH) {
$errors[] = $this->trans('Customer name cannot be more than %s characters', [ProductComment::CUSTOMER_NAME_MAX_LENGTH], 'Modules.Productcomments.Shop');
}
}
return $errors;
}
}

View File

@@ -0,0 +1,87 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use Doctrine\ORM\EntityManagerInterface;
use PrestaShop\Module\ProductComment\Entity\ProductComment;
use PrestaShop\Module\ProductComment\Entity\ProductCommentReport;
class ProductCommentsReportCommentModuleFrontController extends ModuleFrontController
{
public function display()
{
$customerId = (int) $this->context->cookie->id_customer;
if (!$customerId) {
$this->ajaxRender(json_encode([
'success' => false,
'error' => $this->trans('You need to be logged in to report a review.', [], 'Modules.Productcomments.Shop'),
]));
return false;
}
$id_product_comment = (int) Tools::getValue('id_product_comment');
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
$productCommentEntityRepository = $entityManager->getRepository(ProductComment::class);
$productComment = $productCommentEntityRepository->findOneById($id_product_comment);
if (!$productComment) {
$this->ajaxRender(json_encode([
'success' => false,
'error' => $this->trans('Cannot find the requested product review.', [], 'Modules.Productcomments.Shop'),
]));
return false;
}
$productCommentAbuseRepository = $entityManager->getRepository(ProductCommentReport::class);
/** @var ProductCommentReport $productCommentAbuse */
$productCommentAbuse = $productCommentAbuseRepository->findOneBy([
'comment' => $id_product_comment,
'customerId' => $customerId,
]);
if ($productCommentAbuse) {
$this->ajaxRender(json_encode([
'success' => false,
'error' => $this->trans('You already reported this review as abusive.', [], 'Modules.Productcomments.Shop'),
]));
return false;
}
$productCommentAbuse = new ProductCommentReport(
$productComment,
$customerId
);
$entityManager->persist($productCommentAbuse);
$entityManager->flush();
$this->ajaxRender(json_encode([
'success' => true,
'id_product_comment' => $id_product_comment,
]));
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
use Doctrine\ORM\EntityManagerInterface;
use PrestaShop\Module\ProductComment\Entity\ProductComment;
use PrestaShop\Module\ProductComment\Entity\ProductCommentUsefulness;
use PrestaShop\Module\ProductComment\Repository\ProductCommentRepository;
class ProductCommentsUpdateCommentUsefulnessModuleFrontController extends ModuleFrontController
{
public function display()
{
if (!Configuration::get('PRODUCT_COMMENTS_USEFULNESS')) {
$this->ajaxRender(json_encode([
'success' => false,
'error' => $this->trans('This feature is not enabled.', [], 'Modules.Productcomments.Shop'),
]));
return false;
}
$customerId = (int) $this->context->cookie->id_customer;
if (!$customerId) {
$this->ajaxRender(json_encode([
'success' => false,
'error' => $this->trans(
'You need to be [1]logged in[/1] or [2]create an account[/2] to give your appreciation of a review.',
[
'[1]' => '<a href="' . $this->context->link->getPageLink('my-account') . '">',
'[/1]' => '</a>',
'[2]' => '<a href="' . $this->context->link->getPageLink('authentication&create_account=1') . '">',
'[/2]' => '</a>',
],
'Modules.Productcomments.Shop'
),
]));
return false;
}
$id_product_comment = (int) Tools::getValue('id_product_comment');
$usefulness = (int) Tools::getValue('usefulness');
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->container->get('doctrine.orm.entity_manager');
$productCommentEntityRepository = $entityManager->getRepository(ProductComment::class);
$productComment = $productCommentEntityRepository->findOneById($id_product_comment);
if (!$productComment) {
$this->ajaxRender(json_encode([
'success' => false,
'error' => $this->trans('Cannot find the requested product review.', [], 'Modules.Productcomments.Shop'),
]));
return false;
}
$productCommentUsefulnesRepository = $entityManager->getRepository(ProductCommentUsefulness::class);
/** @var ProductCommentUsefulness $productCommentUsefulness */
$productCommentUsefulness = $productCommentUsefulnesRepository->findOneBy([
'comment' => $id_product_comment,
'customerId' => $customerId,
]);
if ($productCommentUsefulness) {
$productCommentUsefulness->setUsefulness($usefulness);
} else {
$productCommentUsefulness = new ProductCommentUsefulness(
$productComment,
$customerId,
$usefulness
);
$entityManager->persist($productCommentUsefulness);
}
$entityManager->flush();
/** @var ProductCommentRepository $productCommentRepository */
$productCommentRepository = $this->context->controller->getContainer()->get('product_comment_repository');
$commentUsefulness = $productCommentRepository->getProductCommentUsefulness($id_product_comment);
$this->ajaxRender(json_encode(array_merge([
'success' => true,
'id_product_comment' => $id_product_comment,
], $commentUsefulness)));
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,75 @@
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment` (
`id_product_comment` int(10) unsigned NOT NULL auto_increment,
`id_product` int(10) unsigned NOT NULL,
`id_customer` int(10) unsigned NOT NULL,
`id_guest` int(10) unsigned NULL,
`title` varchar(64) NULL,
`content` text NOT NULL,
`customer_name` varchar(64) NULL,
`grade` float unsigned NOT NULL,
`validate` tinyint(1) NOT NULL,
`deleted` tinyint(1) NOT NULL,
`date_add` datetime NOT NULL,
PRIMARY KEY (`id_product_comment`),
KEY `id_product` (`id_product`),
KEY `id_customer` (`id_customer`),
KEY `id_guest` (`id_guest`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_criterion` (
`id_product_comment_criterion` int(10) unsigned NOT NULL auto_increment,
`id_product_comment_criterion_type` tinyint(1) NOT NULL,
`active` tinyint(1) NOT NULL,
PRIMARY KEY (`id_product_comment_criterion`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_criterion_product` (
`id_product` int(10) unsigned NOT NULL,
`id_product_comment_criterion` int(10) unsigned NOT NULL,
PRIMARY KEY(`id_product`, `id_product_comment_criterion`),
KEY `id_product_comment_criterion` (`id_product_comment_criterion`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_criterion_lang` (
`id_product_comment_criterion` INT(11) UNSIGNED NOT NULL ,
`id_lang` INT(11) UNSIGNED NOT NULL ,
`name` VARCHAR(64) NOT NULL ,
PRIMARY KEY ( `id_product_comment_criterion` , `id_lang` )
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_criterion_category` (
`id_product_comment_criterion` int(10) unsigned NOT NULL,
`id_category` int(10) unsigned NOT NULL,
PRIMARY KEY(`id_product_comment_criterion`, `id_category`),
KEY `id_category` (`id_category`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_grade` (
`id_product_comment` int(10) unsigned NOT NULL,
`id_product_comment_criterion` int(10) unsigned NOT NULL,
`grade` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_product_comment`, `id_product_comment_criterion`),
KEY `id_product_comment_criterion` (`id_product_comment_criterion`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_usefulness` (
`id_product_comment` int(10) unsigned NOT NULL,
`id_customer` int(10) unsigned NOT NULL,
`usefulness` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`id_product_comment`, `id_customer`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `PREFIX_product_comment_report` (
`id_product_comment` int(10) unsigned NOT NULL,
`id_customer` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_product_comment`, `id_customer`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
INSERT IGNORE INTO `PREFIX_product_comment_criterion` VALUES ('1', '1', '1');
INSERT IGNORE INTO `PREFIX_product_comment_criterion_lang` (`id_product_comment_criterion`, `id_lang`, `name`)
(
SELECT '1', l.`id_lang`, 'Quality'
FROM `PREFIX_lang` l
);

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,127 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
function getCommentForm()
{
if (document.forms)
return (document.forms['comment_form']);
else
return (document.comment_form);
}
function getCommentDeleteForm()
{
if (document.forms)
return (document.forms['delete_comment_form']);
else
return (document.delete_comment_form);
}
function acceptComment(id)
{
var form = getCommentForm();
if (id)
form.elements['id_product_comment'].value = id;
form.elements['action'].value = 'accept';
form.submit();
}
function deleteComment(id)
{
var form = getCommentForm();
if (id)
form.elements['id_product_comment'].value = id;
form.elements['action'].value = 'delete';
form.submit();
}
function delComment(id, confirmation)
{
var answer = confirm(confirmation);
if (answer)
{
var form = getCommentDeleteForm();
if (id)
form.elements['delete_id_product_comment'].value = id;
form.elements['delete_action'].value = 'delete';
form.submit();
}
}
function getCriterionForm()
{
if (document.forms)
return (document.forms['criterion_form']);
else
return (document.criterion_form);
}
function editCriterion(id)
{
var form = getCriterionForm();
form.elements['id_product_comment_criterion'].value = id;
form.elements['criterion_name'].value = document.getElementById('criterion_name_' + id).value;
form.elements['criterion_action'].value = 'edit';
form.submit();
}
function deleteCriterion(id)
{
var form = getCriterionForm();
form.elements['id_product_comment_criterion'].value = id;
form.elements['criterion_action'].value = 'delete';
form.submit();
}
$( document ).ready(function() {
$('select#id_product_comment_criterion_type').change(function() {
// PS 1.6
$('#categoryBox').closest('div.form-group').hide();
$('#ids_product').closest('div.form-group').hide();
// PS 1.5
$('#categories-treeview').closest('div.margin-form').hide();
$('#categories-treeview').closest('div.margin-form').prev().hide();
$('#ids_product').closest('div.margin-form').hide();
$('#ids_product').closest('div.margin-form').prev().hide();
if (this.value == 2)
{
$('#categoryBox').closest('div.form-group').show();
// PS 1.5
$('#categories-treeview').closest('div.margin-form').show();
$('#categories-treeview').closest('div.margin-form').prev().show();
}
else if (this.value == 3)
{
$('#ids_product').closest('div.form-group').show();
// PS 1.5
$('#ids_product').closest('div.margin-form').show();
$('#ids_product').closest('div.margin-form').prev().show();
}
});
$('select#id_product_comment_criterion_type').trigger( "change" );
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,30 @@
{
"name": "productcomments",
"version": "4.1.0",
"description": "Allows users to post reviews and rate products on specific criteria.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"install": "cp node_modules/simplePagination.js/jquery.simplePagination.js views/js/jquery.simplePagination.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/PrestaShop/productcomments.git"
},
"keywords": [
"product",
"comments",
"reviews",
"rate",
"grade"
],
"author": "PrestaShop",
"license": "AFL-3.0",
"bugs": {
"url": "https://github.com/PrestaShop/productcomments/issues"
},
"homepage": "https://github.com/PrestaShop/productcomments#readme",
"dependencies": {
"simplePagination.js": "https://github.com/flaviusmatis/simplePagination.js.git"
}
}

View File

@@ -0,0 +1,249 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
#product_comments_block_extra {
padding:10px 0 0 0;
border-top:1px solid #ccc;
font-weight: bold;
font-size:12px;
line-height:18px
}
#product_comments_block_extra a {
padding-left: 10px;
text-decoration: none;
background: url(img/bg_li.png) no-repeat scroll 1px 45% #fff;
}
#product_comments_block_extra a:hover {text-decoration: underline}
#product_comments_block_extra .comments-note {margin-bottom:5px}
#product_comments_block_extra .comments-note span,
#product_comments_block_extra .star-content {float:left}
#product_comments_block_extra .star-content {margin-top:2px}
#product_comments_block_extra div.star {background: url(img/star.gif) no-repeat scroll 0 0 transparent}
#product_comments_block_extra div.star_on {background: url(img/star.gif) no-repeat scroll 0 -12px transparent}
#product_comments_block_extra .comments_advices {clear:both;}
/* pop-in add grade/advice ********************************************************************* */
#fancybox-wrap { width:585px }
#fancybox-content {
width:585px;
border-width:0
}
#new_comment_form {
width:585px;
color: #333;
text-align: left;
background-color: #fff
}
#new_comment_form .title {
padding:10px;
font-size: 13px;
color: #fff;
text-transform: uppercase;
background: #333
}
#new_comment_form ul.grade_content {list-style-type:none}
#new_comment_form .grade_content li {width:50%}
#new_comment_form .product {padding:15px}
#new_comment_form .product img {
float:left;
border: 1px solid #ccc;
}
#new_comment_form .product .product_desc {
float:left;
margin-left:15px;
width:300px;
line-height:18px;
color:#666
}
#new_comment_form .product .product_desc .product_name {
padding-bottom:5px;
font-size:13px;
color:#000
}
#new_comment_form .grade_content {margin:0 0 20px 0}
#new_comment_form .grade_content span,
#new_comment_form .grade_content span {
display:inline-block;
padding:0 10px;
width:150px;/* 160 */
font-weight:bold
}
#new_comment_form .grade_content .cancel {margin-right:5px}
.new_comment_form_content {
padding:15px;
background:#f8f8f8
}
.new_comment_form_content .intro_form {
padding-bottom: 10px;
font-weight: bold;
font-size: 12px
}
#new_comment_form label {
display: block;
margin:12px 0 4px 0;
font-weight: bold;
font-size: 12px;
}
#new_comment_form input {
padding: 0 5px;
height: 28px;
width: 540px;
border: 1px solid #ccc;
background: #fff;
}
#new_comment_form textarea {
padding: 0 5px;
height: 80px;
width: 540px;
border: 1px solid #ccc;
background: #fff;
}
#new_comment_form .submit {
margin-top:20px;
padding:0;
font-size:13px;
text-align:right
}
#new_comment_form button {
cursor: pointer;
cursor: pointer;
display: inline-block;
padding: 4px 7px 3px 7px;
border: 1px solid #CC9900;
border-radius: 3px 3px 3px 3px;
font-weight: bold;
color: #000;
background: url(img/bg_bt.gif) repeat-x scroll 0 0 #F4B61B
}
#new_comment_form #criterions_list {
border-bottom: 1px solid #CCC;
padding-bottom: 15px;
list-style-type: none;
}
#new_comment_form #criterions_list li {
margin-bottom: 10px;
}
#new_comment_form #criterions_list label {
display: inline;
float: left;
margin: 0 0 0 60px;
}
#new_comment_form #criterions_list .star-content {
float: right;
margin-right: 180px;
}
#new_comment_form #new_comment_form_footer {
margin-top: 20px;
font-size: 12px;
}
/* TAB COMMENTS ******************************************************************************** */
#product_comments_block_tab {margin:0 0 20px 0}
#product_comments_block_tab div.comment {
margin:0 0 10px 0;
padding: 5px;
border-bottom: 1px dotted #ccc
}
#product_comments_block_tab div.comment div.comment_author {
float: left;
padding-right:25px;
width: 140px;/* 165 */
line-height:18px
}
#product_comments_block_tab div.comment div.comment_author span {font-weight:bold;}
#product_comments_block_tab div.comment div.comment_author span,
#product_comments_block_tab div.comment .star-content {
float:left;
}
#product_comments_block_tab div.comment .star-content {margin: 0 0 0 5px}
#product_comments_block_tab div.star,
#product_comments_block_tab div.star_on {
background: url(img/star.gif) no-repeat 0 0 transparent
}
#product_comments_block_tab div.star_on {background-position: 0 -12px}
#product_comments_block_tab .comment_author_infos {clear:both}
#product_comments_block_tab .comment_author_infos em {color:#999}
#product_comments_block_tab div.comment div.comment_details {
float: left;
overflow:hidden;
width: 360px
}
#product_comments_block_tab div.comment_details .title_block, #product_comments_block_tab div.comment_details h4 {padding-bottom:10px}
#product_comments_block_tab div.comment_details p {padding-bottom:10px}
#product_comments_block_tab div.comment_details ul {
list-style-type:none;
margin:0
}
#product_comments_block_tab div.comment_details li {
padding:2px 0 2px 12px;
background:url(img/bg_li.png) no-repeat 1px 45% #fff
}
#product_comments_block_tab a {
text-decoration: none;
font-weight: bold
}
#product_comments_block_tab a:hover {text-decoration: underline}
#product_comments_block_tab button.usefulness_btn {
cursor: pointer;
margin:0 0 0 5px;
display: inline-block;
padding: 0 2px;
border: 1px solid #CC9900;
border-radius: 3px 3px 3px 3px;
color: #000;
font-weight: bold;
background: url("img/bg_bt.gif") repeat-x scroll 0 0 #F4B61B
}
#product_comments_block_tab button.usefulness_btn:hover {background-position: left -50px}
#product_comments_block_tab button.usefulness_btn:active {background-position: left -100px}
#product_comments_block_tab span.report_btn {cursor: pointer}
#product_comments_block_tab span.report_btn:hover {text-decoration:underline}
.fl { float: left; }
.fr { float: right; }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,269 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Addons;
use Doctrine\Common\Cache\FilesystemCache;
use GuzzleHttp\Message\Request;
use GuzzleHttp\Subscriber\Cache\CacheStorage;
use GuzzleHttp\Subscriber\Cache\CacheSubscriber;
use PrestaShop\CircuitBreaker\AdvancedCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\Contract\FactoryInterface;
use PrestaShop\CircuitBreaker\FactorySettings;
use PrestaShop\CircuitBreaker\Storage\DoctrineCache;
use Symfony\Component\CssSelector\CssSelectorConverter;
use DOMDocument;
use DOMXPath;
use DOMNode;
/**
* Class CategoryFetcher helps you to fetch an Addon category data. It calls the Addons
* API for name and link, and scrap the Addons platform to get its description.
* Every call is protected by a CircuitBreaker to avoid blocking the back-office.
*/
class CategoryFetcher
{
const CACHE_DURATION = 86400; //24 hours
const ADDONS_BASE_URL = 'https://addons.prestashop.com';
const ADDONS_API_URL = 'https://api-addons.prestashop.com';
const CLOSED_ALLOWED_FAILURES = 2;
const API_TIMEOUT_SECONDS = 0.6;
/**
* The timeout is longer for Addons platform as the content is bigger (HTML content)
*/
const PLATFORM_TIMEOUT_SECONDS = 2;
const OPEN_ALLOWED_FAILURES = 1;
const OPEN_TIMEOUT_SECONDS = 1.2;
const OPEN_THRESHOLD_SECONDS = 60;
/** @var int */
private $categoryId;
/** @var array */
private $defaultData;
/** @var FactoryInterface */
private $factory;
/** @var array */
private $apiSettings;
/** @var array */
private $platformSettings;
/**
* @param int $categoryId
* @param array $defaultData
*/
public function __construct(
$categoryId,
array $defaultData
) {
$this->categoryId = $categoryId;
$this->defaultData = array_merge([
'id_category' => (int) $categoryId,
], $defaultData);
//Doctrine cache used for Guzzle and CircuitBreaker storage
$doctrineCache = new FilesystemCache(_PS_CACHE_DIR_ . '/addons_category');
//Init Guzzle cache
$cacheStorage = new CacheStorage($doctrineCache, null, self::CACHE_DURATION);
$cacheSubscriber = new CacheSubscriber($cacheStorage, function (Request $request) { return true; });
//Init circuit breaker factory
$storage = new DoctrineCache($doctrineCache);
$this->apiSettings = new FactorySettings(self::CLOSED_ALLOWED_FAILURES, self::API_TIMEOUT_SECONDS, 0);
$this->apiSettings
->setThreshold(self::OPEN_THRESHOLD_SECONDS)
->setStrippedFailures(self::OPEN_ALLOWED_FAILURES)
->setStrippedTimeout(self::OPEN_TIMEOUT_SECONDS)
->setStorage($storage)
->setClientOptions([
'subscribers' => [$cacheSubscriber],
'method' => 'POST',
])
;
$this->platformSettings = new FactorySettings(self::CLOSED_ALLOWED_FAILURES, self::PLATFORM_TIMEOUT_SECONDS, 0);
$this->platformSettings
->setThreshold(self::OPEN_THRESHOLD_SECONDS)
->setStrippedFailures(self::OPEN_ALLOWED_FAILURES)
->setStrippedTimeout(self::OPEN_TIMEOUT_SECONDS)
->setStorage($storage)
->setClientOptions([
'subscribers' => [$cacheSubscriber],
'method' => 'GET',
])
;
$this->factory = new AdvancedCircuitBreakerFactory();
}
/**
* @param string $isoCode Two letters iso code to identify the country (ex: en, fr, es, ...)
*
* @return array
*/
public function getData($isoCode)
{
$category = $this->getCategoryFromApi($isoCode);
$category = $this->addTracking($category, $isoCode);
$category['description'] = $this->getDescription($category);
return $category;
}
/**
* @param string $isoCode
*
* @return array
*/
private function getCategoryFromApi($isoCode)
{
$circuitBreaker = $this->factory->create($this->apiSettings);
$apiJsonResponse = $circuitBreaker->call(
self::ADDONS_API_URL . '?iso_lang=' . $isoCode, //Include language in url to correctly cache results
[
'body' => [
'method' => 'listing',
'action' => 'categories',
'version' => '1.7',
'iso_lang' => $isoCode,
],
]
);
$apiResponse = !empty($apiJsonResponse) ? json_decode($apiJsonResponse, true) : false;
$category = null;
if (false !== $apiResponse && !empty($apiResponse['module']) && empty($apiResponse['errors'])) {
$category = $this->searchCategory($apiResponse['module'], $this->categoryId);
}
return null !== $category ? $category : $this->defaultData;
}
/**
* @param array $categories
* @param int $searchedCategoryId
*
* @return array|null
*/
private function searchCategory(array $categories, $searchedCategoryId)
{
foreach ($categories as $category) {
if (!empty($category['id_category']) && $searchedCategoryId == $category['id_category']) {
return $category;
}
if (!empty($category['categories'])) {
$subCategory = $this->searchCategory($category['categories'], $searchedCategoryId);
if (null !== $subCategory) {
return $subCategory;
}
}
}
return null;
}
/**
* @param array $category
*
* @return string
*/
private function getDescription(array $category)
{
$defaultDescription = !empty($this->defaultData['description']) ? $this->defaultData['description'] : '';
//Clean link used to fetch description (no need for tracking then)
if (empty($category['clean_link'])) {
return $defaultDescription;
}
$circuitBreaker = $this->factory->create($this->platformSettings);
$categoryResponse = $circuitBreaker->call($category['clean_link']);
if (empty($categoryResponse)) {
return $defaultDescription;
}
$cssSelector = new CssSelectorConverter();
$document = new DOMDocument();
// if fetched HTML is not valid, DOMDocument::loadHtml() will generate E_WARNING warnings
libxml_use_internal_errors(true);
$document->loadHTML($categoryResponse);
libxml_use_internal_errors(false);
$xpath = new DOMXPath($document);
$descriptionNode = $xpath->query($cssSelector->toXPath('#category_description'))->item(0);
$categoryDescription = '';
/** @var DOMNode $childNode */
foreach ($descriptionNode->childNodes as $childNode) {
$categoryDescription .= $childNode->ownerDocument->saveHTML($childNode);
}
return !empty($categoryDescription) ? $categoryDescription : $defaultDescription;
}
/**
* Updates link property with a correctly formatted url with tracking parameters
*
* @param array $category
* @param string $isoCode
*
* @return array
*/
private function addTracking(array $category, $isoCode)
{
if (empty($category['link'])) {
return $category;
}
$parsedUrl = parse_url($category['link']);
if (false === $parsedUrl) {
return $category;
}
$parameters = [];
if (!empty($parsedUrl['query'])) {
parse_str($parsedUrl['query'], $parameters);
}
$parameters['utm_source'] = 'back-office';
$parameters['utm_medium'] = 'modules';
$parameters['utm_campaign'] = 'back-office-' . strtoupper($isoCode);
//Clean link used to fetch description (no need for tracking then)
$category['clean_link'] = self::ADDONS_BASE_URL . $parsedUrl['path'];
$category['link'] = self::ADDONS_BASE_URL . $parsedUrl['path'] . '?' . http_build_query($parameters);
return $category;
}
}

View File

@@ -0,0 +1,352 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductComment
{
const TITLE_MAX_LENGTH = 64;
const CUSTOMER_NAME_MAX_LENGTH = 64;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_product_comment", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="id_product", type="integer")
*/
private $productId;
/**
* @var int
*
* @ORM\Column(name="id_customer", type="integer")
*/
private $customerId;
/**
* @var int
*
* @ORM\Column(name="id_guest", type="integer")
*/
private $guestId;
/**
* @var string
*
* @ORM\Column(name="customer_name", type="string", length=64)
*/
private $customerName;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=64)
*/
private $title;
/**
* @var string
*
* @ORM\Column(name="content", type="text")
*/
private $content;
/**
* @var int
*
* @ORM\Column(name="grade", type="integer")
*/
private $grade;
/**
* @var bool
*
* @ORM\Column(name="validate", type="boolean")
*/
private $validate = 0;
/**
* @var bool
*
* @ORM\Column(name="deleted", type="boolean")
*/
private $deleted = 0;
/**
* @var \DateTime
*
* @ORM\Column(name="date_add", type="datetime")
*/
private $dateAdd;
public function __construct()
{
$this->criterions = new ArrayCollection();
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @return int
*/
public function getProductId()
{
return $this->productId;
}
/**
* @param int $productId
*
* @return ProductComment
*/
public function setProductId($productId)
{
$this->productId = $productId;
return $this;
}
/**
* @return int
*/
public function getCustomerId()
{
return $this->customerId;
}
/**
* @param int $customerId
*
* @return ProductComment
*/
public function setCustomerId($customerId)
{
$this->customerId = $customerId;
return $this;
}
/**
* @return int
*/
public function getGuestId()
{
return $this->guestId;
}
/**
* @param int $guestId
*
* @return ProductComment
*/
public function setGuestId($guestId)
{
$this->guestId = $guestId;
return $this;
}
/**
* @return string
*/
public function getCustomerName()
{
return $this->customerName;
}
/**
* @param string $customerName
*
* @return ProductComment
*/
public function setCustomerName($customerName)
{
$this->customerName = $customerName;
return $this;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*
* @return ProductComment
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* @param string $content
*
* @return ProductComment
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* @return int
*/
public function getGrade()
{
return $this->grade;
}
/**
* @param int $grade
*
* @return ProductComment
*/
public function setGrade($grade)
{
$this->grade = $grade;
return $this;
}
/**
* @return bool
*/
public function isValidate()
{
return $this->validate;
}
/**
* @param bool $validate
*
* @return ProductComment
*/
public function setValidate($validate)
{
$this->validate = $validate;
return $this;
}
/**
* @return bool
*/
public function isDeleted()
{
return $this->deleted;
}
/**
* @param bool $deleted
*
* @return ProductComment
*/
public function setDeleted($deleted)
{
$this->deleted = $deleted;
return $this;
}
/**
* @return \DateTime
*/
public function getDateAdd()
{
return $this->dateAdd;
}
/**
* Date is stored in UTC timezone
*
* @param \DateTime $dateAdd
*
* @return ProductComment
*/
public function setDateAdd($dateAdd)
{
$this->dateAdd = $dateAdd;
return $this;
}
/**
* @return array
*/
public function toArray()
{
return [
'id_product' => $this->getProductId(),
'id_product_comment' => $this->getId(),
'title' => $this->getTitle(),
'content' => $this->getContent(),
'customer_name' => $this->getCustomerName(),
'date_add' => $this->dateAdd->format(\DateTime::ATOM),
'grade' => $this->grade,
'usefulness' => 3,
'total_usefulness' => 5,
];
}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductCommentCriterion
{
const ENTIRE_CATALOG_TYPE = 1;
const CATEGORIES_TYPE = 2;
const PRODUCTS_TYPE = 3;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_product_comment_criterion", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="id_product_comment_criterion_type", type="integer")
*/
private $type;
/**
* @var bool
*
* @ORM\Column(name="active", type="boolean")
*/
private $active = 0;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @return int
*/
public function getType()
{
return $this->type;
}
/**
* @param int $type
*
* @return ProductCommentCriterion
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* @return bool
*/
public function isActive()
{
return $this->active;
}
/**
* @param bool $active
*
* @return ProductCommentCriterion
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductCommentGrade
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ProductComment")
* @ORM\JoinColumn(name="id_product_comment", referencedColumnName="id_product_comment")
*/
private $comment;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ProductCommentCriterion")
* @ORM\JoinColumn(name="id_product_comment_criterion", referencedColumnName="id_product_comment_criterion")
*/
private $criterion;
/**
* @var int
*
* @ORM\Column(name="grade", type="integer")
*/
private $grade;
/**
* @param ProductComment $comment
* @param ProductCommentCriterion $criterion
* @param int $grade
*/
public function __construct(
ProductComment $comment,
ProductCommentCriterion $criterion,
$grade
) {
$this->comment = $comment;
$this->criterion = $criterion;
$this->grade = $grade;
}
/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}
/**
* @return mixed
*/
public function getCriterion()
{
return $this->criterion;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductCommentReport
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ProductComment")
* @ORM\JoinColumn(name="id_product_comment", referencedColumnName="id_product_comment")
*/
private $comment;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_customer", type="integer")
*/
private $customerId;
/**
* @param ProductComment $comment
* @param int $customerId
* @param bool $usefulness
*/
public function __construct(
ProductComment $comment,
$customerId
) {
$this->comment = $comment;
$this->customerId = $customerId;
}
/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}
/**
* @return int
*/
public function getCustomerId()
{
return $this->customerId;
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity()
*/
class ProductCommentUsefulness
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ProductComment")
* @ORM\JoinColumn(name="id_product_comment", referencedColumnName="id_product_comment")
*/
private $comment;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_customer", type="integer")
*/
private $customerId;
/**
* @var bool
*
* @ORM\Column(name="usefulness", type="boolean")
*/
private $usefulness;
/**
* @param ProductComment $comment
* @param int $customerId
* @param bool $usefulness
*/
public function __construct(
ProductComment $comment,
$customerId,
$usefulness
) {
$this->comment = $comment;
$this->customerId = $customerId;
$this->usefulness = $usefulness;
}
/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}
/**
* @return int
*/
public function getCustomerId()
{
return $this->customerId;
}
/**
* @return bool
*/
public function isUsefulness()
{
return $this->usefulness;
}
/**
* @param bool $usefulness
*
* @return ProductCommentUsefulness
*/
public function setUsefulness($usefulness)
{
$this->usefulness = $usefulness;
return $this;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,91 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Repository;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
use PrestaShop\Module\ProductComment\Entity\ProductCommentCriterion;
class ProductCommentCriterionRepository
{
/**
* @var Connection the Database connection
*/
private $connection;
/**
* @var string the Database prefix
*/
private $databasePrefix;
/**
* @param Connection $connection
* @param string $databasePrefix
*/
public function __construct(Connection $connection, $databasePrefix)
{
$this->connection = $connection;
$this->databasePrefix = $databasePrefix;
}
/**
* @param int $idProduct
* @param int $idLang
*
* @return array
*
* @throws \PrestaShopException
*/
public function getByProduct($idProduct, $idLang)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('pcc.id_product_comment_criterion, pccl.name')
->from($this->databasePrefix . 'product_comment_criterion', 'pcc')
->leftJoin('pcc', $this->databasePrefix . 'product_comment_criterion_lang', 'pccl', 'pcc.id_product_comment_criterion = pccl.id_product_comment_criterion')
->leftJoin('pcc', $this->databasePrefix . 'product_comment_criterion_product', 'pccp', 'pcc.id_product_comment_criterion = pccp.id_product_comment_criterion')
->leftJoin('pcc', $this->databasePrefix . 'product_comment_criterion_category', 'pccc', 'pcc.id_product_comment_criterion = pccc.id_product_comment_criterion')
->leftJoin('pccc', $this->databasePrefix . 'category', 'c', 'pccc.id_category = c.id_category')
->leftJoin('c', $this->databasePrefix . 'category_product', 'cp', 'c.id_category = cp.id_category')
->andWhere($qb->expr()->orX(
$qb->expr()->eq('pcc.id_product_comment_criterion_type', ':catalog_type'),
$qb->expr()->eq('pccp.id_product', ':id_product'),
$qb->expr()->eq('cp.id_product', ':id_product')
))
->andWhere('pccl.id_lang = :id_lang')
->andWhere('pcc.active = :active')
->setParameter('catalog_type', ProductCommentCriterion::ENTIRE_CATALOG_TYPE)
->setParameter('active', 1)
->setParameter('id_product', $idProduct)
->setParameter('id_lang', $idLang)
->addGroupBy('pcc.id_product_comment_criterion')
;
return $qb->execute()->fetchAll();
}
}

View File

@@ -0,0 +1,415 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\ProductComment\Repository;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
class ProductCommentRepository
{
/**
* @var Connection the Database connection
*/
private $connection;
/**
* @var string the Database prefix
*/
private $databasePrefix;
/**
* @var bool
*/
private $guestCommentsAllowed;
/**
* @var int
*/
private $commentsMinimalTime;
/**
* @param Connection $connection
* @param string $databasePrefix
* @param bool $guestCommentsAllowed
* @param int $commentsMinimalTime
*/
public function __construct(
Connection $connection,
$databasePrefix,
$guestCommentsAllowed,
$commentsMinimalTime
) {
$this->connection = $connection;
$this->databasePrefix = $databasePrefix;
$this->guestCommentsAllowed = (bool) $guestCommentsAllowed;
$this->commentsMinimalTime = (int) $commentsMinimalTime;
}
/**
* @param int $productId
* @param int $page
* @param int $commentsPerPage
* @param bool $validatedOnly
*
* @return array
*/
public function paginate($productId, $page, $commentsPerPage, $validatedOnly)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->addSelect('pc.id_product, pc.id_product_comment, pc.title, pc.content, pc.customer_name, pc.date_add, pc.grade')
->addSelect('c.firstname, c.lastname')
->from($this->databasePrefix . 'product_comment', 'pc')
->leftJoin('pc', $this->databasePrefix . 'customer', 'c', 'pc.id_customer = c.id_customer AND c.deleted = :not_deleted')
->andWhere('pc.id_product = :id_product')
->andWhere('pc.deleted = :not_deleted')
->setParameter('not_deleted', 0)
->setParameter('id_product', $productId)
->setMaxResults($commentsPerPage)
->setFirstResult(($page - 1) * $commentsPerPage)
->addGroupBy('pc.id_product_comment')
->addOrderBy('pc.date_add', 'DESC')
;
if ($validatedOnly) {
$qb
->andWhere('pc.validate = :validate')
->setParameter('validate', 1)
;
}
return $qb->execute()->fetchAll();
}
/**
* @param int $productCommentId
*
* @return array
*/
public function getProductCommentUsefulness($productCommentId)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->addSelect('pcu.usefulness')
->from($this->databasePrefix . 'product_comment_usefulness', 'pcu')
->andWhere('pcu.id_product_comment = :id_product_comment')
->setParameter('id_product_comment', $productCommentId)
;
$usefulnessInfos = [
'usefulness' => 0,
'total_usefulness' => 0,
];
$customerAppreciations = $qb->execute()->fetchAll();
foreach ($customerAppreciations as $customerAppreciation) {
if ((int) $customerAppreciation['usefulness']) {
++$usefulnessInfos['usefulness'];
}
++$usefulnessInfos['total_usefulness'];
}
return $usefulnessInfos;
}
/**
* @param int $productId
* @param bool $validatedOnly
*
* @return float
*/
public function getAverageGrade($productId, $validatedOnly)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('SUM(pc.grade) / COUNT(pc.grade) AS averageGrade')
->from($this->databasePrefix . 'product_comment', 'pc')
->andWhere('pc.id_product = :id_product')
->andWhere('pc.deleted = :deleted')
->setParameter('deleted', 0)
->setParameter('id_product', $productId)
;
if ($validatedOnly) {
$qb
->andWhere('pc.validate = :validate')
->setParameter('validate', 1)
;
}
return (float) $qb->execute()->fetchColumn();
}
/**
* @param array $productIds
* @param bool $validatedOnly
*
* @return array
*/
public function getAverageGrades(array $productIds, $validatedOnly)
{
$sql = 'SELECT';
$count = count($productIds);
foreach ($productIds as $index => $id) {
$esqID = pSQL($id);
$sql .= ' SUM(IF(id_product = ' . $esqID . ' AND deleted = 0';
if ($validatedOnly) {
$sql .= ' AND validate = 1';
}
$sql .= ',grade, 0))';
$sql .= ' / SUM(IF(id_product = ' . $esqID . ' AND deleted = 0';
if ($validatedOnly) {
$sql .= ' AND validate = 1';
}
$sql .= ',1, 0)) AS "' . $esqID . '"';
if ($count - 1 > $index) {
$sql .= ',';
}
}
$sql .= ' FROM ' . $this->databasePrefix . 'product_comment';
$query = $this->connection->prepare($sql);
$query->execute();
return (array) $query->fetch();
}
/**
* @param int $productId
* @param bool $validatedOnly
*
* @return int
*/
public function getCommentsNumber($productId, $validatedOnly)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('COUNT(pc.id_product_comment) AS commentNb')
->from($this->databasePrefix . 'product_comment', 'pc')
->andWhere('pc.id_product = :id_product')
->andWhere('pc.deleted = :deleted')
->setParameter('deleted', 0)
->setParameter('id_product', $productId)
;
if ($validatedOnly) {
$qb
->andWhere('pc.validate = :validate')
->setParameter('validate', 1)
;
}
return (int) $qb->execute()->fetchColumn();
}
/**
* @param array $productIds
* @param bool $validatedOnly
*
* @return array
*/
public function getCommentsNumberForProducts(array $productIds, $validatedOnly)
{
$sql = 'SELECT';
$count = count($productIds);
foreach ($productIds as $index => $id) {
$esqID = pSQL($id);
$sql .= ' SUM(IF(id_product = ' . $esqID . ' AND deleted = 0';
if ($validatedOnly) {
$sql .= ' AND validate = 1';
}
$sql .= ' ,1, 0)) AS "' . $esqID . '"';
if ($count - 1 > $index) {
$sql .= ',';
}
}
$sql .= ' FROM ' . $this->databasePrefix . 'product_comment';
// return $sql;
$query = $this->connection->prepare($sql);
$query->execute();
return (array) $query->fetch();
}
/**
* @param int $productId
* @param int $idCustomer
* @param int $idGuest
*
* @return bool
*/
public function isPostAllowed($productId, $idCustomer, $idGuest)
{
if (!$idCustomer && !$this->guestCommentsAllowed) {
$postAllowed = false;
} else {
$lastCustomerComment = null;
if ($idCustomer) {
$lastCustomerComment = $this->getLastCustomerComment($productId, $idCustomer);
} elseif ($idGuest) {
$lastCustomerComment = $this->getLastGuestComment($productId, $idGuest);
}
$postAllowed = true;
if (null !== $lastCustomerComment && isset($lastCustomerComment['date_add'])) {
$postDate = new \DateTime($lastCustomerComment['date_add'], new \DateTimeZone('UTC'));
if (time() - $postDate->getTimestamp() < $this->commentsMinimalTime) {
$postAllowed = false;
}
}
}
return $postAllowed;
}
/**
* @param int $productId
* @param int $idCustomer
*
* @return array
*/
public function getLastCustomerComment($productId, $idCustomer)
{
return $this->getLastComment(['id_product' => $productId, 'id_customer' => $idCustomer]);
}
/**
* @param int $productId
* @param int $idGuest
*
* @return array
*/
public function getLastGuestComment($productId, $idGuest)
{
return $this->getLastComment(['id_product' => $productId, 'id_guest' => $idGuest]);
}
/**
* @param int $customerId
*/
public function cleanCustomerData($customerId)
{
//We anonymize the customer comment by unlinking them (the name won't be visible any more but the grade and comment are still visible)
$qb = $this->connection->createQueryBuilder();
$qb
->update($this->databasePrefix . 'product_comment', 'pc')
->set('id_customer', 0)
->andWhere('pc.id_customer = :id_customer')
->setParameter('id_customer', $customerId)
;
$qb->execute();
//But we remove every report and votes for comments
$qb = $this->connection->createQueryBuilder();
$qb
->delete($this->databasePrefix . 'product_comment_report')
->andWhere('id_customer = :id_customer')
->setParameter('id_customer', $customerId)
;
$qb->execute();
$qb = $this->connection->createQueryBuilder();
$qb
->delete($this->databasePrefix . 'product_comment_usefulness')
->andWhere('id_customer = :id_customer')
->setParameter('id_customer', $customerId)
;
$qb->execute();
}
/**
* @param int $customerId
* @param int $langId
*
* @return array
*/
public function getCustomerData($customerId, $langId)
{
$qb = $this->connection->createQueryBuilder();
$qb
->select('pl.name, pc.id_product, pc.id_product_comment, pc.title, pc.content, pc.grade, pc.validate, pc.deleted, pcu.usefulness, pc.date_add')
->from($this->databasePrefix . 'product_comment', 'pc')
->leftJoin('pc', $this->databasePrefix . 'product_comment_usefulness', 'pcu', 'pc.id_product_comment = pcu.id_product_comment')
->leftJoin('pc', $this->databasePrefix . 'product', 'p', 'pc.id_product = p.id_product')
->leftJoin('p', $this->databasePrefix . 'product_lang', 'pl', 'p.id_product = pl.id_product')
->leftJoin('pl', $this->databasePrefix . 'lang', 'l', 'pl.id_lang = l.id_lang')
->andWhere('pc.id_customer = :id_customer')
->andWhere('l.id_lang = :id_lang')
->setParameter('id_customer', $customerId)
->setParameter('id_lang', $langId)
->addGroupBy('pc.id_product_comment')
->addOrderBy('pc.date_add', 'ASC')
;
return $qb->execute()->fetchAll();
}
/**
* @param array $criteria
*
* @return array
*/
private function getLastComment(array $criteria)
{
/** @var QueryBuilder $qb */
$qb = $this->connection->createQueryBuilder();
$qb
->select('pc.*')
->from($this->databasePrefix . 'product_comment', 'pc')
->andWhere('pc.deleted = :deleted')
->setParameter('deleted', 0)
->addOrderBy('pc.date_add', 'DESC')
->setMaxResults(1)
;
foreach ($criteria as $field => $value) {
$qb
->andWhere(sprintf('pc.%s = :%s', $field, $field))
->setParameter($field, $value)
;
}
$comments = $qb->execute()->fetchAll();
return empty($comments) ? [] : $comments[0];
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_2_4($object)
{
return $object->registerHook('displayProductListReviews') && $object->registerHook('top');
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_2_9_7($object)
{
return $object->unregisterHook('top');
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_5_0_0($object)
{
if (!Configuration::hasKey('PRODUCT_COMMENTS_PAGE_COMMENTS_NB')) {
Configuration::set('PRODUCT_COMMENTS_PAGE_COMMENTS_NB', 8);
}
if (!Configuration::hasKey('PRODUCT_COMMENTS_USEFULNESS')) {
Configuration::set('PRODUCT_COMMENTS_USEFULNESS', 1);
}
}

View File

@@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitcf0e80547367544c26e9561d5957499d::getLoader();

View File

@@ -0,0 +1,445 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

View File

@@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,260 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Doctrine\\Common\\Cache\\ApcCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php',
'Doctrine\\Common\\Cache\\ApcuCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php',
'Doctrine\\Common\\Cache\\ArrayCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php',
'Doctrine\\Common\\Cache\\Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php',
'Doctrine\\Common\\Cache\\CacheProvider' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php',
'Doctrine\\Common\\Cache\\ChainCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php',
'Doctrine\\Common\\Cache\\ClearableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php',
'Doctrine\\Common\\Cache\\CouchbaseCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php',
'Doctrine\\Common\\Cache\\FileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php',
'Doctrine\\Common\\Cache\\FilesystemCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php',
'Doctrine\\Common\\Cache\\FlushableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php',
'Doctrine\\Common\\Cache\\MemcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php',
'Doctrine\\Common\\Cache\\MemcachedCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php',
'Doctrine\\Common\\Cache\\MongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php',
'Doctrine\\Common\\Cache\\MultiGetCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php',
'Doctrine\\Common\\Cache\\MultiPutCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php',
'Doctrine\\Common\\Cache\\PhpFileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php',
'Doctrine\\Common\\Cache\\PredisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php',
'Doctrine\\Common\\Cache\\RedisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php',
'Doctrine\\Common\\Cache\\RiakCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php',
'Doctrine\\Common\\Cache\\SQLite3Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php',
'Doctrine\\Common\\Cache\\Version' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php',
'Doctrine\\Common\\Cache\\VoidCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php',
'Doctrine\\Common\\Cache\\WinCacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php',
'Doctrine\\Common\\Cache\\XcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php',
'Doctrine\\Common\\Cache\\ZendDataCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php',
'GuzzleHttp\\BatchResults' => $vendorDir . '/guzzlehttp/guzzle/src/BatchResults.php',
'GuzzleHttp\\Client' => $vendorDir . '/guzzlehttp/guzzle/src/Client.php',
'GuzzleHttp\\ClientInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ClientInterface.php',
'GuzzleHttp\\Collection' => $vendorDir . '/guzzlehttp/guzzle/src/Collection.php',
'GuzzleHttp\\Cookie\\CookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php',
'GuzzleHttp\\Cookie\\CookieJarInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php',
'GuzzleHttp\\Cookie\\FileCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php',
'GuzzleHttp\\Cookie\\SessionCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php',
'GuzzleHttp\\Cookie\\SetCookie' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/SetCookie.php',
'GuzzleHttp\\Event\\AbstractEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/AbstractEvent.php',
'GuzzleHttp\\Event\\AbstractRequestEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/AbstractRequestEvent.php',
'GuzzleHttp\\Event\\AbstractRetryableEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/AbstractRetryableEvent.php',
'GuzzleHttp\\Event\\AbstractTransferEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/AbstractTransferEvent.php',
'GuzzleHttp\\Event\\BeforeEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/BeforeEvent.php',
'GuzzleHttp\\Event\\CompleteEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/CompleteEvent.php',
'GuzzleHttp\\Event\\Emitter' => $vendorDir . '/guzzlehttp/guzzle/src/Event/Emitter.php',
'GuzzleHttp\\Event\\EmitterInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Event/EmitterInterface.php',
'GuzzleHttp\\Event\\EndEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/EndEvent.php',
'GuzzleHttp\\Event\\ErrorEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/ErrorEvent.php',
'GuzzleHttp\\Event\\EventInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Event/EventInterface.php',
'GuzzleHttp\\Event\\HasEmitterInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Event/HasEmitterInterface.php',
'GuzzleHttp\\Event\\HasEmitterTrait' => $vendorDir . '/guzzlehttp/guzzle/src/Event/HasEmitterTrait.php',
'GuzzleHttp\\Event\\ListenerAttacherTrait' => $vendorDir . '/guzzlehttp/guzzle/src/Event/ListenerAttacherTrait.php',
'GuzzleHttp\\Event\\ProgressEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/ProgressEvent.php',
'GuzzleHttp\\Event\\RequestEvents' => $vendorDir . '/guzzlehttp/guzzle/src/Event/RequestEvents.php',
'GuzzleHttp\\Event\\SubscriberInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Event/SubscriberInterface.php',
'GuzzleHttp\\Exception\\BadResponseException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/BadResponseException.php',
'GuzzleHttp\\Exception\\ClientException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ClientException.php',
'GuzzleHttp\\Exception\\ConnectException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ConnectException.php',
'GuzzleHttp\\Exception\\CouldNotRewindStreamException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/CouldNotRewindStreamException.php',
'GuzzleHttp\\Exception\\ParseException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ParseException.php',
'GuzzleHttp\\Exception\\RequestException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/RequestException.php',
'GuzzleHttp\\Exception\\ServerException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ServerException.php',
'GuzzleHttp\\Exception\\StateException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/StateException.php',
'GuzzleHttp\\Exception\\TooManyRedirectsException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php',
'GuzzleHttp\\Exception\\TransferException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TransferException.php',
'GuzzleHttp\\Exception\\XmlParseException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/XmlParseException.php',
'GuzzleHttp\\HasDataTrait' => $vendorDir . '/guzzlehttp/guzzle/src/HasDataTrait.php',
'GuzzleHttp\\Message\\AbstractMessage' => $vendorDir . '/guzzlehttp/guzzle/src/Message/AbstractMessage.php',
'GuzzleHttp\\Message\\AppliesHeadersInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/AppliesHeadersInterface.php',
'GuzzleHttp\\Message\\FutureResponse' => $vendorDir . '/guzzlehttp/guzzle/src/Message/FutureResponse.php',
'GuzzleHttp\\Message\\MessageFactory' => $vendorDir . '/guzzlehttp/guzzle/src/Message/MessageFactory.php',
'GuzzleHttp\\Message\\MessageFactoryInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/MessageFactoryInterface.php',
'GuzzleHttp\\Message\\MessageInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/MessageInterface.php',
'GuzzleHttp\\Message\\MessageParser' => $vendorDir . '/guzzlehttp/guzzle/src/Message/MessageParser.php',
'GuzzleHttp\\Message\\Request' => $vendorDir . '/guzzlehttp/guzzle/src/Message/Request.php',
'GuzzleHttp\\Message\\RequestInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/RequestInterface.php',
'GuzzleHttp\\Message\\Response' => $vendorDir . '/guzzlehttp/guzzle/src/Message/Response.php',
'GuzzleHttp\\Message\\ResponseInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/ResponseInterface.php',
'GuzzleHttp\\Mimetypes' => $vendorDir . '/guzzlehttp/guzzle/src/Mimetypes.php',
'GuzzleHttp\\Pool' => $vendorDir . '/guzzlehttp/guzzle/src/Pool.php',
'GuzzleHttp\\Post\\MultipartBody' => $vendorDir . '/guzzlehttp/guzzle/src/Post/MultipartBody.php',
'GuzzleHttp\\Post\\PostBody' => $vendorDir . '/guzzlehttp/guzzle/src/Post/PostBody.php',
'GuzzleHttp\\Post\\PostBodyInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Post/PostBodyInterface.php',
'GuzzleHttp\\Post\\PostFile' => $vendorDir . '/guzzlehttp/guzzle/src/Post/PostFile.php',
'GuzzleHttp\\Post\\PostFileInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Post/PostFileInterface.php',
'GuzzleHttp\\Query' => $vendorDir . '/guzzlehttp/guzzle/src/Query.php',
'GuzzleHttp\\QueryParser' => $vendorDir . '/guzzlehttp/guzzle/src/QueryParser.php',
'GuzzleHttp\\RequestFsm' => $vendorDir . '/guzzlehttp/guzzle/src/RequestFsm.php',
'GuzzleHttp\\RingBridge' => $vendorDir . '/guzzlehttp/guzzle/src/RingBridge.php',
'GuzzleHttp\\Ring\\Client\\ClientUtils' => $vendorDir . '/guzzlehttp/ringphp/src/Client/ClientUtils.php',
'GuzzleHttp\\Ring\\Client\\CurlFactory' => $vendorDir . '/guzzlehttp/ringphp/src/Client/CurlFactory.php',
'GuzzleHttp\\Ring\\Client\\CurlHandler' => $vendorDir . '/guzzlehttp/ringphp/src/Client/CurlHandler.php',
'GuzzleHttp\\Ring\\Client\\CurlMultiHandler' => $vendorDir . '/guzzlehttp/ringphp/src/Client/CurlMultiHandler.php',
'GuzzleHttp\\Ring\\Client\\Middleware' => $vendorDir . '/guzzlehttp/ringphp/src/Client/Middleware.php',
'GuzzleHttp\\Ring\\Client\\MockHandler' => $vendorDir . '/guzzlehttp/ringphp/src/Client/MockHandler.php',
'GuzzleHttp\\Ring\\Client\\StreamHandler' => $vendorDir . '/guzzlehttp/ringphp/src/Client/StreamHandler.php',
'GuzzleHttp\\Ring\\Core' => $vendorDir . '/guzzlehttp/ringphp/src/Core.php',
'GuzzleHttp\\Ring\\Exception\\CancelledException' => $vendorDir . '/guzzlehttp/ringphp/src/Exception/CancelledException.php',
'GuzzleHttp\\Ring\\Exception\\CancelledFutureAccessException' => $vendorDir . '/guzzlehttp/ringphp/src/Exception/CancelledFutureAccessException.php',
'GuzzleHttp\\Ring\\Exception\\ConnectException' => $vendorDir . '/guzzlehttp/ringphp/src/Exception/ConnectException.php',
'GuzzleHttp\\Ring\\Exception\\RingException' => $vendorDir . '/guzzlehttp/ringphp/src/Exception/RingException.php',
'GuzzleHttp\\Ring\\Future\\BaseFutureTrait' => $vendorDir . '/guzzlehttp/ringphp/src/Future/BaseFutureTrait.php',
'GuzzleHttp\\Ring\\Future\\CompletedFutureArray' => $vendorDir . '/guzzlehttp/ringphp/src/Future/CompletedFutureArray.php',
'GuzzleHttp\\Ring\\Future\\CompletedFutureValue' => $vendorDir . '/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php',
'GuzzleHttp\\Ring\\Future\\FutureArray' => $vendorDir . '/guzzlehttp/ringphp/src/Future/FutureArray.php',
'GuzzleHttp\\Ring\\Future\\FutureArrayInterface' => $vendorDir . '/guzzlehttp/ringphp/src/Future/FutureArrayInterface.php',
'GuzzleHttp\\Ring\\Future\\FutureInterface' => $vendorDir . '/guzzlehttp/ringphp/src/Future/FutureInterface.php',
'GuzzleHttp\\Ring\\Future\\FutureValue' => $vendorDir . '/guzzlehttp/ringphp/src/Future/FutureValue.php',
'GuzzleHttp\\Ring\\Future\\MagicFutureTrait' => $vendorDir . '/guzzlehttp/ringphp/src/Future/MagicFutureTrait.php',
'GuzzleHttp\\Stream\\AppendStream' => $vendorDir . '/guzzlehttp/streams/src/AppendStream.php',
'GuzzleHttp\\Stream\\AsyncReadStream' => $vendorDir . '/guzzlehttp/streams/src/AsyncReadStream.php',
'GuzzleHttp\\Stream\\BufferStream' => $vendorDir . '/guzzlehttp/streams/src/BufferStream.php',
'GuzzleHttp\\Stream\\CachingStream' => $vendorDir . '/guzzlehttp/streams/src/CachingStream.php',
'GuzzleHttp\\Stream\\DroppingStream' => $vendorDir . '/guzzlehttp/streams/src/DroppingStream.php',
'GuzzleHttp\\Stream\\Exception\\CannotAttachException' => $vendorDir . '/guzzlehttp/streams/src/Exception/CannotAttachException.php',
'GuzzleHttp\\Stream\\Exception\\SeekException' => $vendorDir . '/guzzlehttp/streams/src/Exception/SeekException.php',
'GuzzleHttp\\Stream\\FnStream' => $vendorDir . '/guzzlehttp/streams/src/FnStream.php',
'GuzzleHttp\\Stream\\GuzzleStreamWrapper' => $vendorDir . '/guzzlehttp/streams/src/GuzzleStreamWrapper.php',
'GuzzleHttp\\Stream\\InflateStream' => $vendorDir . '/guzzlehttp/streams/src/InflateStream.php',
'GuzzleHttp\\Stream\\LazyOpenStream' => $vendorDir . '/guzzlehttp/streams/src/LazyOpenStream.php',
'GuzzleHttp\\Stream\\LimitStream' => $vendorDir . '/guzzlehttp/streams/src/LimitStream.php',
'GuzzleHttp\\Stream\\MetadataStreamInterface' => $vendorDir . '/guzzlehttp/streams/src/MetadataStreamInterface.php',
'GuzzleHttp\\Stream\\NoSeekStream' => $vendorDir . '/guzzlehttp/streams/src/NoSeekStream.php',
'GuzzleHttp\\Stream\\NullStream' => $vendorDir . '/guzzlehttp/streams/src/NullStream.php',
'GuzzleHttp\\Stream\\PumpStream' => $vendorDir . '/guzzlehttp/streams/src/PumpStream.php',
'GuzzleHttp\\Stream\\Stream' => $vendorDir . '/guzzlehttp/streams/src/Stream.php',
'GuzzleHttp\\Stream\\StreamDecoratorTrait' => $vendorDir . '/guzzlehttp/streams/src/StreamDecoratorTrait.php',
'GuzzleHttp\\Stream\\StreamInterface' => $vendorDir . '/guzzlehttp/streams/src/StreamInterface.php',
'GuzzleHttp\\Stream\\Utils' => $vendorDir . '/guzzlehttp/streams/src/Utils.php',
'GuzzleHttp\\Subscriber\\Cache\\CacheStorage' => $vendorDir . '/guzzlehttp/cache-subscriber/src/CacheStorage.php',
'GuzzleHttp\\Subscriber\\Cache\\CacheStorageInterface' => $vendorDir . '/guzzlehttp/cache-subscriber/src/CacheStorageInterface.php',
'GuzzleHttp\\Subscriber\\Cache\\CacheSubscriber' => $vendorDir . '/guzzlehttp/cache-subscriber/src/CacheSubscriber.php',
'GuzzleHttp\\Subscriber\\Cache\\PurgeSubscriber' => $vendorDir . '/guzzlehttp/cache-subscriber/src/PurgeSubscriber.php',
'GuzzleHttp\\Subscriber\\Cache\\Utils' => $vendorDir . '/guzzlehttp/cache-subscriber/src/Utils.php',
'GuzzleHttp\\Subscriber\\Cache\\ValidationSubscriber' => $vendorDir . '/guzzlehttp/cache-subscriber/src/ValidationSubscriber.php',
'GuzzleHttp\\Subscriber\\Cookie' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/Cookie.php',
'GuzzleHttp\\Subscriber\\History' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/History.php',
'GuzzleHttp\\Subscriber\\HttpError' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/HttpError.php',
'GuzzleHttp\\Subscriber\\Mock' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/Mock.php',
'GuzzleHttp\\Subscriber\\Prepare' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/Prepare.php',
'GuzzleHttp\\Subscriber\\Redirect' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/Redirect.php',
'GuzzleHttp\\ToArrayInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ToArrayInterface.php',
'GuzzleHttp\\Transaction' => $vendorDir . '/guzzlehttp/guzzle/src/Transaction.php',
'GuzzleHttp\\UriTemplate' => $vendorDir . '/guzzlehttp/guzzle/src/UriTemplate.php',
'GuzzleHttp\\Url' => $vendorDir . '/guzzlehttp/guzzle/src/Url.php',
'GuzzleHttp\\Utils' => $vendorDir . '/guzzlehttp/guzzle/src/Utils.php',
'PrestaShop\\CircuitBreaker\\AdvancedCircuitBreaker' => $vendorDir . '/prestashop/circuit-breaker/src/AdvancedCircuitBreaker.php',
'PrestaShop\\CircuitBreaker\\AdvancedCircuitBreakerFactory' => $vendorDir . '/prestashop/circuit-breaker/src/AdvancedCircuitBreakerFactory.php',
'PrestaShop\\CircuitBreaker\\Client\\GuzzleClient' => $vendorDir . '/prestashop/circuit-breaker/src/Client/GuzzleClient.php',
'PrestaShop\\CircuitBreaker\\Contract\\CircuitBreakerInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/CircuitBreakerInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\ClientInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/ClientInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\FactoryInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/FactoryInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\FactorySettingsInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/FactorySettingsInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\PlaceInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/PlaceInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\StorageInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/StorageInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\SystemInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/SystemInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\TransactionInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/TransactionInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\TransitionDispatcherInterface' => $vendorDir . '/prestashop/circuit-breaker/src/Contract/TransitionDispatcherInterface.php',
'PrestaShop\\CircuitBreaker\\Event\\TransitionEvent' => $vendorDir . '/prestashop/circuit-breaker/src/Event/TransitionEvent.php',
'PrestaShop\\CircuitBreaker\\Exception\\CircuitBreakerException' => $vendorDir . '/prestashop/circuit-breaker/src/Exception/CircuitBreakerException.php',
'PrestaShop\\CircuitBreaker\\Exception\\InvalidPlaceException' => $vendorDir . '/prestashop/circuit-breaker/src/Exception/InvalidPlaceException.php',
'PrestaShop\\CircuitBreaker\\Exception\\InvalidTransactionException' => $vendorDir . '/prestashop/circuit-breaker/src/Exception/InvalidTransactionException.php',
'PrestaShop\\CircuitBreaker\\Exception\\TransactionNotFoundException' => $vendorDir . '/prestashop/circuit-breaker/src/Exception/TransactionNotFoundException.php',
'PrestaShop\\CircuitBreaker\\Exception\\UnavailableServiceException' => $vendorDir . '/prestashop/circuit-breaker/src/Exception/UnavailableServiceException.php',
'PrestaShop\\CircuitBreaker\\Exception\\UnsupportedMethodException' => $vendorDir . '/prestashop/circuit-breaker/src/Exception/UnsupportedMethodException.php',
'PrestaShop\\CircuitBreaker\\FactorySettings' => $vendorDir . '/prestashop/circuit-breaker/src/FactorySettings.php',
'PrestaShop\\CircuitBreaker\\PartialCircuitBreaker' => $vendorDir . '/prestashop/circuit-breaker/src/PartialCircuitBreaker.php',
'PrestaShop\\CircuitBreaker\\Place\\AbstractPlace' => $vendorDir . '/prestashop/circuit-breaker/src/Place/AbstractPlace.php',
'PrestaShop\\CircuitBreaker\\Place\\ClosedPlace' => $vendorDir . '/prestashop/circuit-breaker/src/Place/ClosedPlace.php',
'PrestaShop\\CircuitBreaker\\Place\\HalfOpenPlace' => $vendorDir . '/prestashop/circuit-breaker/src/Place/HalfOpenPlace.php',
'PrestaShop\\CircuitBreaker\\Place\\OpenPlace' => $vendorDir . '/prestashop/circuit-breaker/src/Place/OpenPlace.php',
'PrestaShop\\CircuitBreaker\\SimpleCircuitBreaker' => $vendorDir . '/prestashop/circuit-breaker/src/SimpleCircuitBreaker.php',
'PrestaShop\\CircuitBreaker\\SimpleCircuitBreakerFactory' => $vendorDir . '/prestashop/circuit-breaker/src/SimpleCircuitBreakerFactory.php',
'PrestaShop\\CircuitBreaker\\State' => $vendorDir . '/prestashop/circuit-breaker/src/State.php',
'PrestaShop\\CircuitBreaker\\Storage\\DoctrineCache' => $vendorDir . '/prestashop/circuit-breaker/src/Storage/DoctrineCache.php',
'PrestaShop\\CircuitBreaker\\Storage\\SimpleArray' => $vendorDir . '/prestashop/circuit-breaker/src/Storage/SimpleArray.php',
'PrestaShop\\CircuitBreaker\\Storage\\SymfonyCache' => $vendorDir . '/prestashop/circuit-breaker/src/Storage/SymfonyCache.php',
'PrestaShop\\CircuitBreaker\\SymfonyCircuitBreaker' => $vendorDir . '/prestashop/circuit-breaker/src/SymfonyCircuitBreaker.php',
'PrestaShop\\CircuitBreaker\\System\\MainSystem' => $vendorDir . '/prestashop/circuit-breaker/src/System/MainSystem.php',
'PrestaShop\\CircuitBreaker\\Transaction\\SimpleTransaction' => $vendorDir . '/prestashop/circuit-breaker/src/Transaction/SimpleTransaction.php',
'PrestaShop\\CircuitBreaker\\Transition' => $vendorDir . '/prestashop/circuit-breaker/src/Transition.php',
'PrestaShop\\CircuitBreaker\\Transition\\EventDispatcher' => $vendorDir . '/prestashop/circuit-breaker/src/Transition/EventDispatcher.php',
'PrestaShop\\CircuitBreaker\\Transition\\NullDispatcher' => $vendorDir . '/prestashop/circuit-breaker/src/Transition/NullDispatcher.php',
'PrestaShop\\CircuitBreaker\\Util\\Assert' => $vendorDir . '/prestashop/circuit-breaker/src/Util/Assert.php',
'PrestaShop\\CircuitBreaker\\Util\\ErrorFormatter' => $vendorDir . '/prestashop/circuit-breaker/src/Util/ErrorFormatter.php',
'PrestaShop\\Module\\ProductComment\\Addons\\CategoryFetcher' => $baseDir . '/src/Addons/CategoryFetcher.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductComment' => $baseDir . '/src/Entity/ProductComment.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductCommentCriterion' => $baseDir . '/src/Entity/ProductCommentCriterion.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductCommentGrade' => $baseDir . '/src/Entity/ProductCommentGrade.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductCommentReport' => $baseDir . '/src/Entity/ProductCommentReport.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductCommentUsefulness' => $baseDir . '/src/Entity/ProductCommentUsefulness.php',
'PrestaShop\\Module\\ProductComment\\Repository\\ProductCommentCriterionRepository' => $baseDir . '/src/Repository/ProductCommentCriterionRepository.php',
'PrestaShop\\Module\\ProductComment\\Repository\\ProductCommentRepository' => $baseDir . '/src/Repository/ProductCommentRepository.php',
'ProductComments' => $baseDir . '/productcomments.php',
'React\\Promise\\CancellablePromiseInterface' => $vendorDir . '/react/promise/src/CancellablePromiseInterface.php',
'React\\Promise\\CancellationQueue' => $vendorDir . '/react/promise/src/CancellationQueue.php',
'React\\Promise\\Deferred' => $vendorDir . '/react/promise/src/Deferred.php',
'React\\Promise\\Exception\\LengthException' => $vendorDir . '/react/promise/src/Exception/LengthException.php',
'React\\Promise\\ExtendedPromiseInterface' => $vendorDir . '/react/promise/src/ExtendedPromiseInterface.php',
'React\\Promise\\FulfilledPromise' => $vendorDir . '/react/promise/src/FulfilledPromise.php',
'React\\Promise\\LazyPromise' => $vendorDir . '/react/promise/src/LazyPromise.php',
'React\\Promise\\Promise' => $vendorDir . '/react/promise/src/Promise.php',
'React\\Promise\\PromiseInterface' => $vendorDir . '/react/promise/src/PromiseInterface.php',
'React\\Promise\\PromisorInterface' => $vendorDir . '/react/promise/src/PromisorInterface.php',
'React\\Promise\\RejectedPromise' => $vendorDir . '/react/promise/src/RejectedPromise.php',
'React\\Promise\\UnhandledRejectionException' => $vendorDir . '/react/promise/src/UnhandledRejectionException.php',
'Symfony\\Component\\CssSelector\\CssSelectorConverter' => $vendorDir . '/symfony/css-selector/CssSelectorConverter.php',
'Symfony\\Component\\CssSelector\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/css-selector/Exception/ExceptionInterface.php',
'Symfony\\Component\\CssSelector\\Exception\\ExpressionErrorException' => $vendorDir . '/symfony/css-selector/Exception/ExpressionErrorException.php',
'Symfony\\Component\\CssSelector\\Exception\\InternalErrorException' => $vendorDir . '/symfony/css-selector/Exception/InternalErrorException.php',
'Symfony\\Component\\CssSelector\\Exception\\ParseException' => $vendorDir . '/symfony/css-selector/Exception/ParseException.php',
'Symfony\\Component\\CssSelector\\Exception\\SyntaxErrorException' => $vendorDir . '/symfony/css-selector/Exception/SyntaxErrorException.php',
'Symfony\\Component\\CssSelector\\Node\\AbstractNode' => $vendorDir . '/symfony/css-selector/Node/AbstractNode.php',
'Symfony\\Component\\CssSelector\\Node\\AttributeNode' => $vendorDir . '/symfony/css-selector/Node/AttributeNode.php',
'Symfony\\Component\\CssSelector\\Node\\ClassNode' => $vendorDir . '/symfony/css-selector/Node/ClassNode.php',
'Symfony\\Component\\CssSelector\\Node\\CombinedSelectorNode' => $vendorDir . '/symfony/css-selector/Node/CombinedSelectorNode.php',
'Symfony\\Component\\CssSelector\\Node\\ElementNode' => $vendorDir . '/symfony/css-selector/Node/ElementNode.php',
'Symfony\\Component\\CssSelector\\Node\\FunctionNode' => $vendorDir . '/symfony/css-selector/Node/FunctionNode.php',
'Symfony\\Component\\CssSelector\\Node\\HashNode' => $vendorDir . '/symfony/css-selector/Node/HashNode.php',
'Symfony\\Component\\CssSelector\\Node\\NegationNode' => $vendorDir . '/symfony/css-selector/Node/NegationNode.php',
'Symfony\\Component\\CssSelector\\Node\\NodeInterface' => $vendorDir . '/symfony/css-selector/Node/NodeInterface.php',
'Symfony\\Component\\CssSelector\\Node\\PseudoNode' => $vendorDir . '/symfony/css-selector/Node/PseudoNode.php',
'Symfony\\Component\\CssSelector\\Node\\SelectorNode' => $vendorDir . '/symfony/css-selector/Node/SelectorNode.php',
'Symfony\\Component\\CssSelector\\Node\\Specificity' => $vendorDir . '/symfony/css-selector/Node/Specificity.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\CommentHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/CommentHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\HandlerInterface' => $vendorDir . '/symfony/css-selector/Parser/Handler/HandlerInterface.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\HashHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/HashHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\IdentifierHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/IdentifierHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\NumberHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/NumberHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\StringHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/StringHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\WhitespaceHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/WhitespaceHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Parser' => $vendorDir . '/symfony/css-selector/Parser/Parser.php',
'Symfony\\Component\\CssSelector\\Parser\\ParserInterface' => $vendorDir . '/symfony/css-selector/Parser/ParserInterface.php',
'Symfony\\Component\\CssSelector\\Parser\\Reader' => $vendorDir . '/symfony/css-selector/Parser/Reader.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ClassParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/ClassParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ElementParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/ElementParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\EmptyStringParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\HashParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/HashParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Token' => $vendorDir . '/symfony/css-selector/Parser/Token.php',
'Symfony\\Component\\CssSelector\\Parser\\TokenStream' => $vendorDir . '/symfony/css-selector/Parser/TokenStream.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\Tokenizer' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/Tokenizer.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerEscaping' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerPatterns' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\AbstractExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/AbstractExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\AttributeMatchingExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\CombinationExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/CombinationExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\ExtensionInterface' => $vendorDir . '/symfony/css-selector/XPath/Extension/ExtensionInterface.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\FunctionExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/FunctionExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\HtmlExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/HtmlExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\NodeExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/NodeExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\PseudoClassExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/PseudoClassExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Translator' => $vendorDir . '/symfony/css-selector/XPath/Translator.php',
'Symfony\\Component\\CssSelector\\XPath\\TranslatorInterface' => $vendorDir . '/symfony/css-selector/XPath/TranslatorInterface.php',
'Symfony\\Component\\CssSelector\\XPath\\XPathExpr' => $vendorDir . '/symfony/css-selector/XPath/XPathExpr.php',
);

View File

@@ -0,0 +1,10 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'ad155f8f1cf0d418fe49e248db8c661b' => $vendorDir . '/react/promise/src/functions_include.php',
);

View File

@@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@@ -0,0 +1,18 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
'React\\Promise\\' => array($vendorDir . '/react/promise/src'),
'PrestaShop\\Module\\ProductComment\\' => array($baseDir . '/src'),
'PrestaShop\\CircuitBreaker\\' => array($vendorDir . '/prestashop/circuit-breaker/src'),
'GuzzleHttp\\Subscriber\\Cache\\' => array($vendorDir . '/guzzlehttp/cache-subscriber/src'),
'GuzzleHttp\\Stream\\' => array($vendorDir . '/guzzlehttp/streams/src'),
'GuzzleHttp\\Ring\\' => array($vendorDir . '/guzzlehttp/ringphp/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'),
);

View File

@@ -0,0 +1,61 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitcf0e80547367544c26e9561d5957499d
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitcf0e80547367544c26e9561d5957499d', 'loadClassLoader'), true, false);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitcf0e80547367544c26e9561d5957499d', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitcf0e80547367544c26e9561d5957499d::getInitializer($loader));
} else {
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->setClassMapAuthoritative(true);
$loader->register(false);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInitcf0e80547367544c26e9561d5957499d::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirecf0e80547367544c26e9561d5957499d($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequirecf0e80547367544c26e9561d5957499d($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@@ -0,0 +1,342 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInitcf0e80547367544c26e9561d5957499d
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
);
public static $prefixLengthsPsr4 = array (
'S' =>
array (
'Symfony\\Component\\CssSelector\\' => 30,
),
'R' =>
array (
'React\\Promise\\' => 14,
),
'P' =>
array (
'PrestaShop\\Module\\ProductComment\\' => 33,
'PrestaShop\\CircuitBreaker\\' => 26,
),
'G' =>
array (
'GuzzleHttp\\Subscriber\\Cache\\' => 28,
'GuzzleHttp\\Stream\\' => 18,
'GuzzleHttp\\Ring\\' => 16,
'GuzzleHttp\\' => 11,
),
'D' =>
array (
'Doctrine\\Common\\Cache\\' => 22,
),
);
public static $prefixDirsPsr4 = array (
'Symfony\\Component\\CssSelector\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/css-selector',
),
'React\\Promise\\' =>
array (
0 => __DIR__ . '/..' . '/react/promise/src',
),
'PrestaShop\\Module\\ProductComment\\' =>
array (
0 => __DIR__ . '/../..' . '/src',
),
'PrestaShop\\CircuitBreaker\\' =>
array (
0 => __DIR__ . '/..' . '/prestashop/circuit-breaker/src',
),
'GuzzleHttp\\Subscriber\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/cache-subscriber/src',
),
'GuzzleHttp\\Stream\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/streams/src',
),
'GuzzleHttp\\Ring\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/ringphp/src',
),
'GuzzleHttp\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
),
'Doctrine\\Common\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache',
),
);
public static $classMap = array (
'Doctrine\\Common\\Cache\\ApcCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php',
'Doctrine\\Common\\Cache\\ApcuCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php',
'Doctrine\\Common\\Cache\\ArrayCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php',
'Doctrine\\Common\\Cache\\Cache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php',
'Doctrine\\Common\\Cache\\CacheProvider' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php',
'Doctrine\\Common\\Cache\\ChainCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php',
'Doctrine\\Common\\Cache\\ClearableCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php',
'Doctrine\\Common\\Cache\\CouchbaseCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php',
'Doctrine\\Common\\Cache\\FileCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php',
'Doctrine\\Common\\Cache\\FilesystemCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php',
'Doctrine\\Common\\Cache\\FlushableCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php',
'Doctrine\\Common\\Cache\\MemcacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php',
'Doctrine\\Common\\Cache\\MemcachedCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php',
'Doctrine\\Common\\Cache\\MongoDBCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php',
'Doctrine\\Common\\Cache\\MultiGetCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php',
'Doctrine\\Common\\Cache\\MultiPutCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php',
'Doctrine\\Common\\Cache\\PhpFileCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php',
'Doctrine\\Common\\Cache\\PredisCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php',
'Doctrine\\Common\\Cache\\RedisCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php',
'Doctrine\\Common\\Cache\\RiakCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php',
'Doctrine\\Common\\Cache\\SQLite3Cache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php',
'Doctrine\\Common\\Cache\\Version' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php',
'Doctrine\\Common\\Cache\\VoidCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php',
'Doctrine\\Common\\Cache\\WinCacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php',
'Doctrine\\Common\\Cache\\XcacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php',
'Doctrine\\Common\\Cache\\ZendDataCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php',
'GuzzleHttp\\BatchResults' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/BatchResults.php',
'GuzzleHttp\\Client' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Client.php',
'GuzzleHttp\\ClientInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/ClientInterface.php',
'GuzzleHttp\\Collection' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Collection.php',
'GuzzleHttp\\Cookie\\CookieJar' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php',
'GuzzleHttp\\Cookie\\CookieJarInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php',
'GuzzleHttp\\Cookie\\FileCookieJar' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php',
'GuzzleHttp\\Cookie\\SessionCookieJar' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php',
'GuzzleHttp\\Cookie\\SetCookie' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/SetCookie.php',
'GuzzleHttp\\Event\\AbstractEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/AbstractEvent.php',
'GuzzleHttp\\Event\\AbstractRequestEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/AbstractRequestEvent.php',
'GuzzleHttp\\Event\\AbstractRetryableEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/AbstractRetryableEvent.php',
'GuzzleHttp\\Event\\AbstractTransferEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/AbstractTransferEvent.php',
'GuzzleHttp\\Event\\BeforeEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/BeforeEvent.php',
'GuzzleHttp\\Event\\CompleteEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/CompleteEvent.php',
'GuzzleHttp\\Event\\Emitter' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/Emitter.php',
'GuzzleHttp\\Event\\EmitterInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/EmitterInterface.php',
'GuzzleHttp\\Event\\EndEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/EndEvent.php',
'GuzzleHttp\\Event\\ErrorEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/ErrorEvent.php',
'GuzzleHttp\\Event\\EventInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/EventInterface.php',
'GuzzleHttp\\Event\\HasEmitterInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/HasEmitterInterface.php',
'GuzzleHttp\\Event\\HasEmitterTrait' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/HasEmitterTrait.php',
'GuzzleHttp\\Event\\ListenerAttacherTrait' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/ListenerAttacherTrait.php',
'GuzzleHttp\\Event\\ProgressEvent' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/ProgressEvent.php',
'GuzzleHttp\\Event\\RequestEvents' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/RequestEvents.php',
'GuzzleHttp\\Event\\SubscriberInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Event/SubscriberInterface.php',
'GuzzleHttp\\Exception\\BadResponseException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/BadResponseException.php',
'GuzzleHttp\\Exception\\ClientException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/ClientException.php',
'GuzzleHttp\\Exception\\ConnectException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/ConnectException.php',
'GuzzleHttp\\Exception\\CouldNotRewindStreamException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/CouldNotRewindStreamException.php',
'GuzzleHttp\\Exception\\ParseException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/ParseException.php',
'GuzzleHttp\\Exception\\RequestException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/RequestException.php',
'GuzzleHttp\\Exception\\ServerException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/ServerException.php',
'GuzzleHttp\\Exception\\StateException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/StateException.php',
'GuzzleHttp\\Exception\\TooManyRedirectsException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php',
'GuzzleHttp\\Exception\\TransferException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/TransferException.php',
'GuzzleHttp\\Exception\\XmlParseException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/XmlParseException.php',
'GuzzleHttp\\HasDataTrait' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/HasDataTrait.php',
'GuzzleHttp\\Message\\AbstractMessage' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/AbstractMessage.php',
'GuzzleHttp\\Message\\AppliesHeadersInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/AppliesHeadersInterface.php',
'GuzzleHttp\\Message\\FutureResponse' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/FutureResponse.php',
'GuzzleHttp\\Message\\MessageFactory' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/MessageFactory.php',
'GuzzleHttp\\Message\\MessageFactoryInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/MessageFactoryInterface.php',
'GuzzleHttp\\Message\\MessageInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/MessageInterface.php',
'GuzzleHttp\\Message\\MessageParser' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/MessageParser.php',
'GuzzleHttp\\Message\\Request' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/Request.php',
'GuzzleHttp\\Message\\RequestInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/RequestInterface.php',
'GuzzleHttp\\Message\\Response' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/Response.php',
'GuzzleHttp\\Message\\ResponseInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Message/ResponseInterface.php',
'GuzzleHttp\\Mimetypes' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Mimetypes.php',
'GuzzleHttp\\Pool' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Pool.php',
'GuzzleHttp\\Post\\MultipartBody' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Post/MultipartBody.php',
'GuzzleHttp\\Post\\PostBody' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Post/PostBody.php',
'GuzzleHttp\\Post\\PostBodyInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Post/PostBodyInterface.php',
'GuzzleHttp\\Post\\PostFile' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Post/PostFile.php',
'GuzzleHttp\\Post\\PostFileInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Post/PostFileInterface.php',
'GuzzleHttp\\Query' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Query.php',
'GuzzleHttp\\QueryParser' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/QueryParser.php',
'GuzzleHttp\\RequestFsm' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RequestFsm.php',
'GuzzleHttp\\RingBridge' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RingBridge.php',
'GuzzleHttp\\Ring\\Client\\ClientUtils' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Client/ClientUtils.php',
'GuzzleHttp\\Ring\\Client\\CurlFactory' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Client/CurlFactory.php',
'GuzzleHttp\\Ring\\Client\\CurlHandler' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Client/CurlHandler.php',
'GuzzleHttp\\Ring\\Client\\CurlMultiHandler' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Client/CurlMultiHandler.php',
'GuzzleHttp\\Ring\\Client\\Middleware' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Client/Middleware.php',
'GuzzleHttp\\Ring\\Client\\MockHandler' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Client/MockHandler.php',
'GuzzleHttp\\Ring\\Client\\StreamHandler' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Client/StreamHandler.php',
'GuzzleHttp\\Ring\\Core' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Core.php',
'GuzzleHttp\\Ring\\Exception\\CancelledException' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Exception/CancelledException.php',
'GuzzleHttp\\Ring\\Exception\\CancelledFutureAccessException' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Exception/CancelledFutureAccessException.php',
'GuzzleHttp\\Ring\\Exception\\ConnectException' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Exception/ConnectException.php',
'GuzzleHttp\\Ring\\Exception\\RingException' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Exception/RingException.php',
'GuzzleHttp\\Ring\\Future\\BaseFutureTrait' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Future/BaseFutureTrait.php',
'GuzzleHttp\\Ring\\Future\\CompletedFutureArray' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Future/CompletedFutureArray.php',
'GuzzleHttp\\Ring\\Future\\CompletedFutureValue' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php',
'GuzzleHttp\\Ring\\Future\\FutureArray' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Future/FutureArray.php',
'GuzzleHttp\\Ring\\Future\\FutureArrayInterface' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Future/FutureArrayInterface.php',
'GuzzleHttp\\Ring\\Future\\FutureInterface' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Future/FutureInterface.php',
'GuzzleHttp\\Ring\\Future\\FutureValue' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Future/FutureValue.php',
'GuzzleHttp\\Ring\\Future\\MagicFutureTrait' => __DIR__ . '/..' . '/guzzlehttp/ringphp/src/Future/MagicFutureTrait.php',
'GuzzleHttp\\Stream\\AppendStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/AppendStream.php',
'GuzzleHttp\\Stream\\AsyncReadStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/AsyncReadStream.php',
'GuzzleHttp\\Stream\\BufferStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/BufferStream.php',
'GuzzleHttp\\Stream\\CachingStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/CachingStream.php',
'GuzzleHttp\\Stream\\DroppingStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/DroppingStream.php',
'GuzzleHttp\\Stream\\Exception\\CannotAttachException' => __DIR__ . '/..' . '/guzzlehttp/streams/src/Exception/CannotAttachException.php',
'GuzzleHttp\\Stream\\Exception\\SeekException' => __DIR__ . '/..' . '/guzzlehttp/streams/src/Exception/SeekException.php',
'GuzzleHttp\\Stream\\FnStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/FnStream.php',
'GuzzleHttp\\Stream\\GuzzleStreamWrapper' => __DIR__ . '/..' . '/guzzlehttp/streams/src/GuzzleStreamWrapper.php',
'GuzzleHttp\\Stream\\InflateStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/InflateStream.php',
'GuzzleHttp\\Stream\\LazyOpenStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/LazyOpenStream.php',
'GuzzleHttp\\Stream\\LimitStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/LimitStream.php',
'GuzzleHttp\\Stream\\MetadataStreamInterface' => __DIR__ . '/..' . '/guzzlehttp/streams/src/MetadataStreamInterface.php',
'GuzzleHttp\\Stream\\NoSeekStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/NoSeekStream.php',
'GuzzleHttp\\Stream\\NullStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/NullStream.php',
'GuzzleHttp\\Stream\\PumpStream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/PumpStream.php',
'GuzzleHttp\\Stream\\Stream' => __DIR__ . '/..' . '/guzzlehttp/streams/src/Stream.php',
'GuzzleHttp\\Stream\\StreamDecoratorTrait' => __DIR__ . '/..' . '/guzzlehttp/streams/src/StreamDecoratorTrait.php',
'GuzzleHttp\\Stream\\StreamInterface' => __DIR__ . '/..' . '/guzzlehttp/streams/src/StreamInterface.php',
'GuzzleHttp\\Stream\\Utils' => __DIR__ . '/..' . '/guzzlehttp/streams/src/Utils.php',
'GuzzleHttp\\Subscriber\\Cache\\CacheStorage' => __DIR__ . '/..' . '/guzzlehttp/cache-subscriber/src/CacheStorage.php',
'GuzzleHttp\\Subscriber\\Cache\\CacheStorageInterface' => __DIR__ . '/..' . '/guzzlehttp/cache-subscriber/src/CacheStorageInterface.php',
'GuzzleHttp\\Subscriber\\Cache\\CacheSubscriber' => __DIR__ . '/..' . '/guzzlehttp/cache-subscriber/src/CacheSubscriber.php',
'GuzzleHttp\\Subscriber\\Cache\\PurgeSubscriber' => __DIR__ . '/..' . '/guzzlehttp/cache-subscriber/src/PurgeSubscriber.php',
'GuzzleHttp\\Subscriber\\Cache\\Utils' => __DIR__ . '/..' . '/guzzlehttp/cache-subscriber/src/Utils.php',
'GuzzleHttp\\Subscriber\\Cache\\ValidationSubscriber' => __DIR__ . '/..' . '/guzzlehttp/cache-subscriber/src/ValidationSubscriber.php',
'GuzzleHttp\\Subscriber\\Cookie' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Subscriber/Cookie.php',
'GuzzleHttp\\Subscriber\\History' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Subscriber/History.php',
'GuzzleHttp\\Subscriber\\HttpError' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Subscriber/HttpError.php',
'GuzzleHttp\\Subscriber\\Mock' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Subscriber/Mock.php',
'GuzzleHttp\\Subscriber\\Prepare' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Subscriber/Prepare.php',
'GuzzleHttp\\Subscriber\\Redirect' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Subscriber/Redirect.php',
'GuzzleHttp\\ToArrayInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/ToArrayInterface.php',
'GuzzleHttp\\Transaction' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Transaction.php',
'GuzzleHttp\\UriTemplate' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/UriTemplate.php',
'GuzzleHttp\\Url' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Url.php',
'GuzzleHttp\\Utils' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Utils.php',
'PrestaShop\\CircuitBreaker\\AdvancedCircuitBreaker' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/AdvancedCircuitBreaker.php',
'PrestaShop\\CircuitBreaker\\AdvancedCircuitBreakerFactory' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/AdvancedCircuitBreakerFactory.php',
'PrestaShop\\CircuitBreaker\\Client\\GuzzleClient' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Client/GuzzleClient.php',
'PrestaShop\\CircuitBreaker\\Contract\\CircuitBreakerInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/CircuitBreakerInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\ClientInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/ClientInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\FactoryInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/FactoryInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\FactorySettingsInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/FactorySettingsInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\PlaceInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/PlaceInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\StorageInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/StorageInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\SystemInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/SystemInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\TransactionInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/TransactionInterface.php',
'PrestaShop\\CircuitBreaker\\Contract\\TransitionDispatcherInterface' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Contract/TransitionDispatcherInterface.php',
'PrestaShop\\CircuitBreaker\\Event\\TransitionEvent' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Event/TransitionEvent.php',
'PrestaShop\\CircuitBreaker\\Exception\\CircuitBreakerException' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Exception/CircuitBreakerException.php',
'PrestaShop\\CircuitBreaker\\Exception\\InvalidPlaceException' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Exception/InvalidPlaceException.php',
'PrestaShop\\CircuitBreaker\\Exception\\InvalidTransactionException' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Exception/InvalidTransactionException.php',
'PrestaShop\\CircuitBreaker\\Exception\\TransactionNotFoundException' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Exception/TransactionNotFoundException.php',
'PrestaShop\\CircuitBreaker\\Exception\\UnavailableServiceException' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Exception/UnavailableServiceException.php',
'PrestaShop\\CircuitBreaker\\Exception\\UnsupportedMethodException' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Exception/UnsupportedMethodException.php',
'PrestaShop\\CircuitBreaker\\FactorySettings' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/FactorySettings.php',
'PrestaShop\\CircuitBreaker\\PartialCircuitBreaker' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/PartialCircuitBreaker.php',
'PrestaShop\\CircuitBreaker\\Place\\AbstractPlace' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Place/AbstractPlace.php',
'PrestaShop\\CircuitBreaker\\Place\\ClosedPlace' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Place/ClosedPlace.php',
'PrestaShop\\CircuitBreaker\\Place\\HalfOpenPlace' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Place/HalfOpenPlace.php',
'PrestaShop\\CircuitBreaker\\Place\\OpenPlace' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Place/OpenPlace.php',
'PrestaShop\\CircuitBreaker\\SimpleCircuitBreaker' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/SimpleCircuitBreaker.php',
'PrestaShop\\CircuitBreaker\\SimpleCircuitBreakerFactory' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/SimpleCircuitBreakerFactory.php',
'PrestaShop\\CircuitBreaker\\State' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/State.php',
'PrestaShop\\CircuitBreaker\\Storage\\DoctrineCache' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Storage/DoctrineCache.php',
'PrestaShop\\CircuitBreaker\\Storage\\SimpleArray' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Storage/SimpleArray.php',
'PrestaShop\\CircuitBreaker\\Storage\\SymfonyCache' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Storage/SymfonyCache.php',
'PrestaShop\\CircuitBreaker\\SymfonyCircuitBreaker' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/SymfonyCircuitBreaker.php',
'PrestaShop\\CircuitBreaker\\System\\MainSystem' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/System/MainSystem.php',
'PrestaShop\\CircuitBreaker\\Transaction\\SimpleTransaction' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Transaction/SimpleTransaction.php',
'PrestaShop\\CircuitBreaker\\Transition' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Transition.php',
'PrestaShop\\CircuitBreaker\\Transition\\EventDispatcher' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Transition/EventDispatcher.php',
'PrestaShop\\CircuitBreaker\\Transition\\NullDispatcher' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Transition/NullDispatcher.php',
'PrestaShop\\CircuitBreaker\\Util\\Assert' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Util/Assert.php',
'PrestaShop\\CircuitBreaker\\Util\\ErrorFormatter' => __DIR__ . '/..' . '/prestashop/circuit-breaker/src/Util/ErrorFormatter.php',
'PrestaShop\\Module\\ProductComment\\Addons\\CategoryFetcher' => __DIR__ . '/../..' . '/src/Addons/CategoryFetcher.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductComment' => __DIR__ . '/../..' . '/src/Entity/ProductComment.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductCommentCriterion' => __DIR__ . '/../..' . '/src/Entity/ProductCommentCriterion.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductCommentGrade' => __DIR__ . '/../..' . '/src/Entity/ProductCommentGrade.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductCommentReport' => __DIR__ . '/../..' . '/src/Entity/ProductCommentReport.php',
'PrestaShop\\Module\\ProductComment\\Entity\\ProductCommentUsefulness' => __DIR__ . '/../..' . '/src/Entity/ProductCommentUsefulness.php',
'PrestaShop\\Module\\ProductComment\\Repository\\ProductCommentCriterionRepository' => __DIR__ . '/../..' . '/src/Repository/ProductCommentCriterionRepository.php',
'PrestaShop\\Module\\ProductComment\\Repository\\ProductCommentRepository' => __DIR__ . '/../..' . '/src/Repository/ProductCommentRepository.php',
'ProductComments' => __DIR__ . '/../..' . '/productcomments.php',
'React\\Promise\\CancellablePromiseInterface' => __DIR__ . '/..' . '/react/promise/src/CancellablePromiseInterface.php',
'React\\Promise\\CancellationQueue' => __DIR__ . '/..' . '/react/promise/src/CancellationQueue.php',
'React\\Promise\\Deferred' => __DIR__ . '/..' . '/react/promise/src/Deferred.php',
'React\\Promise\\Exception\\LengthException' => __DIR__ . '/..' . '/react/promise/src/Exception/LengthException.php',
'React\\Promise\\ExtendedPromiseInterface' => __DIR__ . '/..' . '/react/promise/src/ExtendedPromiseInterface.php',
'React\\Promise\\FulfilledPromise' => __DIR__ . '/..' . '/react/promise/src/FulfilledPromise.php',
'React\\Promise\\LazyPromise' => __DIR__ . '/..' . '/react/promise/src/LazyPromise.php',
'React\\Promise\\Promise' => __DIR__ . '/..' . '/react/promise/src/Promise.php',
'React\\Promise\\PromiseInterface' => __DIR__ . '/..' . '/react/promise/src/PromiseInterface.php',
'React\\Promise\\PromisorInterface' => __DIR__ . '/..' . '/react/promise/src/PromisorInterface.php',
'React\\Promise\\RejectedPromise' => __DIR__ . '/..' . '/react/promise/src/RejectedPromise.php',
'React\\Promise\\UnhandledRejectionException' => __DIR__ . '/..' . '/react/promise/src/UnhandledRejectionException.php',
'Symfony\\Component\\CssSelector\\CssSelectorConverter' => __DIR__ . '/..' . '/symfony/css-selector/CssSelectorConverter.php',
'Symfony\\Component\\CssSelector\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/css-selector/Exception/ExceptionInterface.php',
'Symfony\\Component\\CssSelector\\Exception\\ExpressionErrorException' => __DIR__ . '/..' . '/symfony/css-selector/Exception/ExpressionErrorException.php',
'Symfony\\Component\\CssSelector\\Exception\\InternalErrorException' => __DIR__ . '/..' . '/symfony/css-selector/Exception/InternalErrorException.php',
'Symfony\\Component\\CssSelector\\Exception\\ParseException' => __DIR__ . '/..' . '/symfony/css-selector/Exception/ParseException.php',
'Symfony\\Component\\CssSelector\\Exception\\SyntaxErrorException' => __DIR__ . '/..' . '/symfony/css-selector/Exception/SyntaxErrorException.php',
'Symfony\\Component\\CssSelector\\Node\\AbstractNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/AbstractNode.php',
'Symfony\\Component\\CssSelector\\Node\\AttributeNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/AttributeNode.php',
'Symfony\\Component\\CssSelector\\Node\\ClassNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/ClassNode.php',
'Symfony\\Component\\CssSelector\\Node\\CombinedSelectorNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/CombinedSelectorNode.php',
'Symfony\\Component\\CssSelector\\Node\\ElementNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/ElementNode.php',
'Symfony\\Component\\CssSelector\\Node\\FunctionNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/FunctionNode.php',
'Symfony\\Component\\CssSelector\\Node\\HashNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/HashNode.php',
'Symfony\\Component\\CssSelector\\Node\\NegationNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/NegationNode.php',
'Symfony\\Component\\CssSelector\\Node\\NodeInterface' => __DIR__ . '/..' . '/symfony/css-selector/Node/NodeInterface.php',
'Symfony\\Component\\CssSelector\\Node\\PseudoNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/PseudoNode.php',
'Symfony\\Component\\CssSelector\\Node\\SelectorNode' => __DIR__ . '/..' . '/symfony/css-selector/Node/SelectorNode.php',
'Symfony\\Component\\CssSelector\\Node\\Specificity' => __DIR__ . '/..' . '/symfony/css-selector/Node/Specificity.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\CommentHandler' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Handler/CommentHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\HandlerInterface' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Handler/HandlerInterface.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\HashHandler' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Handler/HashHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\IdentifierHandler' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Handler/IdentifierHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\NumberHandler' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Handler/NumberHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\StringHandler' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Handler/StringHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Handler\\WhitespaceHandler' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Handler/WhitespaceHandler.php',
'Symfony\\Component\\CssSelector\\Parser\\Parser' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Parser.php',
'Symfony\\Component\\CssSelector\\Parser\\ParserInterface' => __DIR__ . '/..' . '/symfony/css-selector/Parser/ParserInterface.php',
'Symfony\\Component\\CssSelector\\Parser\\Reader' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Reader.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ClassParser' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Shortcut/ClassParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ElementParser' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Shortcut/ElementParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\EmptyStringParser' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\HashParser' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Shortcut/HashParser.php',
'Symfony\\Component\\CssSelector\\Parser\\Token' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Token.php',
'Symfony\\Component\\CssSelector\\Parser\\TokenStream' => __DIR__ . '/..' . '/symfony/css-selector/Parser/TokenStream.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\Tokenizer' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Tokenizer/Tokenizer.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerEscaping' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php',
'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerPatterns' => __DIR__ . '/..' . '/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\AbstractExtension' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Extension/AbstractExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\AttributeMatchingExtension' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\CombinationExtension' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Extension/CombinationExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\ExtensionInterface' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Extension/ExtensionInterface.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\FunctionExtension' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Extension/FunctionExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\HtmlExtension' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Extension/HtmlExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\NodeExtension' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Extension/NodeExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Extension\\PseudoClassExtension' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Extension/PseudoClassExtension.php',
'Symfony\\Component\\CssSelector\\XPath\\Translator' => __DIR__ . '/..' . '/symfony/css-selector/XPath/Translator.php',
'Symfony\\Component\\CssSelector\\XPath\\TranslatorInterface' => __DIR__ . '/..' . '/symfony/css-selector/XPath/TranslatorInterface.php',
'Symfony\\Component\\CssSelector\\XPath\\XPathExpr' => __DIR__ . '/..' . '/symfony/css-selector/XPath/XPathExpr.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitcf0e80547367544c26e9561d5957499d::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitcf0e80547367544c26e9561d5957499d::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitcf0e80547367544c26e9561d5957499d::$classMap;
}, null, ClassLoader::class);
}
}

View File

@@ -0,0 +1,451 @@
[
{
"name": "doctrine/cache",
"version": "v1.6.2",
"version_normalized": "1.6.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/eb152c5100571c7a45470ff2a35095ab3f3b900b",
"reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b",
"shasum": ""
},
"require": {
"php": "~5.5|~7.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"phpunit/phpunit": "~4.8|~5.0",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"time": "2017-07-22T12:49:21+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
]
},
{
"name": "guzzlehttp/cache-subscriber",
"version": "0.2.0",
"version_normalized": "0.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/cache-subscriber.git",
"reference": "8c766ba399e4c46383e3eaa220201be62abd101e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/cache-subscriber/zipball/8c766ba399e4c46383e3eaa220201be62abd101e",
"reference": "8c766ba399e4c46383e3eaa220201be62abd101e",
"shasum": ""
},
"require": {
"doctrine/cache": "~1.3",
"guzzlehttp/guzzle": "~5.0",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"time": "2019-09-16T13:44:55+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.2-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"GuzzleHttp\\Subscriber\\Cache\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle HTTP cache subscriber",
"homepage": "http://guzzlephp.org/",
"keywords": [
"Guzzle",
"cache"
]
},
{
"name": "guzzlehttp/guzzle",
"version": "5.3.4",
"version_normalized": "5.3.4.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "b87eda7a7162f95574032da17e9323c9899cb6b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/b87eda7a7162f95574032da17e9323c9899cb6b2",
"reference": "b87eda7a7162f95574032da17e9323c9899cb6b2",
"shasum": ""
},
"require": {
"guzzlehttp/ringphp": "^1.1",
"php": ">=5.4.0",
"react/promise": "^2.2"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.0"
},
"time": "2019-10-30T09:32:00+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"rest",
"web service"
]
},
{
"name": "guzzlehttp/ringphp",
"version": "1.1.1",
"version_normalized": "1.1.1.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/RingPHP.git",
"reference": "5e2a174052995663dd68e6b5ad838afd47dd615b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/5e2a174052995663dd68e6b5ad838afd47dd615b",
"reference": "5e2a174052995663dd68e6b5ad838afd47dd615b",
"shasum": ""
},
"require": {
"guzzlehttp/streams": "~3.0",
"php": ">=5.4.0",
"react/promise": "~2.0"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "~4.0"
},
"suggest": {
"ext-curl": "Guzzle will use specific adapters if cURL is present"
},
"time": "2018-07-31T13:22:33+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"GuzzleHttp\\Ring\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
"abandoned": true
},
{
"name": "guzzlehttp/streams",
"version": "3.0.0",
"version_normalized": "3.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/streams.git",
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"time": "2014-10-12T19:18:40+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"GuzzleHttp\\Stream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Provides a simple abstraction over streams of data",
"homepage": "http://guzzlephp.org/",
"keywords": [
"Guzzle",
"stream"
],
"abandoned": true
},
{
"name": "prestashop/circuit-breaker",
"version": "v3.0.0",
"version_normalized": "3.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/PrestaShop/circuit-breaker.git",
"reference": "8764540d470b533c9484534343688733bc363f77"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PrestaShop/circuit-breaker/zipball/8764540d470b533c9484534343688733bc363f77",
"reference": "8764540d470b533c9484534343688733bc363f77",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^5",
"php": ">=5.6"
},
"require-dev": {
"doctrine/cache": "^1.6.0",
"friendsofphp/php-cs-fixer": "^2.12",
"phpunit/phpunit": "^5.7.0",
"squizlabs/php_codesniffer": "3.*",
"symfony/cache": "^3.4.0",
"symfony/event-dispatcher": "^3.4",
"vimeo/psalm": "^1.1"
},
"suggest": {
"doctrine/cache": "Allows use of Doctrine Cache adapters to store transactions",
"ext-apcu": "Allows use of APCu adapter (performant) to store transactions",
"guzzlehttp/cache-subscriber": "Allow use of Guzzle cache (use dev-master for most recent changes)",
"symfony/cache": "Allows use of Symfony Cache adapters to store transactions"
},
"time": "2019-06-13T10:50:14+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"PrestaShop\\CircuitBreaker\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PrestaShop SA",
"email": "contact@prestashop.com"
},
{
"name": "PrestaShop Community",
"homepage": "http://contributors.prestashop.com/"
}
],
"description": "A circuit breaker implementation for PHP"
},
{
"name": "react/promise",
"version": "v2.7.1",
"version_normalized": "2.7.1.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
"reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8"
},
"time": "2019-01-07T21:25:54+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"React\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com"
}
],
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
"keywords": [
"promise",
"promises"
]
},
{
"name": "symfony/css-selector",
"version": "v3.4.37",
"version_normalized": "3.4.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5",
"reference": "e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
},
"time": "2020-01-01T11:03:25+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com"
}
]

View File

@@ -0,0 +1,19 @@
Copyright (c) 2006-2015 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,14 @@
# Doctrine Cache
Master: [![Build Status](https://secure.travis-ci.org/doctrine/cache.png?branch=master)](http://travis-ci.org/doctrine/cache) [![Coverage Status](https://coveralls.io/repos/doctrine/cache/badge.png?branch=master)](https://coveralls.io/r/doctrine/cache?branch=master)
[![Latest Stable Version](https://poser.pugx.org/doctrine/cache/v/stable.png)](https://packagist.org/packages/doctrine/cache) [![Total Downloads](https://poser.pugx.org/doctrine/cache/downloads.png)](https://packagist.org/packages/doctrine/cache)
Cache component extracted from the Doctrine Common project.
## Changelog
### v1.2
* Added support for MongoDB as Cache Provider
* Fix namespace version reset

View File

@@ -0,0 +1,16 @@
# Upgrade to 1.4
## Minor BC Break: `Doctrine\Common\Cache\FileCache#$extension` is now `private`.
If you need to override the value of `Doctrine\Common\Cache\FileCache#$extension`, then use the
second parameter of `Doctrine\Common\Cache\FileCache#__construct()` instead of overriding
the property in your own implementation.
## Minor BC Break: file based caches paths changed
`Doctrine\Common\Cache\FileCache`, `Doctrine\Common\Cache\PhpFileCache` and
`Doctrine\Common\Cache\FilesystemCache` are using a different cache paths structure.
If you rely on warmed up caches for deployments, consider that caches generated
with `doctrine/cache` `<1.4` are not compatible with the new directory structure,
and will be ignored.

View File

@@ -0,0 +1,3 @@
# Version class and file
project.version_class = Doctrine\\Common\\Cache\\Version
project.version_file = lib/Doctrine/Common/Cache/Version.php

View File

@@ -0,0 +1,110 @@
<?xml version="1.0"?>
<project name="DoctrineCommonCache" default="build" basedir=".">
<property file="build.properties" />
<target name="php">
<exec executable="which" outputproperty="php_executable">
<arg value="php" />
</exec>
</target>
<target name="prepare">
<mkdir dir="build" />
</target>
<target name="build" depends="check-git-checkout-clean,prepare,php,composer">
<exec executable="${php_executable}">
<arg value="build/composer.phar" />
<arg value="archive" />
<arg value="--dir=build" />
</exec>
</target>
<target name="composer" depends="php,composer-check,composer-download">
<exec executable="${php_executable}">
<arg value="build/composer.phar" />
<arg value="install" />
</exec>
</target>
<target name="composer-check" depends="prepare">
<available file="build/composer.phar" property="composer.present"/>
</target>
<target name="composer-download" unless="composer.present">
<exec executable="wget">
<arg value="-Obuild/composer.phar" />
<arg value="http://getcomposer.org/composer.phar" />
</exec>
</target>
<target name="make-release" depends="check-git-checkout-clean,prepare,php">
<replace file="${project.version_file}" token="-DEV" value="" failOnNoReplacements="true" />
<exec executable="git" failonerror="true" outputproperty="current_git_branch">
<arg value="rev-parse" />
<arg value="--abbrev-ref" />
<arg value="HEAD" />
</exec>
<exec executable="${php_executable}" outputproperty="doctrine.current_version" failonerror="true">
<arg value="-r" />
<arg value="require_once '${project.version_file}';echo ${project.version_class}::VERSION;" />
</exec>
<exec executable="${php_executable}" outputproperty="doctrine.next_version" failonerror="true">
<arg value="-r" />
<arg value="$parts = explode('.', str_ireplace(array('-DEV', '-ALPHA', '-BETA'), '', '${doctrine.current_version}'));
if (count($parts) != 3) {
throw new \InvalidArgumentException('Version is assumed in format x.y.z, ${doctrine.current_version} given');
}
if ('${current_git_branch}' === 'master') {
$parts[1]++;
} else {
$parts[2]++;
}
echo implode('.', $parts);
" />
</exec>
<git-commit file="${project.version_file}" message="Release ${doctrine.current_version}" />
<git-tag version="${doctrine.current_version}" />
<replace file="${project.version_file}" token="${doctrine.current_version}" value="${doctrine.next_version}-DEV" />
<git-commit file="${project.version_file}" message="Bump version to ${doctrine.next_version}" />
</target>
<target name="check-git-checkout-clean">
<exec executable="git" failonerror="true">
<arg value="diff-index" />
<arg value="--quiet" />
<arg value="HEAD" />
</exec>
</target>
<macrodef name="git-commit">
<attribute name="file" default="NOT SET"/>
<attribute name="message" default="NOT SET"/>
<sequential>
<exec executable="git">
<arg value="add" />
<arg value="@{file}" />
</exec>
<exec executable="git">
<arg value="commit" />
<arg value="-m" />
<arg value="@{message}" />
</exec>
</sequential>
</macrodef>
<macrodef name="git-tag">
<attribute name="version" default="NOT SET" />
<sequential>
<exec executable="git">
<arg value="tag" />
<arg value="-m" />
<arg value="v@{version}" />
<arg value="v@{version}" />
</exec>
</sequential>
</macrodef>
</project>

View File

@@ -0,0 +1,37 @@
{
"name": "doctrine/cache",
"type": "library",
"description": "Caching library offering an object-oriented API for many cache backends",
"keywords": ["cache", "caching"],
"homepage": "http://www.doctrine-project.org",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
],
"require": {
"php": "~5.5|~7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8|~5.0",
"satooshi/php-coveralls": "~0.6",
"predis/predis": "~1.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"autoload": {
"psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" }
},
"autoload-dev": {
"psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" }
},
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
}
}

View File

@@ -0,0 +1,118 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* APC cache provider.
*
* @link www.doctrine-project.org
* @deprecated since version 1.6, use ApcuCache instead
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class ApcCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return apc_fetch($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return apc_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return apc_store($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
// apc_delete returns false if the id does not exist
return apc_delete($id) || ! apc_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return apc_clear_cache() && apc_clear_cache('user');
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return apc_fetch($keys) ?: [];
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$result = apc_store($keysAndValues, null, $lifetime);
return empty($result);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = apc_cache_info('', true);
$sma = apc_sma_info();
// @TODO - Temporary fix @see https://github.com/krakjoe/apcu/pull/42
if (PHP_VERSION_ID >= 50500) {
$info['num_hits'] = isset($info['num_hits']) ? $info['num_hits'] : $info['nhits'];
$info['num_misses'] = isset($info['num_misses']) ? $info['num_misses'] : $info['nmisses'];
$info['start_time'] = isset($info['start_time']) ? $info['start_time'] : $info['stime'];
}
return array(
Cache::STATS_HITS => $info['num_hits'],
Cache::STATS_MISSES => $info['num_misses'],
Cache::STATS_UPTIME => $info['start_time'],
Cache::STATS_MEMORY_USAGE => $info['mem_size'],
Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
);
}
}

View File

@@ -0,0 +1,106 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* APCu cache provider.
*
* @link www.doctrine-project.org
* @since 1.6
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class ApcuCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return apcu_fetch($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return apcu_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return apcu_store($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
// apcu_delete returns false if the id does not exist
return apcu_delete($id) || ! apcu_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return apcu_clear_cache();
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return apcu_fetch($keys) ?: [];
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$result = apcu_store($keysAndValues, null, $lifetime);
return empty($result);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = apcu_cache_info(true);
$sma = apcu_sma_info();
return array(
Cache::STATS_HITS => $info['num_hits'],
Cache::STATS_MISSES => $info['num_misses'],
Cache::STATS_UPTIME => $info['start_time'],
Cache::STATS_MEMORY_USAGE => $info['mem_size'],
Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
);
}
}

View File

@@ -0,0 +1,142 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Array cache driver.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class ArrayCache extends CacheProvider
{
/**
* @var array[] $data each element being a tuple of [$data, $expiration], where the expiration is int|bool
*/
private $data = [];
/**
* @var int
*/
private $hitsCount = 0;
/**
* @var int
*/
private $missesCount = 0;
/**
* @var int
*/
private $upTime;
/**
* {@inheritdoc}
*/
public function __construct()
{
$this->upTime = time();
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
if (! $this->doContains($id)) {
$this->missesCount += 1;
return false;
}
$this->hitsCount += 1;
return $this->data[$id][0];
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
if (! isset($this->data[$id])) {
return false;
}
$expiration = $this->data[$id][1];
if ($expiration && $expiration < time()) {
$this->doDelete($id);
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false];
return true;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
unset($this->data[$id]);
return true;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
$this->data = [];
return true;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
return [
Cache::STATS_HITS => $this->hitsCount,
Cache::STATS_MISSES => $this->missesCount,
Cache::STATS_UPTIME => $this->upTime,
Cache::STATS_MEMORY_USAGE => null,
Cache::STATS_MEMORY_AVAILABLE => null,
];
}
}

View File

@@ -0,0 +1,116 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @author Kévin Dunglas <dunglas@gmail.com>
*/
interface Cache
{
const STATS_HITS = 'hits';
const STATS_MISSES = 'misses';
const STATS_UPTIME = 'uptime';
const STATS_MEMORY_USAGE = 'memory_usage';
const STATS_MEMORY_AVAILABLE = 'memory_available';
/**
* Only for backward compatibility (may be removed in next major release)
*
* @deprecated
*/
const STATS_MEMORY_AVAILIABLE = 'memory_available';
/**
* Fetches an entry from the cache.
*
* @param string $id The id of the cache entry to fetch.
*
* @return mixed The cached data or FALSE, if no cache entry exists for the given id.
*/
public function fetch($id);
/**
* Tests if an entry exists in the cache.
*
* @param string $id The cache id of the entry to check for.
*
* @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
*/
public function contains($id);
/**
* Puts data into the cache.
*
* If a cache entry with the given id already exists, its data will be replaced.
*
* @param string $id The cache id.
* @param mixed $data The cache entry/data.
* @param int $lifeTime The lifetime in number of seconds for this cache entry.
* If zero (the default), the entry never expires (although it may be deleted from the cache
* to make place for other entries).
*
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
*/
public function save($id, $data, $lifeTime = 0);
/**
* Deletes a cache entry.
*
* @param string $id The cache id.
*
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
* Deleting a non-existing entry is considered successful.
*/
public function delete($id);
/**
* Retrieves cached information from the data store.
*
* The server's statistics array has the following values:
*
* - <b>hits</b>
* Number of keys that have been requested and found present.
*
* - <b>misses</b>
* Number of items that have been requested and not found.
*
* - <b>uptime</b>
* Time that the server is running.
*
* - <b>memory_usage</b>
* Memory used by this server to store items.
*
* - <b>memory_available</b>
* Memory allowed to use for storage.
*
* @since 2.2
*
* @return array|null An associative array with server's statistics if available, NULL otherwise.
*/
public function getStats();
}

View File

@@ -0,0 +1,312 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Base class for cache provider implementations.
*
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache
{
const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
/**
* The namespace to prefix all cache ids with.
*
* @var string
*/
private $namespace = '';
/**
* The namespace version.
*
* @var integer|null
*/
private $namespaceVersion;
/**
* Sets the namespace to prefix all cache ids with.
*
* @param string $namespace
*
* @return void
*/
public function setNamespace($namespace)
{
$this->namespace = (string) $namespace;
$this->namespaceVersion = null;
}
/**
* Retrieves the namespace that prefixes all cache ids.
*
* @return string
*/
public function getNamespace()
{
return $this->namespace;
}
/**
* {@inheritdoc}
*/
public function fetch($id)
{
return $this->doFetch($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function fetchMultiple(array $keys)
{
if (empty($keys)) {
return array();
}
// note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
$namespacedKeys = array_combine($keys, array_map(array($this, 'getNamespacedId'), $keys));
$items = $this->doFetchMultiple($namespacedKeys);
$foundItems = array();
// no internal array function supports this sort of mapping: needs to be iterative
// this filters and combines keys in one pass
foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) {
$foundItems[$requestedKey] = $items[$namespacedKey];
}
}
return $foundItems;
}
/**
* {@inheritdoc}
*/
public function saveMultiple(array $keysAndValues, $lifetime = 0)
{
$namespacedKeysAndValues = array();
foreach ($keysAndValues as $key => $value) {
$namespacedKeysAndValues[$this->getNamespacedId($key)] = $value;
}
return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime);
}
/**
* {@inheritdoc}
*/
public function contains($id)
{
return $this->doContains($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function save($id, $data, $lifeTime = 0)
{
return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
public function delete($id)
{
return $this->doDelete($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function getStats()
{
return $this->doGetStats();
}
/**
* {@inheritDoc}
*/
public function flushAll()
{
return $this->doFlush();
}
/**
* {@inheritDoc}
*/
public function deleteAll()
{
$namespaceCacheKey = $this->getNamespaceCacheKey();
$namespaceVersion = $this->getNamespaceVersion() + 1;
if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
$this->namespaceVersion = $namespaceVersion;
return true;
}
return false;
}
/**
* Prefixes the passed id with the configured namespace value.
*
* @param string $id The id to namespace.
*
* @return string The namespaced id.
*/
private function getNamespacedId($id)
{
$namespaceVersion = $this->getNamespaceVersion();
return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
}
/**
* Returns the namespace cache key.
*
* @return string
*/
private function getNamespaceCacheKey()
{
return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
}
/**
* Returns the namespace version.
*
* @return integer
*/
private function getNamespaceVersion()
{
if (null !== $this->namespaceVersion) {
return $this->namespaceVersion;
}
$namespaceCacheKey = $this->getNamespaceCacheKey();
$this->namespaceVersion = $this->doFetch($namespaceCacheKey) ?: 1;
return $this->namespaceVersion;
}
/**
* Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
*
* @param array $keys Array of keys to retrieve from cache
* @return array Array of values retrieved for the given keys.
*/
protected function doFetchMultiple(array $keys)
{
$returnValues = array();
foreach ($keys as $key) {
if (false !== ($item = $this->doFetch($key)) || $this->doContains($key)) {
$returnValues[$key] = $item;
}
}
return $returnValues;
}
/**
* Fetches an entry from the cache.
*
* @param string $id The id of the cache entry to fetch.
*
* @return mixed|false The cached data or FALSE, if no cache entry exists for the given id.
*/
abstract protected function doFetch($id);
/**
* Tests if an entry exists in the cache.
*
* @param string $id The cache id of the entry to check for.
*
* @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
*/
abstract protected function doContains($id);
/**
* Default implementation of doSaveMultiple. Each driver that supports multi-put should override it.
*
* @param array $keysAndValues Array of keys and values to save in cache
* @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
* cache entries (0 => infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$success = true;
foreach ($keysAndValues as $key => $value) {
if (!$this->doSave($key, $value, $lifetime)) {
$success = false;
}
}
return $success;
}
/**
* Puts data into the cache.
*
* @param string $id The cache id.
* @param string $data The cache entry/data.
* @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this
* cache entry (0 => infinite lifeTime).
*
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
*/
abstract protected function doSave($id, $data, $lifeTime = 0);
/**
* Deletes a cache entry.
*
* @param string $id The cache id.
*
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
*/
abstract protected function doDelete($id);
/**
* Flushes all cache entries.
*
* @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
*/
abstract protected function doFlush();
/**
* Retrieves cached information from the data store.
*
* @since 2.2
*
* @return array|null An associative array with server's statistics if available, NULL otherwise.
*/
abstract protected function doGetStats();
}

View File

@@ -0,0 +1,147 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Cache provider that allows to easily chain multiple cache providers
*
* @author Michaël Gallego <mic.gallego@gmail.com>
*/
class ChainCache extends CacheProvider
{
/**
* @var CacheProvider[]
*/
private $cacheProviders = array();
/**
* Constructor
*
* @param CacheProvider[] $cacheProviders
*/
public function __construct($cacheProviders = array())
{
$this->cacheProviders = $cacheProviders;
}
/**
* {@inheritDoc}
*/
public function setNamespace($namespace)
{
parent::setNamespace($namespace);
foreach ($this->cacheProviders as $cacheProvider) {
$cacheProvider->setNamespace($namespace);
}
}
/**
* {@inheritDoc}
*/
protected function doFetch($id)
{
foreach ($this->cacheProviders as $key => $cacheProvider) {
if ($cacheProvider->doContains($id)) {
$value = $cacheProvider->doFetch($id);
// We populate all the previous cache layers (that are assumed to be faster)
for ($subKey = $key - 1 ; $subKey >= 0 ; $subKey--) {
$this->cacheProviders[$subKey]->doSave($id, $value);
}
return $value;
}
}
return false;
}
/**
* {@inheritDoc}
*/
protected function doContains($id)
{
foreach ($this->cacheProviders as $cacheProvider) {
if ($cacheProvider->doContains($id)) {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$stored = true;
foreach ($this->cacheProviders as $cacheProvider) {
$stored = $cacheProvider->doSave($id, $data, $lifeTime) && $stored;
}
return $stored;
}
/**
* {@inheritDoc}
*/
protected function doDelete($id)
{
$deleted = true;
foreach ($this->cacheProviders as $cacheProvider) {
$deleted = $cacheProvider->doDelete($id) && $deleted;
}
return $deleted;
}
/**
* {@inheritDoc}
*/
protected function doFlush()
{
$flushed = true;
foreach ($this->cacheProviders as $cacheProvider) {
$flushed = $cacheProvider->doFlush() && $flushed;
}
return $flushed;
}
/**
* {@inheritDoc}
*/
protected function doGetStats()
{
// We return all the stats from all adapters
$stats = array();
foreach ($this->cacheProviders as $cacheProvider) {
$stats[] = $cacheProvider->doGetStats();
}
return $stats;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache that can be flushed.
*
* Intended to be used for partial clearing of a cache namespace. For a more
* global "flushing", see {@see FlushableCache}.
*
* @link www.doctrine-project.org
* @since 1.4
* @author Adirelle <adirelle@gmail.com>
*/
interface ClearableCache
{
/**
* Deletes all cache entries in the current cache namespace.
*
* @return bool TRUE if the cache entries were successfully deleted, FALSE otherwise.
*/
public function deleteAll();
}

View File

@@ -0,0 +1,121 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use \Couchbase;
/**
* Couchbase cache provider.
*
* @link www.doctrine-project.org
* @since 2.4
* @author Michael Nitschinger <michael@nitschinger.at>
*/
class CouchbaseCache extends CacheProvider
{
/**
* @var Couchbase|null
*/
private $couchbase;
/**
* Sets the Couchbase instance to use.
*
* @param Couchbase $couchbase
*
* @return void
*/
public function setCouchbase(Couchbase $couchbase)
{
$this->couchbase = $couchbase;
}
/**
* Gets the Couchbase instance used by the cache.
*
* @return Couchbase|null
*/
public function getCouchbase()
{
return $this->couchbase;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->couchbase->get($id) ?: false;
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return (null !== $this->couchbase->get($id));
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 30 * 24 * 3600) {
$lifeTime = time() + $lifeTime;
}
return $this->couchbase->set($id, $data, (int) $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return $this->couchbase->delete($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->couchbase->flush();
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$stats = $this->couchbase->getStats();
$servers = $this->couchbase->getServers();
$server = explode(":", $servers[0]);
$key = $server[0] . ":" . "11210";
$stats = $stats[$key];
return array(
Cache::STATS_HITS => $stats['get_hits'],
Cache::STATS_MISSES => $stats['get_misses'],
Cache::STATS_UPTIME => $stats['uptime'],
Cache::STATS_MEMORY_USAGE => $stats['bytes'],
Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
);
}
}

View File

@@ -0,0 +1,286 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Base file cache driver.
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @author Tobias Schultze <http://tobion.de>
*/
abstract class FileCache extends CacheProvider
{
/**
* The cache directory.
*
* @var string
*/
protected $directory;
/**
* The cache file extension.
*
* @var string
*/
private $extension;
/**
* @var int
*/
private $umask;
/**
* @var int
*/
private $directoryStringLength;
/**
* @var int
*/
private $extensionStringLength;
/**
* @var bool
*/
private $isRunningOnWindows;
/**
* Constructor.
*
* @param string $directory The cache directory.
* @param string $extension The cache file extension.
*
* @throws \InvalidArgumentException
*/
public function __construct($directory, $extension = '', $umask = 0002)
{
// YES, this needs to be *before* createPathIfNeeded()
if ( ! is_int($umask)) {
throw new \InvalidArgumentException(sprintf(
'The umask parameter is required to be integer, was: %s',
gettype($umask)
));
}
$this->umask = $umask;
if ( ! $this->createPathIfNeeded($directory)) {
throw new \InvalidArgumentException(sprintf(
'The directory "%s" does not exist and could not be created.',
$directory
));
}
if ( ! is_writable($directory)) {
throw new \InvalidArgumentException(sprintf(
'The directory "%s" is not writable.',
$directory
));
}
// YES, this needs to be *after* createPathIfNeeded()
$this->directory = realpath($directory);
$this->extension = (string) $extension;
$this->directoryStringLength = strlen($this->directory);
$this->extensionStringLength = strlen($this->extension);
$this->isRunningOnWindows = defined('PHP_WINDOWS_VERSION_BUILD');
}
/**
* Gets the cache directory.
*
* @return string
*/
public function getDirectory()
{
return $this->directory;
}
/**
* Gets the cache file extension.
*
* @return string
*/
public function getExtension()
{
return $this->extension;
}
/**
* @param string $id
*
* @return string
*/
protected function getFilename($id)
{
$hash = hash('sha256', $id);
// This ensures that the filename is unique and that there are no invalid chars in it.
if (
'' === $id
|| ((strlen($id) * 2 + $this->extensionStringLength) > 255)
|| ($this->isRunningOnWindows && ($this->directoryStringLength + 4 + strlen($id) * 2 + $this->extensionStringLength) > 258)
) {
// Most filesystems have a limit of 255 chars for each path component. On Windows the the whole path is limited
// to 260 chars (including terminating null char). Using long UNC ("\\?\" prefix) does not work with the PHP API.
// And there is a bug in PHP (https://bugs.php.net/bug.php?id=70943) with path lengths of 259.
// So if the id in hex representation would surpass the limit, we use the hash instead. The prefix prevents
// collisions between the hash and bin2hex.
$filename = '_' . $hash;
} else {
$filename = bin2hex($id);
}
return $this->directory
. DIRECTORY_SEPARATOR
. substr($hash, 0, 2)
. DIRECTORY_SEPARATOR
. $filename
. $this->extension;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
$filename = $this->getFilename($id);
return @unlink($filename) || ! file_exists($filename);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
foreach ($this->getIterator() as $name => $file) {
if ($file->isDir()) {
// Remove the intermediate directories which have been created to balance the tree. It only takes effect
// if the directory is empty. If several caches share the same directory but with different file extensions,
// the other ones are not removed.
@rmdir($name);
} elseif ($this->isFilenameEndingWithExtension($name)) {
// If an extension is set, only remove files which end with the given extension.
// If no extension is set, we have no other choice than removing everything.
@unlink($name);
}
}
return true;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$usage = 0;
foreach ($this->getIterator() as $name => $file) {
if (! $file->isDir() && $this->isFilenameEndingWithExtension($name)) {
$usage += $file->getSize();
}
}
$free = disk_free_space($this->directory);
return array(
Cache::STATS_HITS => null,
Cache::STATS_MISSES => null,
Cache::STATS_UPTIME => null,
Cache::STATS_MEMORY_USAGE => $usage,
Cache::STATS_MEMORY_AVAILABLE => $free,
);
}
/**
* Create path if needed.
*
* @param string $path
* @return bool TRUE on success or if path already exists, FALSE if path cannot be created.
*/
private function createPathIfNeeded($path)
{
if ( ! is_dir($path)) {
if (false === @mkdir($path, 0777 & (~$this->umask), true) && !is_dir($path)) {
return false;
}
}
return true;
}
/**
* Writes a string content to file in an atomic way.
*
* @param string $filename Path to the file where to write the data.
* @param string $content The content to write
*
* @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error.
*/
protected function writeFile($filename, $content)
{
$filepath = pathinfo($filename, PATHINFO_DIRNAME);
if ( ! $this->createPathIfNeeded($filepath)) {
return false;
}
if ( ! is_writable($filepath)) {
return false;
}
$tmpFile = tempnam($filepath, 'swap');
@chmod($tmpFile, 0666 & (~$this->umask));
if (file_put_contents($tmpFile, $content) !== false) {
if (@rename($tmpFile, $filename)) {
return true;
}
@unlink($tmpFile);
}
return false;
}
/**
* @return \Iterator
*/
private function getIterator()
{
return new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST
);
}
/**
* @param string $name The filename
*
* @return bool
*/
private function isFilenameEndingWithExtension($name)
{
return '' === $this->extension
|| strrpos($name, $this->extension) === (strlen($name) - $this->extensionStringLength);
}
}

View File

@@ -0,0 +1,111 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Filesystem cache driver.
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class FilesystemCache extends FileCache
{
const EXTENSION = '.doctrinecache.data';
/**
* {@inheritdoc}
*/
public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
{
parent::__construct($directory, $extension, $umask);
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$data = '';
$lifetime = -1;
$filename = $this->getFilename($id);
if ( ! is_file($filename)) {
return false;
}
$resource = fopen($filename, "r");
if (false !== ($line = fgets($resource))) {
$lifetime = (int) $line;
}
if ($lifetime !== 0 && $lifetime < time()) {
fclose($resource);
return false;
}
while (false !== ($line = fgets($resource))) {
$data .= $line;
}
fclose($resource);
return unserialize($data);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$lifetime = -1;
$filename = $this->getFilename($id);
if ( ! is_file($filename)) {
return false;
}
$resource = fopen($filename, "r");
if (false !== ($line = fgets($resource))) {
$lifetime = (int) $line;
}
fclose($resource);
return $lifetime === 0 || $lifetime > time();
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 0) {
$lifeTime = time() + $lifeTime;
}
$data = serialize($data);
$filename = $this->getFilename($id);
return $this->writeFile($filename, $lifeTime . PHP_EOL . $data);
}
}

View File

@@ -0,0 +1,37 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache that can be flushed.
*
* @link www.doctrine-project.org
* @since 1.4
* @author Adirelle <adirelle@gmail.com>
*/
interface FlushableCache
{
/**
* Flushes all cache entries, globally.
*
* @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
*/
public function flushAll();
}

View File

@@ -0,0 +1,126 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use \Memcache;
/**
* Memcache cache provider.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class MemcacheCache extends CacheProvider
{
/**
* @var Memcache|null
*/
private $memcache;
/**
* Sets the memcache instance to use.
*
* @param Memcache $memcache
*
* @return void
*/
public function setMemcache(Memcache $memcache)
{
$this->memcache = $memcache;
}
/**
* Gets the memcache instance used by the cache.
*
* @return Memcache|null
*/
public function getMemcache()
{
return $this->memcache;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->memcache->get($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$flags = null;
$this->memcache->get($id, $flags);
//if memcache has changed the value of "flags", it means the value exists
return ($flags !== null);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 30 * 24 * 3600) {
$lifeTime = time() + $lifeTime;
}
return $this->memcache->set($id, $data, 0, (int) $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
// Memcache::delete() returns false if entry does not exist
return $this->memcache->delete($id) || ! $this->doContains($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->memcache->flush();
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$stats = $this->memcache->getStats();
return array(
Cache::STATS_HITS => $stats['get_hits'],
Cache::STATS_MISSES => $stats['get_misses'],
Cache::STATS_UPTIME => $stats['uptime'],
Cache::STATS_MEMORY_USAGE => $stats['bytes'],
Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
);
}
}

View File

@@ -0,0 +1,147 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use \Memcached;
/**
* Memcached cache provider.
*
* @link www.doctrine-project.org
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class MemcachedCache extends CacheProvider
{
/**
* @var Memcached|null
*/
private $memcached;
/**
* Sets the memcache instance to use.
*
* @param Memcached $memcached
*
* @return void
*/
public function setMemcached(Memcached $memcached)
{
$this->memcached = $memcached;
}
/**
* Gets the memcached instance used by the cache.
*
* @return Memcached|null
*/
public function getMemcached()
{
return $this->memcached;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->memcached->get($id);
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return $this->memcached->getMulti($keys) ?: [];
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
if ($lifetime > 30 * 24 * 3600) {
$lifetime = time() + $lifetime;
}
return $this->memcached->setMulti($keysAndValues, $lifetime);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$this->memcached->get($id);
return $this->memcached->getResultCode() === Memcached::RES_SUCCESS;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 30 * 24 * 3600) {
$lifeTime = time() + $lifeTime;
}
return $this->memcached->set($id, $data, (int) $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return $this->memcached->delete($id)
|| $this->memcached->getResultCode() === Memcached::RES_NOTFOUND;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->memcached->flush();
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$stats = $this->memcached->getStats();
$servers = $this->memcached->getServerList();
$key = $servers[0]['host'] . ':' . $servers[0]['port'];
$stats = $stats[$key];
return array(
Cache::STATS_HITS => $stats['get_hits'],
Cache::STATS_MISSES => $stats['get_misses'],
Cache::STATS_UPTIME => $stats['uptime'],
Cache::STATS_MEMORY_USAGE => $stats['bytes'],
Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
);
}
}

View File

@@ -0,0 +1,197 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use MongoBinData;
use MongoCollection;
use MongoCursorException;
use MongoDate;
/**
* MongoDB cache provider.
*
* @since 1.1
* @author Jeremy Mikola <jmikola@gmail.com>
*/
class MongoDBCache extends CacheProvider
{
/**
* The data field will store the serialized PHP value.
*/
const DATA_FIELD = 'd';
/**
* The expiration field will store a MongoDate value indicating when the
* cache entry should expire.
*
* With MongoDB 2.2+, entries can be automatically deleted by MongoDB by
* indexing this field with the "expireAfterSeconds" option equal to zero.
* This will direct MongoDB to regularly query for and delete any entries
* whose date is older than the current time. Entries without a date value
* in this field will be ignored.
*
* The cache provider will also check dates on its own, in case expired
* entries are fetched before MongoDB's TTLMonitor pass can expire them.
*
* @see http://docs.mongodb.org/manual/tutorial/expire-data/
*/
const EXPIRATION_FIELD = 'e';
/**
* @var MongoCollection
*/
private $collection;
/**
* Constructor.
*
* This provider will default to the write concern and read preference
* options set on the MongoCollection instance (or inherited from MongoDB or
* MongoClient). Using an unacknowledged write concern (< 1) may make the
* return values of delete() and save() unreliable. Reading from secondaries
* may make contain() and fetch() unreliable.
*
* @see http://www.php.net/manual/en/mongo.readpreferences.php
* @see http://www.php.net/manual/en/mongo.writeconcerns.php
* @param MongoCollection $collection
*/
public function __construct(MongoCollection $collection)
{
$this->collection = $collection;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$document = $this->collection->findOne(array('_id' => $id), array(self::DATA_FIELD, self::EXPIRATION_FIELD));
if ($document === null) {
return false;
}
if ($this->isExpired($document)) {
$this->doDelete($id);
return false;
}
return unserialize($document[self::DATA_FIELD]->bin);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$document = $this->collection->findOne(array('_id' => $id), array(self::EXPIRATION_FIELD));
if ($document === null) {
return false;
}
if ($this->isExpired($document)) {
$this->doDelete($id);
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
try {
$result = $this->collection->update(
array('_id' => $id),
array('$set' => array(
self::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null),
self::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY),
)),
array('upsert' => true, 'multiple' => false)
);
} catch (MongoCursorException $e) {
return false;
}
return isset($result['ok']) ? $result['ok'] == 1 : true;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
$result = $this->collection->remove(array('_id' => $id));
return isset($result['ok']) ? $result['ok'] == 1 : true;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
// Use remove() in lieu of drop() to maintain any collection indexes
$result = $this->collection->remove();
return isset($result['ok']) ? $result['ok'] == 1 : true;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$serverStatus = $this->collection->db->command(array(
'serverStatus' => 1,
'locks' => 0,
'metrics' => 0,
'recordStats' => 0,
'repl' => 0,
));
$collStats = $this->collection->db->command(array('collStats' => 1));
return array(
Cache::STATS_HITS => null,
Cache::STATS_MISSES => null,
Cache::STATS_UPTIME => (isset($serverStatus['uptime']) ? (int) $serverStatus['uptime'] : null),
Cache::STATS_MEMORY_USAGE => (isset($collStats['size']) ? (int) $collStats['size'] : null),
Cache::STATS_MEMORY_AVAILABLE => null,
);
}
/**
* Check if the document is expired.
*
* @param array $document
*
* @return bool
*/
private function isExpired(array $document)
{
return isset($document[self::EXPIRATION_FIELD]) &&
$document[self::EXPIRATION_FIELD] instanceof MongoDate &&
$document[self::EXPIRATION_FIELD]->sec < time();
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers that allows to get many items at once.
*
* @link www.doctrine-project.org
* @since 1.4
* @author Asmir Mustafic <goetas@gmail.com>
*/
interface MultiGetCache
{
/**
* Returns an associative array of values for keys is found in cache.
*
* @param string[] $keys Array of keys to retrieve from cache
* @return mixed[] Array of retrieved values, indexed by the specified keys.
* Values that couldn't be retrieved are not contained in this array.
*/
function fetchMultiple(array $keys);
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers that allows to put many items at once.
*
* @link www.doctrine-project.org
* @since 1.6
* @author Daniel Gorgan <danut007ro@gmail.com>
*/
interface MultiPutCache
{
/**
* Returns a boolean value indicating if the operation succeeded.
*
* @param array $keysAndValues Array of keys and values to save in cache
* @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
* cache entries (0 => infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
function saveMultiple(array $keysAndValues, $lifetime = 0);
}

View File

@@ -0,0 +1,120 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Php file cache driver.
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class PhpFileCache extends FileCache
{
const EXTENSION = '.doctrinecache.php';
/**
* {@inheritdoc}
*/
public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
{
parent::__construct($directory, $extension, $umask);
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$value = $this->includeFileForId($id);
if (! $value) {
return false;
}
if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) {
return false;
}
return $value['data'];
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$value = $this->includeFileForId($id);
if (! $value) {
return false;
}
return $value['lifetime'] === 0 || $value['lifetime'] > time();
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 0) {
$lifeTime = time() + $lifeTime;
}
if (is_object($data) && ! method_exists($data, '__set_state')) {
throw new \InvalidArgumentException(
"Invalid argument given, PhpFileCache only allows objects that implement __set_state() " .
"and fully support var_export(). You can use the FilesystemCache to save arbitrary object " .
"graphs using serialize()/deserialize()."
);
}
$filename = $this->getFilename($id);
$value = array(
'lifetime' => $lifeTime,
'data' => $data
);
$value = var_export($value, true);
$code = sprintf('<?php return %s;', $value);
return $this->writeFile($filename, $code);
}
/**
* @param string $id
*
* @return array|false
*/
private function includeFileForId($id)
{
$fileName = $this->getFilename($id);
// note: error suppression is still faster than `file_exists`, `is_file` and `is_readable`
$value = @include $fileName;
if (! isset($value['lifetime'])) {
return false;
}
return $value;
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace Doctrine\Common\Cache;
use Predis\ClientInterface;
/**
* Predis cache provider.
*
* @author othillo <othillo@othillo.nl>
*/
class PredisCache extends CacheProvider
{
/**
* @var ClientInterface
*/
private $client;
/**
* @param ClientInterface $client
*
* @return void
*/
public function __construct(ClientInterface $client)
{
$this->client = $client;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$result = $this->client->get($id);
if (null === $result) {
return false;
}
return unserialize($result);
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
$fetchedItems = call_user_func_array(array($this->client, 'mget'), $keys);
return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems)));
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
if ($lifetime) {
$success = true;
// Keys have lifetime, use SETEX for each of them
foreach ($keysAndValues as $key => $value) {
$response = $this->client->setex($key, $lifetime, serialize($value));
if ((string) $response != 'OK') {
$success = false;
}
}
return $success;
}
// No lifetime, use MSET
$response = $this->client->mset(array_map(function ($value) {
return serialize($value);
}, $keysAndValues));
return (string) $response == 'OK';
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return (bool) $this->client->exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$data = serialize($data);
if ($lifeTime > 0) {
$response = $this->client->setex($id, $lifeTime, $data);
} else {
$response = $this->client->set($id, $data);
}
return $response === true || $response == 'OK';
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return $this->client->del($id) >= 0;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
$response = $this->client->flushdb();
return $response === true || $response == 'OK';
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = $this->client->info();
return array(
Cache::STATS_HITS => $info['Stats']['keyspace_hits'],
Cache::STATS_MISSES => $info['Stats']['keyspace_misses'],
Cache::STATS_UPTIME => $info['Server']['uptime_in_seconds'],
Cache::STATS_MEMORY_USAGE => $info['Memory']['used_memory'],
Cache::STATS_MEMORY_AVAILABLE => false
);
}
}

View File

@@ -0,0 +1,180 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use Redis;
/**
* Redis cache provider.
*
* @link www.doctrine-project.org
* @since 2.2
* @author Osman Ungur <osmanungur@gmail.com>
*/
class RedisCache extends CacheProvider
{
/**
* @var Redis|null
*/
private $redis;
/**
* Sets the redis instance to use.
*
* @param Redis $redis
*
* @return void
*/
public function setRedis(Redis $redis)
{
$redis->setOption(Redis::OPT_SERIALIZER, $this->getSerializerValue());
$this->redis = $redis;
}
/**
* Gets the redis instance used by the cache.
*
* @return Redis|null
*/
public function getRedis()
{
return $this->redis;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->redis->get($id);
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
$fetchedItems = array_combine($keys, $this->redis->mget($keys));
// Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data.
$foundItems = array();
foreach ($fetchedItems as $key => $value) {
if (false !== $value || $this->redis->exists($key)) {
$foundItems[$key] = $value;
}
}
return $foundItems;
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
if ($lifetime) {
$success = true;
// Keys have lifetime, use SETEX for each of them
foreach ($keysAndValues as $key => $value) {
if (!$this->redis->setex($key, $lifetime, $value)) {
$success = false;
}
}
return $success;
}
// No lifetime, use MSET
return (bool) $this->redis->mset($keysAndValues);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return $this->redis->exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 0) {
return $this->redis->setex($id, $lifeTime, $data);
}
return $this->redis->set($id, $data);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return $this->redis->delete($id) >= 0;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->redis->flushDB();
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = $this->redis->info();
return array(
Cache::STATS_HITS => $info['keyspace_hits'],
Cache::STATS_MISSES => $info['keyspace_misses'],
Cache::STATS_UPTIME => $info['uptime_in_seconds'],
Cache::STATS_MEMORY_USAGE => $info['used_memory'],
Cache::STATS_MEMORY_AVAILABLE => false
);
}
/**
* Returns the serializer constant to use. If Redis is compiled with
* igbinary support, that is used. Otherwise the default PHP serializer is
* used.
*
* @return integer One of the Redis::SERIALIZER_* constants
*/
protected function getSerializerValue()
{
if (defined('HHVM_VERSION')) {
return Redis::SERIALIZER_PHP;
}
if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) {
return Redis::SERIALIZER_IGBINARY;
}
return Redis::SERIALIZER_PHP;
}
}

View File

@@ -0,0 +1,250 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use Riak\Bucket;
use Riak\Connection;
use Riak\Input;
use Riak\Exception;
use Riak\Object;
/**
* Riak cache provider.
*
* @link www.doctrine-project.org
* @since 1.1
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class RiakCache extends CacheProvider
{
const EXPIRES_HEADER = 'X-Riak-Meta-Expires';
/**
* @var \Riak\Bucket
*/
private $bucket;
/**
* Sets the riak bucket instance to use.
*
* @param \Riak\Bucket $bucket
*/
public function __construct(Bucket $bucket)
{
$this->bucket = $bucket;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
try {
$response = $this->bucket->get($id);
// No objects found
if ( ! $response->hasObject()) {
return false;
}
// Check for attempted siblings
$object = ($response->hasSiblings())
? $this->resolveConflict($id, $response->getVClock(), $response->getObjectList())
: $response->getFirstObject();
// Check for expired object
if ($this->isExpired($object)) {
$this->bucket->delete($object);
return false;
}
return unserialize($object->getContent());
} catch (Exception\RiakException $e) {
// Covers:
// - Riak\ConnectionException
// - Riak\CommunicationException
// - Riak\UnexpectedResponseException
// - Riak\NotFoundException
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
try {
// We only need the HEAD, not the entire object
$input = new Input\GetInput();
$input->setReturnHead(true);
$response = $this->bucket->get($id, $input);
// No objects found
if ( ! $response->hasObject()) {
return false;
}
$object = $response->getFirstObject();
// Check for expired object
if ($this->isExpired($object)) {
$this->bucket->delete($object);
return false;
}
return true;
} catch (Exception\RiakException $e) {
// Do nothing
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
try {
$object = new Object($id);
$object->setContent(serialize($data));
if ($lifeTime > 0) {
$object->addMetadata(self::EXPIRES_HEADER, (string) (time() + $lifeTime));
}
$this->bucket->put($object);
return true;
} catch (Exception\RiakException $e) {
// Do nothing
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
try {
$this->bucket->delete($id);
return true;
} catch (Exception\BadArgumentsException $e) {
// Key did not exist on cluster already
} catch (Exception\RiakException $e) {
// Covers:
// - Riak\Exception\ConnectionException
// - Riak\Exception\CommunicationException
// - Riak\Exception\UnexpectedResponseException
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
try {
$keyList = $this->bucket->getKeyList();
foreach ($keyList as $key) {
$this->bucket->delete($key);
}
return true;
} catch (Exception\RiakException $e) {
// Do nothing
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
// Only exposed through HTTP stats API, not Protocol Buffers API
return null;
}
/**
* Check if a given Riak Object have expired.
*
* @param \Riak\Object $object
*
* @return bool
*/
private function isExpired(Object $object)
{
$metadataMap = $object->getMetadataMap();
return isset($metadataMap[self::EXPIRES_HEADER])
&& $metadataMap[self::EXPIRES_HEADER] < time();
}
/**
* On-read conflict resolution. Applied approach here is last write wins.
* Specific needs may override this method to apply alternate conflict resolutions.
*
* {@internal Riak does not attempt to resolve a write conflict, and store
* it as sibling of conflicted one. By following this approach, it is up to
* the next read to resolve the conflict. When this happens, your fetched
* object will have a list of siblings (read as a list of objects).
* In our specific case, we do not care about the intermediate ones since
* they are all the same read from storage, and we do apply a last sibling
* (last write) wins logic.
* If by any means our resolution generates another conflict, it'll up to
* next read to properly solve it.}
*
* @param string $id
* @param string $vClock
* @param array $objectList
*
* @return \Riak\Object
*/
protected function resolveConflict($id, $vClock, array $objectList)
{
// Our approach here is last-write wins
$winner = $objectList[count($objectList)];
$putInput = new Input\PutInput();
$putInput->setVClock($vClock);
$mergedObject = new Object($id);
$mergedObject->setContent($winner->getContent());
$this->bucket->put($mergedObject, $putInput);
return $mergedObject;
}
}

View File

@@ -0,0 +1,220 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use SQLite3;
use SQLite3Result;
/**
* SQLite3 cache provider.
*
* @since 1.4
* @author Jake Bell <jake@theunraveler.com>
*/
class SQLite3Cache extends CacheProvider
{
/**
* The ID field will store the cache key.
*/
const ID_FIELD = 'k';
/**
* The data field will store the serialized PHP value.
*/
const DATA_FIELD = 'd';
/**
* The expiration field will store a date value indicating when the
* cache entry should expire.
*/
const EXPIRATION_FIELD = 'e';
/**
* @var SQLite3
*/
private $sqlite;
/**
* @var string
*/
private $table;
/**
* Constructor.
*
* Calling the constructor will ensure that the database file and table
* exist and will create both if they don't.
*
* @param SQLite3 $sqlite
* @param string $table
*/
public function __construct(SQLite3 $sqlite, $table)
{
$this->sqlite = $sqlite;
$this->table = (string) $table;
list($id, $data, $exp) = $this->getFields();
return $this->sqlite->exec(sprintf(
'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)',
$table,
$id,
$data,
$exp
));
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
if ($item = $this->findById($id)) {
return unserialize($item[self::DATA_FIELD]);
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return null !== $this->findById($id, false);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$statement = $this->sqlite->prepare(sprintf(
'INSERT OR REPLACE INTO %s (%s) VALUES (:id, :data, :expire)',
$this->table,
implode(',', $this->getFields())
));
$statement->bindValue(':id', $id);
$statement->bindValue(':data', serialize($data), SQLITE3_BLOB);
$statement->bindValue(':expire', $lifeTime > 0 ? time() + $lifeTime : null);
return $statement->execute() instanceof SQLite3Result;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
list($idField) = $this->getFields();
$statement = $this->sqlite->prepare(sprintf(
'DELETE FROM %s WHERE %s = :id',
$this->table,
$idField
));
$statement->bindValue(':id', $id);
return $statement->execute() instanceof SQLite3Result;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->sqlite->exec(sprintf('DELETE FROM %s', $this->table));
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
// no-op.
}
/**
* Find a single row by ID.
*
* @param mixed $id
* @param bool $includeData
*
* @return array|null
*/
private function findById($id, $includeData = true)
{
list($idField) = $fields = $this->getFields();
if (!$includeData) {
$key = array_search(static::DATA_FIELD, $fields);
unset($fields[$key]);
}
$statement = $this->sqlite->prepare(sprintf(
'SELECT %s FROM %s WHERE %s = :id LIMIT 1',
implode(',', $fields),
$this->table,
$idField
));
$statement->bindValue(':id', $id, SQLITE3_TEXT);
$item = $statement->execute()->fetchArray(SQLITE3_ASSOC);
if ($item === false) {
return null;
}
if ($this->isExpired($item)) {
$this->doDelete($id);
return null;
}
return $item;
}
/**
* Gets an array of the fields in our table.
*
* @return array
*/
private function getFields()
{
return array(static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD);
}
/**
* Check if the item is expired.
*
* @param array $item
*
* @return bool
*/
private function isExpired(array $item)
{
return isset($item[static::EXPIRATION_FIELD]) &&
$item[self::EXPIRATION_FIELD] !== null &&
$item[self::EXPIRATION_FIELD] < time();
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
class Version
{
const VERSION = '1.6.1-DEV';
}

View File

@@ -0,0 +1,78 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Void cache driver. The cache could be of use in tests where you don`t need to cache anything.
*
* @link www.doctrine-project.org
* @since 1.5
* @author Kotlyar Maksim <kotlyar.maksim@gmail.com>
*/
class VoidCache extends CacheProvider
{
/**
* {@inheritDoc}
*/
protected function doFetch($id)
{
return false;
}
/**
* {@inheritDoc}
*/
protected function doContains($id)
{
return false;
}
/**
* {@inheritDoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return true;
}
/**
* {@inheritDoc}
*/
protected function doDelete($id)
{
return true;
}
/**
* {@inheritDoc}
*/
protected function doFlush()
{
return true;
}
/**
* {@inheritDoc}
*/
protected function doGetStats()
{
return;
}
}

View File

@@ -0,0 +1,109 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* WinCache cache provider.
*
* @link www.doctrine-project.org
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class WinCacheCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return wincache_ucache_get($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return wincache_ucache_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return wincache_ucache_set($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return wincache_ucache_delete($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return wincache_ucache_clear();
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return wincache_ucache_get($keys);
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$result = wincache_ucache_set($keysAndValues, null, $lifetime);
return empty($result);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = wincache_ucache_info();
$meminfo = wincache_ucache_meminfo();
return array(
Cache::STATS_HITS => $info['total_hit_count'],
Cache::STATS_MISSES => $info['total_miss_count'],
Cache::STATS_UPTIME => $info['total_cache_uptime'],
Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'],
Cache::STATS_MEMORY_AVAILABLE => $meminfo['memory_free'],
);
}
}

Some files were not shown because too many files have changed in this diff Show More