Skip to content

Commit

Permalink
0.74.0-beta5
Browse files Browse the repository at this point in the history
* Various
    * Added the new methods/fields in the Catalog Product Data Object
    * Improved the Nginx configuration sample file for better web-server responsiveness and security
    * Implemented the new look & feel for Create New Order page
    * Removed the redundant DB constraints for cascade operations related to order management
    * Implemented the mechanism of asynchronous email notifications after creation of Orders, Invoices, Shipments and Credit Memos
    * Moved the join logic on application level in order to make DB separation possible in Reports component
    * Implemented the TTL and event approaches of cache invalidation, introduced the full and the partial Varnish Cache flush
    * Moved all Setup commands to Magento CLI
    * Exposed CMS API as Web API
* Fixed bugs:
    * Unexpected response for API "/V1/customers/password" service
    * Cant include a third-party link to frontend section via layout
    * Specified details for Grouped product are lost after adding to wishlist
    * Impossible to configure products in customer wishlist in Admin Panel
    * Adding the product from wishlist to cart if more than one store view exists
    * Specified product field custom options is not displayed in wishlist in Admin Panel
    * Checkout doesn't work with JS bundling enabled in production mode
    * Issue with price excluding tax when selecting downloadable links
    * Undefined index warning in case the frontend cache information is missing in configuration file
    * "New Order" email is not sent to customer after placing order via API service
    * 503 error when placing order with multiple shipping addresses if mail transport doesn't exist
    * Broken words for fields with long labels all over the Admin Panel
    * Issue with saving 'is_virtual' flag in quote
    * "Void" button available after "Deny Payment" operation
    * Uninstall logic did not clean cache properly
    * Obsolete code tests did not cover Tests folders
    * Random fail of Magento\Log\Test\Unit\Model\VisitorTest
