Skip to content

Commit 52405c5

Browse files
authored
Merge pull request #1 from magento/develop
Merged mg2 develop into develop
2 parents ad9c8e3 + b180d87 commit 52405c5

File tree

53 files changed

+1422
-177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1422
-177
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ addons:
99
- postfix
1010
language: php
1111
php:
12-
- 5.6
12+
- 5.6.29
1313
- 7.0
1414
env:
1515
global:

README.md

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,61 +3,14 @@
33
<h2>Welcome</h2>
44
Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a cutting edge, feature-rich eCommerce solution that gets results.
55

6-
The installation instructions that used to be here are now published on our GitHub site. Use the information on this page to get started or go directly to the <a href="http://devdocs.magento.com/guides/v2.0/install-gde/bk-install-guide.html" target="_blank">guide</a>.
6+
## Magento system requirements
7+
[Magento system requirements](http://devdocs.magento.com/magento-system-requirements.html)
78

8-
<h2>New to Magento? Need some help?</h2>
9-
If you're not sure about the following, you probably need a little help before you start installing the Magento software:
9+
## Install Magento
10+
To install Magento, see either:
1011

11-
* Is the Magento software <a href="http://devdocs.magento.com/guides/v2.0/install-gde/basics/basics_magento-installed.html">installed already</a>?
12-
* What's a <a href="http://devdocs.magento.com/guides/v2.0/install-gde/basics/basics_login.html">terminal, command prompt, or Secure Shell (ssh)</a>?
13-
* Where's my <a href="http://devdocs.magento.com/guides/v2.0/install-gde/basics/basics_login.html">Magento server</a> and how do I access it?
14-
* What's <a href="http://devdocs.magento.com/guides/v2.0/install-gde/basics/basics_software.html">PHP</a>?
15-
* What's <a href="http://devdocs.magento.com/guides/v2.0/install-gde/basics/basics_software.html">Apache</a>?
16-
* What's <a href="http://devdocs.magento.com/guides/v2.0/install-gde/basics/basics_software.html">MySQL</a>?
17-
18-
<h2>Step 1: Verify your prerequisites</h2>
19-
20-
Use the following table to verify you have the correct prerequisites to install the Magento software.
21-
22-
<table>
23-
<tbody>
24-
<tr>
25-
<th>Prerequisite</th>
26-
<th>How to check</th>
27-
<th>For more information</th>
28-
</tr>
29-
<tr>
30-
<td>Apache 2.2 or 2.4</td>
31-
<td>Ubuntu: <code>apache2 -v</code><br>
32-
CentOS: <code>httpd -v</code></td>
33-
<td><a href="http://devdocs.magento.com/guides/v2.0/install-gde/prereq/apache.html">Apache</a></td>
34-
</tr>
35-
<tr>
36-
<td>PHP 5.6.x, 7.0.2, 7.0.4 or 7.0.6</td>
37-
<td><code>php -v</code></td>
38-
<td><a href="http://devdocs.magento.com/guides/v2.0/install-gde/prereq/php-ubuntu.html">PHP Ubuntu</a><br><a href="http://devdocs.magento.com/guides/v2.0/install-gde/prereq/php-centos.html">PHP CentOS</a></td>
39-
</tr>
40-
<tr><td>MySQL 5.6.x</td>
41-
<td><code>mysql -u [root user name] -p</code></td>
42-
<td><a href="http://devdocs.magento.com/guides/v2.0/install-gde/prereq/mysql.html">MySQL</a></td>
43-
</tr>
44-
</tbody>
45-
</table>
46-
47-
<h2>Step 2: Prepare to install</h2>
48-
49-
After verifying your prerequisites, perform the following tasks in order to prepare to install the Magento software.
50-
51-
1. <a href="http://devdocs.magento.com/guides/v2.0/install-gde/install/composer-clone.html#instgde-prereq-compose-install">Install Composer</a>
52-
2. <a href="http://devdocs.magento.com/guides/v2.0/install-gde/install/composer-clone.html#instgde-prereq-compose-clone">Clone the Magento repository</a>
53-
54-
<h2>Step 3: Install and verify the installation</h2>
55-
56-
1. <a href="http://devdocs.magento.com/guides/v2.0/install-gde/install/prepare-install.html">Update installation dependencies</a>
57-
2. Install Magento:
58-
* <a href="http://devdocs.magento.com/guides/v2.0/install-gde/install/install-web.html">Install Magento software using the web interface</a>
59-
* <a href="http://devdocs.magento.com/guides/v2.0/install-gde/install/install-cli.html">Install Magento software using the command line</a>
60-
2. <a href="http://devdocs.magento.com/guides/v2.0/install-gde/install/verify.html">Verify the installation</a>
12+
* [Magento DevBox](https://magento.com/tech-resources/download), the easiest way to get started with Magento.
13+
* [Installation guide](http://devdocs.magento.com/guides/v2.0/install-gde/bk-install-guide.html)
6114

6215
<h2>Contributing to the Magento 2 code base</h2>
6316
Contributions can take the form of new components or features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations, or just good suggestions.

app/code/Magento/Backend/i18n/en_US.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ Minute,Minute
250250
"JavaScript may be disabled in your browser.","JavaScript may be disabled in your browser."
251251
"To use this website you must first enable JavaScript in your browser.","To use this website you must first enable JavaScript in your browser."
252252
"This is only a demo store. You can browse and place orders, but nothing will be processed.","This is only a demo store. You can browse and place orders, but nothing will be processed."
253-
"Report Bugs","Report Bugs"
253+
"Report a Bug","Report a Bug"
254254
"Store View:","Store View:"
255255
"Stores Configuration","Stores Configuration"
256256
"Please confirm scope switching. All data that hasn\'t been saved will be lost.","Please confirm scope switching. All data that hasn\'t been saved will be lost."

app/code/Magento/Backend/view/adminhtml/templates/page/report.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88

99
?>
1010
<?php if ($block->getBugreportUrl()): ?>
11-
<a class="link-report" href="<?php /* @escapeNotVerified */ echo $block->getBugreportUrl(); ?>" id="footer_bug_tracking"><?php /* @escapeNotVerified */ echo __('Report Bugs') ?></a>
11+
<a class="link-report" href="<?php /* @escapeNotVerified */ echo $block->getBugreportUrl(); ?>" id="footer_bug_tracking"><?php /* @escapeNotVerified */ echo __('Report a Bug') ?></a>
1212
<?php endif; ?>

app/code/Magento/Captcha/Test/Unit/Helper/DataTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ protected function setUp()
5353
*/
5454
public function testGetCaptcha()
5555
{
56-
if (!function_exists("imageftbbox")) {
57-
$this->markTestSkipped('imageftbbox is not available on the test environment');
58-
}
59-
6056
$this->configMock->expects(
6157
$this->once()
6258
)->method(

app/code/Magento/Captcha/Test/Unit/Model/DefaultTest.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@ class DefaultTest extends \PHPUnit_Framework_TestCase
8888
*/
8989
protected function setUp()
9090
{
91-
if (!function_exists("imageftbbox")) {
92-
$this->markTestSkipped('imageftbbox is not available on the test environment');
93-
}
9491
$this->session = $this->_getSessionStub();
9592

9693
$this->_storeManager = $this->getMock(

app/code/Magento/Catalog/Model/ProductLink/CollectionProvider.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,21 @@ public function getCollection(\Magento\Catalog\Model\Product $product, $type)
4848
$products = $this->providers[$type]->getLinkedProducts($product);
4949
$converter = $this->converterPool->getConverter($type);
5050
$output = [];
51+
$sorterItems = [];
5152
foreach ($products as $item) {
5253
$output[$item->getId()] = $converter->convert($item);
5354
}
54-
return $output;
55+
56+
foreach ($output as $item) {
57+
$itemPosition = $item['position'];
58+
if (!isset($sorterItems[$itemPosition])) {
59+
$sorterItems[$itemPosition] = $item;
60+
} else {
61+
$newPosition = $itemPosition + 1;
62+
$sorterItems[$newPosition] = $item;
63+
}
64+
}
65+
ksort($sorterItems);
66+
return $sorterItems;
5567
}
5668
}

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ public function build($productId)
9898
->limit(1);
9999
$priceSelect = $this->baseSelectProcessor->process($priceSelect);
100100

101-
$priceSelectDefault = clone $priceSelect;
102-
$priceSelectDefault->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
103-
$select[] = $priceSelectDefault;
104-
105101
if (!$this->catalogHelper->isPriceGlobal()) {
106-
$priceSelect->where('t.store_id = ?', $this->storeManager->getStore()->getId());
107-
$select[] = $priceSelect;
102+
$priceSelectStore = clone $priceSelect;
103+
$priceSelectStore->where('t.store_id = ?', $this->storeManager->getStore()->getId());
104+
$selects[] = $priceSelectStore;
108105
}
109106

110-
return $select;
107+
$priceSelect->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
108+
$selects[] = $priceSelect;
109+
110+
return $selects;
111111
}
112112
}

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,15 @@ public function build($productId)
142142
->limit(1);
143143
$specialPrice = $this->baseSelectProcessor->process($specialPrice);
144144

145-
$specialPriceDefault = clone $specialPrice;
146-
$specialPriceDefault->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
147-
$select[] = $specialPriceDefault;
148-
149145
if (!$this->catalogHelper->isPriceGlobal()) {
150-
$specialPrice->where('t.store_id = ?', $this->storeManager->getStore()->getId());
151-
$select[] = $specialPrice;
146+
$priceSelectStore = clone $specialPrice;
147+
$priceSelectStore->where('t.store_id = ?', $this->storeManager->getStore()->getId());
148+
$selects[] = $priceSelectStore;
152149
}
153150

154-
return $select;
151+
$specialPrice->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
152+
$selects[] = $specialPrice;
153+
154+
return $selects;
155155
}
156156
}

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,15 @@ public function build($productId)
100100
->limit(1);
101101
$priceSelect = $this->baseSelectProcessor->process($priceSelect);
102102

103-
$priceSelectDefault = clone $priceSelect;
104-
$priceSelectDefault->where('t.website_id = ?', self::DEFAULT_WEBSITE_ID);
105-
$select[] = $priceSelectDefault;
106-
107103
if (!$this->catalogHelper->isPriceGlobal()) {
108-
$priceSelect->where('t.website_id = ?', $this->storeManager->getStore()->getWebsiteId());
109-
$select[] = $priceSelect;
104+
$priceSelectStore = clone $priceSelect;
105+
$priceSelectStore->where('t.website_id = ?', $this->storeManager->getStore()->getWebsiteId());
106+
$selects[] = $priceSelectStore;
110107
}
111108

112-
return $select;
109+
$priceSelect->where('t.website_id = ?', self::DEFAULT_WEBSITE_ID);
110+
$selects[] = $priceSelect;
111+
112+
return $selects;
113113
}
114114
}

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderComposite.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ public function __construct($linkedProductSelectBuilder)
2626
*/
2727
public function build($productId)
2828
{
29-
$select = [];
29+
$selects = [];
3030
foreach ($this->linkedProductSelectBuilder as $productSelectBuilder) {
31-
$select = array_merge($select, $productSelectBuilder->build($productId));
31+
$selects = array_merge($selects, $productSelectBuilder->build($productId));
3232
}
3333

34-
return $select;
34+
return $selects;
3535
}
3636
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model\ResourceModel\Product\Website;
7+
8+
use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
9+
use Magento\Framework\DB\Select;
10+
use Magento\Framework\EntityManager\MetadataPool;
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Framework\App\ResourceConnection;
13+
use Magento\Store\Model\StoreManagerInterface;
14+
15+
/**
16+
* Filter products that belongs to current website
17+
*/
18+
class SelectProcessor implements BaseSelectProcessorInterface
19+
{
20+
/**
21+
* @var ResourceConnection
22+
*/
23+
private $resource;
24+
25+
/**
26+
* @var MetadataPool
27+
*/
28+
private $metadataPool;
29+
30+
/**
31+
* @var StoreManagerInterface
32+
*/
33+
private $storeManager;
34+
35+
/**
36+
* @param MetadataPool $metadataPool
37+
* @param ResourceConnection $resource
38+
* @param StoreManagerInterface $storeManager
39+
*/
40+
public function __construct(
41+
MetadataPool $metadataPool,
42+
ResourceConnection $resource,
43+
StoreManagerInterface $storeManager
44+
) {
45+
$this->metadataPool = $metadataPool;
46+
$this->resource = $resource;
47+
$this->storeManager = $storeManager;
48+
}
49+
50+
/**
51+
* Joins website-product relation table to filter products that are only in current website
52+
*
53+
* {@inheritdoc}
54+
*/
55+
public function process(Select $select)
56+
{
57+
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
58+
$select->joinInner(
59+
['pw' => $this->resource->getTableName('catalog_product_website')],
60+
'pw.product_id = ' . BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS . '.' . $linkField
61+
. ' AND pw.website_id = ' . $this->storeManager->getWebsite()->getId(),
62+
[]
63+
);
64+
65+
return $select;
66+
}
67+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Test\Unit\Model;
8+
9+
use Magento\Catalog\Model\ProductLink\CollectionProvider;
10+
use Magento\Catalog\Model\ProductLink\CollectionProviderInterface;
11+
use Magento\Catalog\Model\ProductLink\Converter\ConverterInterface;
12+
use Magento\Catalog\Model\ProductLink\Converter\ConverterPool;
13+
use Magento\Catalog\Model\Product;
14+
15+
class CollectionProviderTest extends \PHPUnit_Framework_TestCase
16+
{
17+
/**
18+
* @var CollectionProvider
19+
*/
20+
private $model;
21+
22+
/**
23+
* @var \PHPUnit_Framework_MockObject_MockObject
24+
*/
25+
private $converterPoolMock;
26+
27+
/**
28+
* @var \PHPUnit_Framework_MockObject_MockObject
29+
*/
30+
private $providerMock;
31+
32+
/**
33+
* @var \PHPUnit_Framework_MockObject_MockObject
34+
*/
35+
private $productMock;
36+
37+
/**
38+
* @var \PHPUnit_Framework_MockObject_MockObject
39+
*/
40+
private $converterMock;
41+
42+
protected function setUp()
43+
{
44+
$this->productMock = $this->getMock(Product::class, [], [], '', false, false);
45+
$this->converterPoolMock = $this->getMock(ConverterPool::class, [], [], '', false, false);
46+
$this->providerMock = $this->getMock(CollectionProviderInterface::class);
47+
$this->converterMock = $this->getMock(ConverterInterface::class);
48+
49+
$this->model = new CollectionProvider($this->converterPoolMock, ['crosssell' => $this->providerMock]);
50+
}
51+
52+
/**
53+
* Test sort order of linked products based on configured item position.
54+
*/
55+
public function testGetCollection()
56+
{
57+
$linkedProductOneMock = $this->getMock(Product::class, [], [], '', false, false);
58+
$linkedProductTwoMock = $this->getMock(Product::class, [], [], '', false, false);
59+
$linkedProductThreeMock = $this->getMock(Product::class, [], [], '', false, false);
60+
61+
$linkedProductOneMock->expects($this->once())->method('getId')->willReturn(1);
62+
$linkedProductTwoMock->expects($this->once())->method('getId')->willReturn(2);
63+
$linkedProductThreeMock->expects($this->once())->method('getId')->willReturn(3);
64+
65+
$this->converterPoolMock->expects($this->once())
66+
->method('getConverter')
67+
->with('crosssell')
68+
->willReturn($this->converterMock);
69+
70+
$map = [
71+
[$linkedProductOneMock, ['name' => 'Product One', 'position' => 10]],
72+
[$linkedProductTwoMock, ['name' => 'Product Two', 'position' => 2]],
73+
[$linkedProductThreeMock, ['name' => 'Product Three', 'position' => 2]],
74+
];
75+
76+
$this->converterMock->expects($this->exactly(3))->method('convert')->willReturnMap($map);
77+
78+
$this->providerMock->expects($this->once())
79+
->method('getLinkedProducts')
80+
->with($this->productMock)
81+
->willReturn(
82+
[
83+
$linkedProductOneMock,
84+
$linkedProductTwoMock,
85+
$linkedProductThreeMock
86+
]
87+
);
88+
89+
$expectedResult = [
90+
2 => ['name' => 'Product Two', 'position' => 2],
91+
3 => ['name' => 'Product Three', 'position' => 2],
92+
10 => ['name' => 'Product One', 'position' => 10],
93+
];
94+
95+
$actualResult = $this->model->getCollection($this->productMock, 'crosssell');
96+
97+
$this->assertEquals($expectedResult, $actualResult, 'Sort order of linked products in incorrect');
98+
}
99+
100+
/**
101+
* Test exception when collection provider is not configured for product link type.
102+
*
103+
* @expectedException \Magento\Framework\Exception\NoSuchEntityException
104+
* @expectedExceptionMessage Collection provider is not registered
105+
*/
106+
public function testGetCollectionWithMissingProviders()
107+
{
108+
$this->model->getCollection($this->productMock, 'upsell');
109+
}
110+
}

0 commit comments

Comments
 (0)