diff --git a/CHANGELOG.md b/CHANGELOG.md index 4658c20f..e1945234 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## Changelog +* 2.0.6 - 2016.12.2: + * Fix: Do not allow to add external products to cart. + * Fix: Fix external product url. + * Fix: Checkout fields validation. + * Fix: Checkout registration. + * Fix: Remove usage of `price` meta from purchasable products. + * Fix: Properly handle account creation errors on checkout. * 2.0.5 - 2016.11.24: * Fix: Updating customer on checkout page. * Fix: Removed unnecessary filter. diff --git a/jigoshop.php b/jigoshop.php index 1426959f..36397be6 100755 --- a/jigoshop.php +++ b/jigoshop.php @@ -20,7 +20,7 @@ * Description: Jigoshop, a WordPress eCommerce plugin that works. * Author: Jigoshop * Author URI: http://www.jigoshop.com - * Version: 2.0.5 + * Version: 2.0.6 * Requires at least: 4.0 * Tested up to: 4.6.1 * Text Domain: jigoshop diff --git a/readme.txt b/readme.txt index 9d81c061..5edfd9b8 100755 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i Requires at least: 4.0 Tested up to: 4.6.1 -Stable tag: 2.0.4.1 +Stable tag: 2.0.6 A feature-packed eCommerce plugin built upon WordPress core functionality ensuring excellent performance and customizability. @@ -104,6 +104,13 @@ However, if you want priority, dedicated support from Jigoshop staff, we dp offe == Changelog == += 2.0.6 - 2016.12.2 = +* Fix: Do not allow to add external products to cart. +* Fix: Fix external product url. +* Fix: Checkout fields validation. +* Fix: Checkout registration. +* Fix: Remove usage of `price` meta from purchasable products. +* Fix: Properly handle account creation errors on checkout. = 2.0.5 - 2016.11.24 = * Fix: Updating customer on checkout page. * Fix: Removed unnecessary filter. diff --git a/src/Jigoshop/Core.php b/src/Jigoshop/Core.php index 88809090..d8c49c6a 100755 --- a/src/Jigoshop/Core.php +++ b/src/Jigoshop/Core.php @@ -13,7 +13,7 @@ class Core { - const VERSION = '2.0.5'; + const VERSION = '2.0.6'; const WIDGET_CACHE = 'jigoshop_widget_cache'; const TERMS = 'jigoshop_term'; diff --git a/src/Jigoshop/Core/Types/Product/External.php b/src/Jigoshop/Core/Types/Product/External.php index 87f44979..c34931c4 100755 --- a/src/Jigoshop/Core/Types/Product/External.php +++ b/src/Jigoshop/Core/Types/Product/External.php @@ -5,6 +5,7 @@ use Jigoshop\Entity\Order\Item; use Jigoshop\Entity\Product; use Jigoshop\Entity\Product\External as Entity; +use Jigoshop\Exception; use Jigoshop\Helper\Render; use Jigoshop\Helper\Scripts; use WPAL\Wordpress; @@ -97,13 +98,7 @@ public function addVariableSubtype($subtypes) public function addToCart($value, $product) { if ($product instanceof Entity) { - $item = new Item(); - $item->setName($product->getName()); - $item->setPrice($product->getPrice()); - $item->setQuantity(1); - $item->setProduct($product); - - return $item; + throw new Exception(__('The external product cannot be added to cart', 'jigoshop')); } return $value; diff --git a/src/Jigoshop/Entity/Product/External.php b/src/Jigoshop/Entity/Product/External.php index 9841896a..eda5ccdb 100755 --- a/src/Jigoshop/Entity/Product/External.php +++ b/src/Jigoshop/Entity/Product/External.php @@ -159,8 +159,8 @@ public function getStateToSave() case 'regular_price': $toSave['regular_price'] = $this->regularPrice; break; - case 'url': - $toSave['url'] = $this->url; + case 'external_url': + $toSave['external_url'] = $this->url; break; } } @@ -180,14 +180,11 @@ public function restoreState(array $state) { parent::restoreState($state); - if (isset($state['price'])) { - $this->price = (float)$state['price']; - } if (isset($state['regular_price'])) { $this->regularPrice = $state['regular_price'] !== '' ? (float)$state['regular_price'] : ''; } - if (isset($state['url'])) { - $this->url = $state['url']; + if (isset($state['external_url'])) { + $this->url = $state['external_url']; } if (isset($state['sales_enabled'])) { $this->sales->setEnabled((bool)$state['sales_enabled']); diff --git a/src/Jigoshop/Entity/Product/Simple.php b/src/Jigoshop/Entity/Product/Simple.php index 4d974c18..34e33787 100755 --- a/src/Jigoshop/Entity/Product/Simple.php +++ b/src/Jigoshop/Entity/Product/Simple.php @@ -173,9 +173,6 @@ public function restoreState(array $state) { parent::restoreState($state); - if (isset($state['price'])) { - $this->price = (float)$state['price']; - } if (isset($state['regular_price'])) { $this->regularPrice = $state['regular_price'] !== '' ? (float)$state['regular_price'] : ''; } diff --git a/src/Jigoshop/Entity/Product/Virtual.php b/src/Jigoshop/Entity/Product/Virtual.php index 88fcfb27..a0aa8c4d 100755 --- a/src/Jigoshop/Entity/Product/Virtual.php +++ b/src/Jigoshop/Entity/Product/Virtual.php @@ -168,9 +168,6 @@ public function restoreState(array $state) { parent::restoreState($state); - if (isset($state['price'])) { - $this->price = (float)$state['price']; - } if (isset($state['regular_price'])) { $this->regularPrice = $state['regular_price'] !== '' ? (float)$state['regular_price'] : ''; } diff --git a/src/Jigoshop/Frontend/Page/Checkout.php b/src/Jigoshop/Frontend/Page/Checkout.php index d8a81af2..4c403c65 100755 --- a/src/Jigoshop/Frontend/Page/Checkout.php +++ b/src/Jigoshop/Frontend/Page/Checkout.php @@ -423,7 +423,7 @@ private function createUserAccount() return; } - $email = $_POST['jigoshop_order']['billing']['email']; + $email = $_POST['jigoshop_order']['billing_address']['email']; $errors = new \WP_Error(); $this->wp->doAction('register_post', $email, $email, $errors); @@ -451,22 +451,31 @@ private function createUserAccount() )); } + if (is_wp_error($id)){ + throw new Exception(sprintf( + __("Error Account creation failed: %s", 'jigoshop'), + $id->get_error_message($id->get_error_code()) + )); + } + $this->wp->wpUpdateUser(array( 'ID' => $id, 'role' => 'customer', - 'first_name' => $_POST['jigoshop_order']['billing']['first_name'], - 'last_name' => $_POST['jigoshop_order']['billing']['last_name'], + 'first_name' => $_POST['jigoshop_order']['billing_address']['first_name'], + 'last_name' => $_POST['jigoshop_order']['billing_address']['last_name'], )); $this->wp->doAction('jigoshop\checkout\created_account', $id); // send the user a confirmation and their login details if ($this->wp->applyFilters('jigoshop\checkout\new_user_notification', true, $id)) { - $this->wp->wpNewUserNotification($id, $password); + $this->wp->wpNewUserNotification($id); } $this->wp->wpSetAuthCookie($id, true, $this->wp->isSsl()); - $customer = $this->cartService->getCurrent()->getCustomer(); - $customer->setId($id); + $cart = $this->cartService->getCurrent(); + $customer = $this->customerService->find($id); + $customer->restoreState($cart->getCustomer()->getStateToSave()); + $cart->setCustomer($customer); } /** diff --git a/src/Jigoshop/Frontend/Page/Product.php b/src/Jigoshop/Frontend/Page/Product.php index ac18262d..ca89eac3 100755 --- a/src/Jigoshop/Frontend/Page/Product.php +++ b/src/Jigoshop/Frontend/Page/Product.php @@ -66,7 +66,9 @@ public function __construct(Wordpress $wp, Options $options, ProductServiceInter $wp->addFilter('jigoshop\cart\add', function ($item) use ($productService){ /** @var $item Item */ - $item->setKey($productService->generateItemKey($item)); + if($item instanceof Item) { + $item->setKey($productService->generateItemKey($item)); + } return $item; }); diff --git a/src/Jigoshop/Service/CartService.php b/src/Jigoshop/Service/CartService.php index a06ed037..05d00da6 100755 --- a/src/Jigoshop/Service/CartService.php +++ b/src/Jigoshop/Service/CartService.php @@ -9,6 +9,7 @@ use Jigoshop\Entity\OrderInterface; use Jigoshop\Entity\Session; use Jigoshop\Exception; +use Jigoshop\Factory\Customer; use Jigoshop\Factory\Order as OrderFactory; use Jigoshop\Frontend\Pages; use Jigoshop\Helper\Country; @@ -114,14 +115,12 @@ public function get($id) if (!isset($this->carts[$id])) { $cart = new Cart($this->options->get('tax.classes')); $cart->setCustomer($this->customerService->getCurrent()); - $cart->getCustomer() - ->selectTaxAddress($this->options->get('taxes.shipping') ? 'shipping' : 'billing'); + $cart->getCustomer()->selectTaxAddress($this->options->get('taxes.shipping') ? 'shipping' : 'billing'); // Fetch data from session if available $cart->setId($id); $state = $this->getStateFromSession($id); - unset($state['customer']); if (isset($_POST['jigoshop_order']) && Pages::isCheckout()) { $state = $this->getStateFromCheckout($state); } @@ -143,10 +142,7 @@ private function getStateFromSession($id) if (isset($session[$id])) { $state = $session[$id]; - if (isset($state['customer'])) { - // Customer must be unserialized twice "thanks" to WordPress second serialization. - $state['customer'] = unserialize($state['customer']); - } + $state['customer'] = $this->customerService->getCurrent(); if (isset($state['items'])) { $productService = $this->productService; diff --git a/templates/admin/product/box/general/external.php b/templates/admin/product/box/general/external.php index bfed365b..2bac9c1c 100755 --- a/templates/admin/product/box/general/external.php +++ b/templates/admin/product/box/general/external.php @@ -9,7 +9,7 @@
'product[url]', + 'name' => 'product[external_url]', 'label' => __('Product URL', 'jigoshop'), 'classes' => array('product-external'), 'placeholder' => __('Enter external product URL...', 'jigoshop'), diff --git a/templates/shop/list/cart/external.php b/templates/shop/list/cart/external.php index ed525867..0e7bde2c 100755 --- a/templates/shop/list/cart/external.php +++ b/templates/shop/list/cart/external.php @@ -3,6 +3,5 @@ * @var $product \Jigoshop\Entity\Product\External Product to add. */ ?> -
- -
+ + diff --git a/vendor/autoload.php b/vendor/autoload.php index 8df64945..aee57bc4 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInitc1b1b78b4274136f36bff3e366cb19ea::getLoader(); +return ComposerAutoloaderInit686ddfe1d7d54e7df1ed9e5a204f1480::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 9deee01f..c69dedfa 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitc1b1b78b4274136f36bff3e366cb19ea +class ComposerAutoloaderInit686ddfe1d7d54e7df1ed9e5a204f1480 { private static $loader; @@ -19,9 +19,9 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitc1b1b78b4274136f36bff3e366cb19ea', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit686ddfe1d7d54e7df1ed9e5a204f1480', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitc1b1b78b4274136f36bff3e366cb19ea', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit686ddfe1d7d54e7df1ed9e5a204f1480', 'loadClassLoader')); $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 39768be1..b82439d7 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -132,12 +132,12 @@ "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "3c782662f9d29c02eb3f200a02dafc8288e28a9e" + "reference": "bad29cb8d18ab0315e6c477751418a82c850d558" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/3c782662f9d29c02eb3f200a02dafc8288e28a9e", - "reference": "3c782662f9d29c02eb3f200a02dafc8288e28a9e", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bad29cb8d18ab0315e6c477751418a82c850d558", + "reference": "bad29cb8d18ab0315e6c477751418a82c850d558", "shasum": "" }, "require": { @@ -173,7 +173,7 @@ "ruflin/elastica": "Allow sending log messages to an Elastic Search server", "sentry/sentry": "Allow sending log messages to a Sentry server" }, - "time": "2016-11-17 11:01:44", + "time": "2016-11-26 00:15:39", "type": "library", "extra": { "branch-alias": { @@ -401,6 +401,57 @@ "psr-6" ] }, + { + "name": "spatie/array-to-xml", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/spatie/array-to-xml.git", + "reference": "06e2e7b256f02672a35f1811385f1d98239c1464" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/06e2e7b256f02672a35f1811385f1d98239c1464", + "reference": "06e2e7b256f02672a35f1811385f1d98239c1464", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "4.*", + "scrutinizer/ocular": "~1.1" + }, + "time": "2016-07-29 15:10:32", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-4": { + "Spatie\\ArrayToXml\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://murze.be", + "role": "Developer" + } + ], + "description": "Convert an array to xml", + "homepage": "https://github.com/spatie/array-to-xml", + "keywords": [ + "array", + "convert", + "xml" + ] + }, { "name": "phpfastcache/phpfastcache", "version": "6.x-dev", @@ -408,12 +459,12 @@ "source": { "type": "git", "url": "https://github.com/PHPSocialNetwork/phpfastcache.git", - "reference": "768f69b6b3c0362159050317b78b30af37b5f3d0" + "reference": "de48dc3b91799ab915785e103a9726a03b544dd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPSocialNetwork/phpfastcache/zipball/768f69b6b3c0362159050317b78b30af37b5f3d0", - "reference": "768f69b6b3c0362159050317b78b30af37b5f3d0", + "url": "https://api.github.com/repos/PHPSocialNetwork/phpfastcache/zipball/de48dc3b91799ab915785e103a9726a03b544dd7", + "reference": "de48dc3b91799ab915785e103a9726a03b544dd7", "shasum": "" }, "require": { @@ -433,7 +484,7 @@ "ext-redis": "*", "ext-sqlite": "*" }, - "time": "2016-11-19 20:43:20", + "time": "2016-11-30 19:16:22", "type": "library", "installation-source": "source", "autoload": { @@ -488,56 +539,5 @@ "zend memory cache", "zend server" ] - }, - { - "name": "spatie/array-to-xml", - "version": "dev-master", - "version_normalized": "9999999-dev", - "source": { - "type": "git", - "url": "https://github.com/spatie/array-to-xml.git", - "reference": "06e2e7b256f02672a35f1811385f1d98239c1464" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/06e2e7b256f02672a35f1811385f1d98239c1464", - "reference": "06e2e7b256f02672a35f1811385f1d98239c1464", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "mockery/mockery": "0.9.*", - "phpunit/phpunit": "4.*", - "scrutinizer/ocular": "~1.1" - }, - "time": "2016-07-29 15:10:32", - "type": "library", - "installation-source": "source", - "autoload": { - "psr-4": { - "Spatie\\ArrayToXml\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://murze.be", - "role": "Developer" - } - ], - "description": "Convert an array to xml", - "homepage": "https://github.com/spatie/array-to-xml", - "keywords": [ - "array", - "convert", - "xml" - ] } ] diff --git a/vendor/monolog/monolog/CHANGELOG.mdown b/vendor/monolog/monolog/CHANGELOG.mdown index 79bf6285..76ea0ead 100644 --- a/vendor/monolog/monolog/CHANGELOG.mdown +++ b/vendor/monolog/monolog/CHANGELOG.mdown @@ -1,12 +1,13 @@ -### 1.22.0 (2016-11-XX) +### 1.22.0 (2016-11-26) + * Added SlackbotHandler and SlackWebhookHandler to set up Slack integration more easily * Added MercurialProcessor to add mercurial revision and branch names to log records * Added support for AWS SDK v3 in DynamoDbHandler * Fixed fatal errors occuring when normalizing generators that have been fully consumed * Fixed RollbarHandler to include a level (rollbar level), monolog_level (original name), channel and datetime (unix) * Fixed RollbarHandler not flushing records automatically, calling close() explicitly is not necessary anymore * Fixed SyslogUdpHandler to avoid sending empty frames - * Fixed a few PHP7 compatibility issues + * Fixed a few PHP 7.0 and 7.1 compatibility issues ### 1.21.0 (2016-07-29) diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php index f037d54a..d4414882 100644 --- a/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php +++ b/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php @@ -70,17 +70,13 @@ protected function normalize($data) return $data; } - if (is_array($data) || $data instanceof \Traversable) { + if (is_array($data)) { $normalized = array(); $count = 1; - if ($data instanceof \Generator && !$data->valid()) { - return array('...' => 'Generator is already consumed, aborting'); - } - foreach ($data as $key => $value) { if ($count++ >= 1000) { - $normalized['...'] = 'Over 1000 items ('.($data instanceof \Generator ? 'generator function' : count($data).' total').'), aborting normalization'; + $normalized['...'] = 'Over 1000 items ('.count($data).' total), aborting normalization'; break; } $normalized[$key] = $this->normalize($value); diff --git a/vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php b/vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php new file mode 100644 index 00000000..cb0b8717 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php @@ -0,0 +1,248 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\Slack; + +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; +use Monolog\Formatter\FormatterInterface; + +/** + * Slack record utility helping to log to Slack webhooks or API. + * + * @author Greg Kedzierski + * @author Haralan Dobrev + * @see https://api.slack.com/incoming-webhooks + * @see https://api.slack.com/docs/message-attachments + */ +class SlackRecord +{ + const COLOR_DANGER = 'danger'; + + const COLOR_WARNING = 'warning'; + + const COLOR_GOOD = 'good'; + + const COLOR_DEFAULT = '#e3e4e6'; + + /** + * Slack channel (encoded ID or name) + * @var string|null + */ + private $channel; + + /** + * Name of a bot + * @var string + */ + private $username; + + /** + * Emoji icon name + * @var string + */ + private $iconEmoji; + + /** + * Whether the message should be added to Slack as attachment (plain text otherwise) + * @var bool + */ + private $useAttachment; + + /** + * Whether the the context/extra messages added to Slack as attachments are in a short style + * @var bool + */ + private $useShortAttachment; + + /** + * Whether the attachment should include context and extra data + * @var bool + */ + private $includeContextAndExtra; + + /** + * @var FormatterInterface + */ + private $formatter; + + /** + * @var LineFormatter + */ + private $lineFormatter; + + public function __construct($channel = null, $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $useShortAttachment = false, $includeContextAndExtra = false, FormatterInterface $formatter = null) + { + $this->channel = $channel; + $this->username = $username; + $this->iconEmoji = trim($iconEmoji, ':'); + $this->useAttachment = $useAttachment; + $this->useShortAttachment = $useShortAttachment; + $this->includeContextAndExtra = $includeContextAndExtra; + $this->formatter = $formatter; + + if ($this->includeContextAndExtra) { + $this->lineFormatter = new LineFormatter(); + } + } + + public function getSlackData(array $record) + { + $dataArray = array( + 'username' => $this->username, + 'text' => '', + ); + + if ($this->channel) { + $dataArray['channel'] = $this->channel; + } + + if ($this->formatter) { + $message = $this->formatter->format($record); + } else { + $message = $record['message']; + } + + if ($this->useAttachment) { + $attachment = array( + 'fallback' => $message, + 'text' => $message, + 'color' => $this->getAttachmentColor($record['level']), + 'fields' => array(), + ); + + if ($this->useShortAttachment) { + $attachment['title'] = $record['level_name']; + } else { + $attachment['title'] = 'Message'; + $attachment['fields'][] = $this->generateAttachmentField('Level', $record['level_name'], true); + } + + if ($this->includeContextAndExtra) { + foreach (array('extra', 'context') as $key) { + if (empty($record[$key])) { + continue; + } + + if ($this->useShortAttachment) { + $attachment['fields'][] = $this->generateAttachmentField( + ucfirst($key), + $this->stringify($record[$key]), + true + ); + } else { + // Add all extra fields as individual fields in attachment + $attachment['fields'] = array_merge( + $attachment['fields'], + $this->generateAttachmentFields($record[$key]) + ); + } + } + } + + $dataArray['attachments'] = array($attachment); + } else { + $dataArray['text'] = $message; + } + + if ($this->iconEmoji) { + $dataArray['icon_emoji'] = ":{$this->iconEmoji}:"; + } + + return $dataArray; + } + + /** + * Returned a Slack message attachment color associated with + * provided level. + * + * @param int $level + * @return string + */ + public function getAttachmentColor($level) + { + switch (true) { + case $level >= Logger::ERROR: + return self::COLOR_DANGER; + case $level >= Logger::WARNING: + return self::COLOR_WARNING; + case $level >= Logger::INFO: + return self::COLOR_GOOD; + default: + return self::COLOR_DEFAULT; + } + } + + /** + * Stringifies an array of key/value pairs to be used in attachment fields + * + * @param array $fields + * @return string|null + */ + public function stringify($fields) + { + if (!$this->lineFormatter) { + return null; + } + + $string = ''; + foreach ($fields as $var => $val) { + $string .= $var.': '.$this->lineFormatter->stringify($val)." | "; + } + + $string = rtrim($string, " |"); + + return $string; + } + + /** + * Sets the formatter + * + * @param FormatterInterface $formatter + */ + public function setFormatter(FormatterInterface $formatter) + { + $this->formatter = $formatter; + } + + /** + * Generates attachment field + * + * @param string $title + * @param string|array $value + * @param bool $short + * @return array + */ + private function generateAttachmentField($title, $value, $short) + { + return array( + 'title' => $title, + 'value' => is_array($value) ? $this->lineFormatter->stringify($value) : $value, + 'short' => $short + ); + } + + /** + * Generates a collection of attachment fields from array + * + * @param array $data + * @return array + */ + private function generateAttachmentFields(array $data) + { + $fields = array(); + foreach ($data as $key => $value) { + $fields[] = $this->generateAttachmentField($key, $value, false); + } + + return $fields; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php index 3de2576a..c2cca0c8 100644 --- a/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php +++ b/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php @@ -11,8 +11,9 @@ namespace Monolog\Handler; +use Monolog\Formatter\FormatterInterface; use Monolog\Logger; -use Monolog\Formatter\LineFormatter; +use Monolog\Handler\Slack\SlackRecord; /** * Sends notifications through Slack API @@ -29,45 +30,10 @@ class SlackHandler extends SocketHandler private $token; /** - * Slack channel (encoded ID or name) - * @var string - */ - private $channel; - - /** - * Name of a bot - * @var string - */ - private $username; - - /** - * Emoji icon name - * @var string - */ - private $iconEmoji; - - /** - * Whether the message should be added to Slack as attachment (plain text otherwise) - * @var bool + * Instance of the SlackRecord util class preparing data for Slack API. + * @var SlackRecord */ - private $useAttachment; - - /** - * Whether the the context/extra messages added to Slack as attachments are in a short style - * @var bool - */ - private $useShortAttachment; - - /** - * Whether the attachment should include context and extra data - * @var bool - */ - private $includeContextAndExtra; - - /** - * @var LineFormatter - */ - private $lineFormatter; + private $slackRecord; /** * @param string $token Slack API token @@ -89,17 +55,22 @@ public function __construct($token, $channel, $username = 'Monolog', $useAttachm parent::__construct('ssl://slack.com:443', $level, $bubble); + $this->slackRecord = new SlackRecord( + $channel, + $username, + $useAttachment, + $iconEmoji, + $useShortAttachment, + $includeContextAndExtra, + $this->formatter + ); + $this->token = $token; - $this->channel = $channel; - $this->username = $username; - $this->iconEmoji = trim($iconEmoji, ':'); - $this->useAttachment = $useAttachment; - $this->useShortAttachment = $useShortAttachment; - $this->includeContextAndExtra = $includeContextAndExtra; + } - if ($this->includeContextAndExtra && $this->useShortAttachment) { - $this->lineFormatter = new LineFormatter; - } + public function getSlackRecord() + { + return $this->slackRecord; } /** @@ -136,87 +107,11 @@ private function buildContent($record) */ protected function prepareContentData($record) { - $dataArray = array( - 'token' => $this->token, - 'channel' => $this->channel, - 'username' => $this->username, - 'text' => '', - 'attachments' => array(), - ); - - if ($this->formatter) { - $message = $this->formatter->format($record); - } else { - $message = $record['message']; - } - - if ($this->useAttachment) { - $attachment = array( - 'fallback' => $message, - 'color' => $this->getAttachmentColor($record['level']), - 'fields' => array(), - ); + $dataArray = $this->slackRecord->getSlackData($record); + $dataArray['token'] = $this->token; - if ($this->useShortAttachment) { - $attachment['title'] = $record['level_name']; - $attachment['text'] = $message; - } else { - $attachment['title'] = 'Message'; - $attachment['text'] = $message; - $attachment['fields'][] = array( - 'title' => 'Level', - 'value' => $record['level_name'], - 'short' => true, - ); - } - - if ($this->includeContextAndExtra) { - if (!empty($record['extra'])) { - if ($this->useShortAttachment) { - $attachment['fields'][] = array( - 'title' => "Extra", - 'value' => $this->stringify($record['extra']), - 'short' => $this->useShortAttachment, - ); - } else { - // Add all extra fields as individual fields in attachment - foreach ($record['extra'] as $var => $val) { - $attachment['fields'][] = array( - 'title' => $var, - 'value' => $val, - 'short' => $this->useShortAttachment, - ); - } - } - } - - if (!empty($record['context'])) { - if ($this->useShortAttachment) { - $attachment['fields'][] = array( - 'title' => "Context", - 'value' => $this->stringify($record['context']), - 'short' => $this->useShortAttachment, - ); - } else { - // Add all context fields as individual fields in attachment - foreach ($record['context'] as $var => $val) { - $attachment['fields'][] = array( - 'title' => $var, - 'value' => $val, - 'short' => $this->useShortAttachment, - ); - } - } - } - } - - $dataArray['attachments'] = json_encode(array($attachment)); - } else { - $dataArray['text'] = $message; - } - - if ($this->iconEmoji) { - $dataArray['icon_emoji'] = ":{$this->iconEmoji}:"; + if (!empty($dataArray['attachments'])) { + $dataArray['attachments'] = json_encode($dataArray['attachments']); } return $dataArray; @@ -260,19 +155,16 @@ protected function write(array $record) * * @param int $level * @return string + * @deprecated Use underlying SlackRecord instead */ protected function getAttachmentColor($level) { - switch (true) { - case $level >= Logger::ERROR: - return 'danger'; - case $level >= Logger::WARNING: - return 'warning'; - case $level >= Logger::INFO: - return 'good'; - default: - return '#e3e4e6'; - } + trigger_error( + 'SlackHandler::getAttachmentColor() is deprecated. Use underlying SlackRecord instead.', + E_USER_DEPRECATED + ); + + return $this->slackRecord->getAttachmentColor($level); } /** @@ -280,16 +172,31 @@ protected function getAttachmentColor($level) * * @param array $fields * @return string + * @deprecated Use underlying SlackRecord instead */ protected function stringify($fields) { - $string = ''; - foreach ($fields as $var => $val) { - $string .= $var.': '.$this->lineFormatter->stringify($val)." | "; - } + trigger_error( + 'SlackHandler::stringify() is deprecated. Use underlying SlackRecord instead.', + E_USER_DEPRECATED + ); + + return $this->slackRecord->stringify($fields); + } - $string = rtrim($string, " |"); + public function setFormatter(FormatterInterface $formatter) + { + parent::setFormatter($formatter); + $this->slackRecord->setFormatter($formatter); + + return $this; + } + + public function getFormatter() + { + $formatter = parent::getFormatter(); + $this->slackRecord->setFormatter($formatter); - return $string; + return $formatter; } } diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php new file mode 100644 index 00000000..a2df0f1a --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; +use Monolog\Logger; +use Monolog\Handler\Slack\SlackRecord; + +/** + * Sends notifications through Slack Webhooks + * + * @author Haralan Dobrev + * @see https://api.slack.com/incoming-webhooks + */ +class SlackWebhookHandler extends AbstractProcessingHandler +{ + /** + * Slack Webhook token + * @var string + */ + private $webhookUrl; + + /** + * Instance of the SlackRecord util class preparing data for Slack API. + * @var SlackRecord + */ + private $slackRecord; + + /** + * @param string $webhookUrl Slack Webhook URL + * @param string|null $channel Slack channel (encoded ID or name) + * @param string $username Name of a bot + * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise) + * @param string|null $iconEmoji The emoji name to use (or null) + * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style + * @param bool $includeContextAndExtra Whether the attachment should include context and extra data + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($webhookUrl, $channel = null, $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $useShortAttachment = false, $includeContextAndExtra = false, $level = Logger::CRITICAL, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->webhookUrl = $webhookUrl; + + $this->slackRecord = new SlackRecord( + $channel, + $username, + $useAttachment, + $iconEmoji, + $useShortAttachment, + $includeContextAndExtra, + $this->formatter + ); + } + + public function getSlackRecord() + { + return $this->slackRecord; + } + + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + $postData = $this->slackRecord->getSlackData($record); + $postString = json_encode($postData); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $this->webhookUrl); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + if (defined('CURLOPT_SAFE_UPLOAD')) { + curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true); + } + curl_setopt($ch, CURLOPT_POSTFIELDS, array('payload' => $postString)); + + Curl\Util::execute($ch); + } + + public function setFormatter(FormatterInterface $formatter) + { + parent::setFormatter($formatter); + $this->slackRecord->setFormatter($formatter); + + return $this; + } + + public function getFormatter() + { + $formatter = parent::getFormatter(); + $this->slackRecord->setFormatter($formatter); + + return $formatter; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SlackbotHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SlackbotHandler.php new file mode 100644 index 00000000..baead525 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SlackbotHandler.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Sends notifications through Slack's Slackbot + * + * @author Haralan Dobrev + * @see https://slack.com/apps/A0F81R8ET-slackbot + */ +class SlackbotHandler extends AbstractProcessingHandler +{ + /** + * The slug of the Slack team + * @var string + */ + private $slackTeam; + + /** + * Slackbot token + * @var string + */ + private $token; + + /** + * Slack channel name + * @var string + */ + private $channel; + + /** + * @param string $slackTeam Slack team slug + * @param string $token Slackbot token + * @param string $channel Slack channel (encoded ID or name) + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($slackTeam, $token, $channel, $level = Logger::CRITICAL, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->slackTeam = $slackTeam; + $this->token = $token; + $this->channel = $channel; + } + + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + $slackbotUrl = sprintf( + 'https://%s.slack.com/services/hooks/slackbot?token=%s&channel=%s', + $this->slackTeam, + $this->token, + $this->channel + ); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $slackbotUrl); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $record['message']); + + Curl\Util::execute($ch); + } +} diff --git a/vendor/phpfastcache/phpfastcache/README.md b/vendor/phpfastcache/phpfastcache/README.md index c3b8809d..3ad7a4a1 100644 --- a/vendor/phpfastcache/phpfastcache/README.md +++ b/vendor/phpfastcache/phpfastcache/README.md @@ -33,7 +33,7 @@ He's fresh, so feel free to report any bug or contribute to the code using pull --------------------------- Not a "Traditional" Caching --------------------------- -phpFastCache is not a traditional caching method which is keep read and write to files, sqlite or mass connections to memcache, redis, mongodb... Also, when you use Memcache / Memcached, your miss hits will be reduce. +phpFastCache is not a traditional caching method which keep read and write to files, sqlite or mass connections to memcache, redis, mongodb... Also, when you use Memcache / Memcached, your miss hits will be reduce. Different with normal caching methods which shared everywhere on internet, phpFastCache Lib reduce the high I/O load, and faster than traditional caching method at least x7 ~+ times. However, some time you still want to use traditional caching, we support them too. diff --git a/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/Pool/DriverBaseTrait.php b/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/Pool/DriverBaseTrait.php index bde31693..9cf94488 100644 --- a/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/Pool/DriverBaseTrait.php +++ b/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/Pool/DriverBaseTrait.php @@ -272,7 +272,7 @@ public function driverWriteTags(ExtendedCacheItemInterface $item) $this->driverWrite($tagsItem); $tagsItem->setHit(true); } else { - $this->deleteItem($tagsItem); + $this->deleteItem($tagsItem->getKey()); } } diff --git a/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/Pool/ExtendedCacheItemPoolInterface.php b/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/Pool/ExtendedCacheItemPoolInterface.php index a06d1a1d..d25e8757 100644 --- a/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/Pool/ExtendedCacheItemPoolInterface.php +++ b/vendor/phpfastcache/phpfastcache/src/phpFastCache/Core/Pool/ExtendedCacheItemPoolInterface.php @@ -144,7 +144,7 @@ public function getStats(); * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * - * @return array|\Traversable + * @return ExtendedCacheItemInterface[] * A traversable collection of Cache Items keyed by the cache keys of * each item. A Cache item will be returned for each key, even if that * key is not found. However, if no keys are specified then an empty @@ -162,7 +162,7 @@ public function getItemsByTag($tagName); * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * - * @return array|\Traversable + * @return ExtendedCacheItemInterface[] * A traversable collection of Cache Items keyed by the cache keys of * each item. A Cache item will be returned for each key, even if that * key is not found. However, if no keys are specified then an empty