* GitHub issues:
   * [#1149] (magento/magento2#1149) -- Checkout Grand Total amount miscalculation
   * [#1165] (magento/magento2#1165) -- Fix typos
   * [#1182] (magento/magento2#1182) -- Update system.xml for 'fix' sortOrder in adminhtml
   * [#1186] (magento/magento2#1186) -- SalesSequence: Fixed composer installer dependency
  • Loading branch information
magento-team committed Apr 28, 2015
2 parents 6cbe7dd + be256fb commit bfc9c29
Show file tree
Hide file tree
Showing 110 changed files with 29,231 additions and 0 deletions.
11 changes: 11 additions & 0 deletions update/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/var/*
!/var/.htaccess
/vendor
/.buildpath
/.cache
/.metadata
/.project
/.settings
atlassian*
/.idea
/.gitattributes
6 changes: 6 additions & 0 deletions update/.htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Order deny,allow
Deny from all

<Files index.php>
Allow from all
</Files>
Empty file added update/README.md
Empty file.
15 changes: 15 additions & 0 deletions update/app/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

error_reporting(E_ALL);

define('UPDATER_BP', realpath(__DIR__ . '/../'));
define('UPDATER_BACKUP_DIR', UPDATER_BP . '/var/backup/');
define('MAGENTO_BP', realpath(__DIR__ . '/../../'));

date_default_timezone_set('UTC');

require_once UPDATER_BP . '/vendor/autoload.php';
78 changes: 78 additions & 0 deletions update/app/code/Magento/Update/Backup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Update;

use Magento\Update\Backup\BackupInfo;
use Magento\Update\Status;

/**
* Class for creating Magento codebase backups.
*/
class Backup
{
/**
* @var BackupInfo
*/
protected $backupInfo;

/**
* @var Status
*/
protected $status;

/**
* Initialize dependencies.
*
* @param BackupInfo|null $backupInfo
* @param Status|null $status
*/
public function __construct(BackupInfo $backupInfo = null, Status $status = null)
{
$this->backupInfo = $backupInfo ? $backupInfo : new BackupInfo();
$this->status = $status ? $status : new Status();
}

/**
* Create backup archive using unix zip tool.
*
* @return $this
* @throws \RuntimeException
*/
public function execute()
{
$backupFilePath = $this->backupInfo->getBackupPath() . $this->backupInfo->generateBackupFilename();
$command = $this->buildShellCommand($backupFilePath);
$this->status->add(sprintf('Creating backup archive "%s" ...', $backupFilePath));
exec($command, $output, $return);
if ($return) {
throw new \RuntimeException(
sprintf('Cannot create backup with command "%s": %s', $command, implode("\n", $output))
);
}
$this->status->add(sprintf('Backup archive "%s" has been created.', $backupFilePath));
return $this;
}

/**
* Construct shell command for creating backup archive.
*
* @param string $backupFilePath
* @return string
*/
protected function buildShellCommand($backupFilePath)
{
$excludedElements = '';
foreach ($this->backupInfo->getBlacklist() as $excludedElement) {
$elementPath = $excludedElement;
$fullPath = $this->backupInfo->getArchivedDirectory() . '/' . $elementPath;
$excludedElements .= is_dir($fullPath) ? $elementPath . '\* ' : $elementPath . ' ';
}
$changeDirectoryCommand = sprintf("cd %s", $this->backupInfo->getArchivedDirectory());
$zipCommand = sprintf("zip -r %s . -x %s", $backupFilePath, $excludedElements);
return $changeDirectoryCommand . ' && ' . $zipCommand;
}
}
90 changes: 90 additions & 0 deletions update/app/code/Magento/Update/Backup/BackupInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Update\Backup;

/**
* Data object, which stores information about files to be archived.
*/
class BackupInfo
{
/**
* @var string
*/
protected $blacklistFilePath;

/**
* @var string[]
*/
protected $blacklist;

/**
* Init backup info
*
* @param string $blacklistFilePath
*/
public function __construct($blacklistFilePath = null)
{
$this->blacklistFilePath = $blacklistFilePath ? $blacklistFilePath : __DIR__ . '/../etc/backup_blacklist.txt';
}

/**
* Generate backup filename based on current timestamp.
*
* @return string
*/
public function generateBackupFilename()
{
$currentDate = date('Y-m-d-H-i-s', time());
return 'backup-' . $currentDate . '-' . date_default_timezone_get() . '.zip';
}

/**
* Return files/directories, which need to be excluded from backup
*
* @return string[]
*/
public function getBlacklist()
{
if (null === $this->blacklist) {
$blacklistContent = file_get_contents($this->blacklistFilePath);
if ($blacklistContent === FALSE) {
throw new \RuntimeException('Could not read the blacklist file: ' . $this->blacklistFilePath);
}
/** Ignore commented and empty lines */
$blacklistArray = explode("\n", $blacklistContent);
$blacklistArray = array_filter(
$blacklistArray,
function ($value) {
$value = trim($value);
return (empty($value) || strpos($value, '#') === 0) ? false : true;
}
);
$this->blacklist = $blacklistArray;
}
return $this->blacklist;
}

/**
* Return path to a directory, which need to be archived
*
* @return string
*/
public function getArchivedDirectory()
{
return MAGENTO_BP;
}

/**
* Return path, where backup have to be saved
*
* @return string
*/
public function getBackupPath()
{
return UPDATER_BACKUP_DIR;
}
}
87 changes: 87 additions & 0 deletions update/app/code/Magento/Update/MaintenanceMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Update;

use Magento\Update\Status;

/**
* Class for handling Magento maintenance mode.
*/
class MaintenanceMode
{
/**
* Path to the maintenance flag file
*
* @var string
*/
protected $flagFile;

/**
* Path to the file with white-listed IP addresses
*
* @var string
*/
protected $ipFile;

/**
* @var Status
*/
protected $status;

/**
* Initialize.
*
* @param string|null $flagFile
* @param string|null $ipFile
* @param Status|null $status
*/
public function __construct($flagFile = null, $ipFile = null, Status $status = null)
{
$this->flagFile = $flagFile ? $flagFile : MAGENTO_BP . '/var/.maintenance.flag';
$this->ipFile = $ipFile ? $ipFile : MAGENTO_BP . '/var/.maintenance.ip';
$this->status = $status ? $status : new Status();
}

/**
* Check whether Magento maintenance mode is on.
*
* @return bool
*/
public function isOn()
{
return file_exists($this->flagFile);
}

/**
* Set maintenance mode.
*
* @param bool $isOn
* @return $this
* @throws \RuntimeException
*/
public function set($isOn)
{
if ($isOn) {
if (touch($this->flagFile)) {
$this->status->add("Magento maintenance mode is enabled.");
} else {
throw new \RuntimeException("Magento maintenance mode cannot be enabled.");
}
} else if (file_exists($this->flagFile)) {
if (file_exists($this->ipFile)) {
/** Maintenance mode should not be unset from updater application if it was set manually by the admin */
$this->status->add(
"Magento maintenance mode was not disabled. It can be disabled form the Magento Backend."
);
} else if (unlink($this->flagFile)) {
$this->status->add("Magento maintenance mode is disabled.");
} else {
throw new \RuntimeException("Magento maintenance mode cannot be disabled.");
}
}
return $this;
}
}
91 changes: 91 additions & 0 deletions update/app/code/Magento/Update/Queue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Update;

use Magento\Update\Queue\Reader;
use Magento\Update\Queue\AbstractJob;
use Magento\Update\Queue\JobFactory;

/**
* Class for access to the queue of Magento updater application jobs.
*/
class Queue
{
/**#@+
* Key used in queue file.
*/
const KEY_JOBS = 'jobs';
const KEY_JOB_NAME = 'name';
const KEY_JOB_PARAMS = 'params';
/**#@-*/

/**
* @var Reader
*/
protected $reader;

/**
* @var JobFactory
*/
protected $jobFactory;

/**
* Initialize dependencies.
*
* @param Reader|null $reader
* @param JobFactory|null $jobFactory
*/
public function __construct(Reader $reader = null, JobFactory $jobFactory = null)
{
$this->reader = $reader ? $reader : new Reader();
$this->jobFactory = $jobFactory ? $jobFactory : new JobFactory();
}

/**
* Pop all updater application queued jobs.
*
* Note, that this method is not idempotent, queue will be cleared after its execution
*
* @return AbstractJob[]
* @throws \RuntimeException
*/
public function popQueuedJobs()
{
$jobs = [];
$queue = json_decode($this->reader->read(), true);
if (!is_array($queue)) {
return $jobs;
}
if (isset($queue[self::KEY_JOBS]) && is_array($queue[self::KEY_JOBS])) {
/** @var object $job */
foreach ($queue[self::KEY_JOBS] as $job) {
$this->validateJobDeclaration($job);
$jobs[] = $this->jobFactory->create($job[self::KEY_JOB_NAME], $job[self::KEY_JOB_PARAMS]);
}
} else {
throw new \RuntimeException(sprintf('"%s" field is missing or is not an array.', self::KEY_JOBS));
}
$this->reader->clearQueue();
return $jobs;
}

/**
* Make sure job declaration is correct.
*
* @param object $job
* @throws \RuntimeException
*/
protected function validateJobDeclaration($job)
{
$requiredFields = [self::KEY_JOB_NAME, self::KEY_JOB_PARAMS];
foreach ($requiredFields as $field) {
if (!isset($job[$field])) {
throw new \RuntimeException(sprintf('"%s" field is missing for one or more jobs.', $field));
}
}
}
}
Loading

0 comments on commit bfc9c29

Please sign in to comment.