Completed
Push — master ( 586166...fecb59 )
by Paweł
47:58
created

ArticleLoader::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 11
nc 1
nop 5
crap 1
1
<?php
2
3
/**
4
 * This file is part of the Superdesk Web Publisher Content Bundle.
5
 *
6
 * Copyright 2015 Sourcefabric z.u. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2015 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\ContentBundle\Loader;
16
17
use PHPCR\Query\QueryInterface;
18
use SWP\Bundle\ContentBundle\Doctrine\ODM\PHPCR\ArticleInterface;
19
use SWP\Component\TemplatesSystem\Gimme\Context\Context;
20
use SWP\Component\TemplatesSystem\Gimme\Factory\MetaFactoryInterface;
21
use SWP\Component\TemplatesSystem\Gimme\Loader\LoaderInterface;
22
use SWP\Component\TemplatesSystem\Gimme\Meta\Meta;
23
use SWP\Component\TemplatesSystem\Gimme\Meta\MetaCollection;
24
use Doctrine\ODM\PHPCR\DocumentManager;
25
use SWP\Component\MultiTenancy\PathBuilder\TenantAwarePathBuilderInterface;
26
27
/**
28
 * Class ArticleLoader.
29
 */
30
class ArticleLoader implements LoaderInterface
31
{
32
    /**
33
     * @var DocumentManager
34
     */
35
    protected $dm;
36
37
    /**
38
     * @var TenantAwarePathBuilderInterface
39
     */
40
    protected $pathBuilder;
41
42
    /**
43
     * @var string
44
     */
45
    protected $routeBasepaths;
46
47
    /**
48
     * @var MetaFactoryInterface
49
     */
50
    protected $metaFactory;
51
52
    /**
53
     * @var Context
54
     */
55
    protected $context;
56
57
    /**
58
     * ArticleLoader constructor.
59
     *
60
     * @param DocumentManager                 $dm
61
     * @param TenantAwarePathBuilderInterface $pathBuilder
62
     * @param string                          $routeBasepaths
63
     * @param MetaFactoryInterface            $metaFactory
64
     * @param Context                         $context
65
     */
66 95
    public function __construct(
67
        DocumentManager $dm,
68
        TenantAwarePathBuilderInterface $pathBuilder,
69
        $routeBasepaths,
70
        MetaFactoryInterface $metaFactory,
71
        Context $context
72
    ) {
73 95
        $this->dm = $dm;
74 95
        $this->pathBuilder = $pathBuilder;
75 95
        $this->routeBasepaths = $routeBasepaths;
76 95
        $this->metaFactory = $metaFactory;
77 95
        $this->context = $context;
78 95
    }
79
80
    /**
81
     * Load meta object by provided type and parameters.
82
     *
83
     * @MetaLoaderDoc(
84
     *     description="Article Loader loads articles from Content Repository",
85
     *     parameters={
86
     *         contentPath="SINGLE|required content path",
87
     *         slug="SINGLE|required content slug",
88
     *         pageName="COLLECTiON|name of Page for required articles"
89
     *     }
90
     * )
91
     *
92
     * @param string $type         object type
93
     * @param array  $parameters   parameters needed to load required object type
94
     * @param int    $responseType response type: single meta (LoaderInterface::SINGLE) or collection of metas (LoaderInterface::COLLECTION)
95
     *
96
     * @return Meta|Meta[]|bool false if meta cannot be loaded, a Meta instance otherwise
97
     *
98
     * @throws \Exception
99
     */
100 18
    public function load($type, $parameters = [], $responseType = LoaderInterface::SINGLE)
101
    {
102 18
        $article = null;
103
104 18
        if ($responseType === LoaderInterface::SINGLE) {
105 14
            if (array_key_exists('contentPath', $parameters)) {
106 3
                $article = $this->dm->find('SWP\Bundle\ContentBundle\Doctrine\ODM\PHPCR\Article', $parameters['contentPath']);
107 3
                if (null !== $article && !$article->isPublished()) {
108 3
                    $article = null;
109
                }
110 11
            } elseif (array_key_exists('article', $parameters)) {
111
                $this->dm->detach($parameters['article']);
112
                $article = $this->dm->find('SWP\Bundle\ContentBundle\Doctrine\ODM\PHPCR\Article', $parameters['article']->getId());
113
                if (null !== $article && !$article->isPublished()) {
114
                    $article = null;
115
                }
116 11
            } elseif (array_key_exists('slug', $parameters)) {
117 11
                $article = $this->dm->getRepository('SWP\Bundle\ContentBundle\Doctrine\ODM\PHPCR\Article')->findOneBy([
118 11
                    'slug' => $parameters['slug'],
119 11
                    'status' => ArticleInterface::STATUS_PUBLISHED,
120
                ]);
121
            }
122
123 14
            return $this->getArticleMeta($article);
124 6
        } elseif ($responseType === LoaderInterface::COLLECTION) {
125 6
            $route = null;
126 6
            if (array_key_exists('route', $parameters)) {
127 6
                $route = $this->dm->find(null, $this->pathBuilder->build($this->routeBasepaths[0].$parameters['route']));
0 ignored issues
show
Bug introduced by
It seems like $this->pathBuilder->buil.... $parameters['route']) targeting SWP\Component\MultiTenan...ilderInterface::build() can also be of type array; however, Doctrine\ODM\PHPCR\DocumentManager::find() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
128 3
            } elseif (null !== ($currentPage = $this->context->getCurrentPage())) {
129 2
                $route = $currentPage->getValues();
130
            }
131
132 6
            if (null !== $route && is_object($route)) {
133 6
                $identifier = $this->dm->getNodeForDocument($route)->getIdentifier();
134 6
                $query = $this->dm->createPhpcrQuery($this->getQueryString($identifier, $parameters), QueryInterface::JCR_SQL2);
135 5
                $countQuery = clone $query;
136
137 5
                if (isset($parameters['limit'])) {
138 1
                    $query->setLimit($parameters['limit']);
139
                }
140
141 5
                if (isset($parameters['start'])) {
142 1
                    $query->setOffset($parameters['start']);
143
                }
144
145 5
                $articles = $this->dm->getDocumentsByPhpcrQuery($query);
146 5
                $metaCollection = new MetaCollection();
147 5
                $metaCollection->setTotalItemsCount($countQuery->execute()->getRows()->count());
148 5
                foreach ($articles as $article) {
149 5
                    $articleMeta = $this->getArticleMeta($article);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $articleMeta is correct as $this->getArticleMeta($article) (which targets SWP\Bundle\ContentBundle...oader::getArticleMeta()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
150 5
                    if ($articleMeta) {
151 5
                        $metaCollection->add($articleMeta);
152
                    }
153
                }
154
155 5
                return $metaCollection;
156
            }
157
        }
158
159 1
        return;
160
    }
161
162
    /**
163
     * Checks if Loader supports provided type.
164
     *
165
     * @param string $type
166
     *
167
     * @return bool
168
     */
169 17
    public function isSupported($type)
170
    {
171 17
        return in_array($type, ['articles', 'article']);
172
    }
173
174 17
    private function getArticleMeta($article)
175
    {
176 17
        if (!is_null($article)) {
177 15
            return $this->metaFactory->create($article);
178
        }
179
180 4
        return;
181
    }
182
183 6
    private function getQueryString($identifier, $parameters)
184
    {
185 6
        $queryStr = sprintf("SELECT * FROM [nt:unstructured] as S WHERE S.phpcr:class='SWP\Bundle\ContentBundle\Doctrine\ODM\PHPCR\Article' AND S.route=%s AND S.status=published", $identifier);
186 6
        if (isset($parameters['order'])) {
187 3
            $order = $parameters['order'];
188 3
            if (!is_array($order) || count($order) !== 2 || (strtoupper($order[1]) != 'ASC' && strtoupper($order[1]) != 'DESC')) {
189
                throw new \Exception('Order filter must have two parameters with second one asc or desc, e.g. order(id, desc)');
190
            }
191 3
            if ($order[0] === 'id') {
192 1
                $order[0] = 'jcr:uuid';
193
            } else {
194
                // Check that the given parameter is actually a field name of a route
195 2
                $metaData = $this->dm->getClassMetadata('SWP\Bundle\ContentBundle\Doctrine\ODM\PHPCR\Article');
196 2
                if (!in_array($order[0], $metaData->getFieldNames())) {
197 1
                    throw new \Exception('Order parameter must be id or the name of one of the fields in the route class');
198
                }
199
            }
200 2
            $queryStr .= sprintf(' ORDER BY S.%s %s', $order[0], $order[1]);
201
        }
202
203 5
        return $queryStr;
204
    }
205
}
206