Issues (260)

src/controllers/ContentSeoController.php (2 issues)

1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS
4
 *
5
 * @link      https://nystudio107.com/
6
 * @copyright Copyright (c) 2019 nystudio107
7
 * @license   https://nystudio107.com/license
8
 */
9
10
namespace nystudio107\seomatic\controllers;
11
12
use Craft;
13
use craft\helpers\UrlHelper;
14
use craft\web\Controller;
15
use nystudio107\seomatic\base\SeoElementInterface;
16
use nystudio107\seomatic\helpers\ArrayHelper;
17
use nystudio107\seomatic\Seomatic;
18
use yii\web\BadRequestHttpException;
19
use yii\web\Response;
20
use function count;
21
22
/**
23
 * @author    nystudio107
24
 * @package   Seomatic
25
 * @since     3.2.18
26
 */
27
class ContentSeoController extends Controller
28
{
29
    // Constants
30
    // =========================================================================
31
32
    public const SORT_MAP = [
33
        'DESC' => SORT_DESC,
34
        'ASC' => SORT_ASC,
35
    ];
36
37
    public const ALLOWED_SORT_FIELDS = [
38
        'sourceName',
39
        'sourceType',
40
    ];
41
42
    // Protected Properties
43
    // =========================================================================
44
45
    /**
46
     * @inheritdoc
47
     */
48
    protected array|bool|int $allowAnonymous = [
49
    ];
50
51
    // Public Methods
52
    // =========================================================================
53
54
    /**
55
     * Handle requests for the dashboard statistics table
56
     *
57
     * @param string $sort
58
     * @param int $page
59
     * @param int $per_page
60
     * @param string $filter
61
     * @param null|int $siteId
62
     *
63
     * @return Response
64
     * @throws BadRequestHttpException
65
     */
66
    public function actionMetaBundles(
67
        string $sort = 'sourceName|asc',
68
        int    $page = 1,
69
        int    $per_page = 20,
70
               $filter = '',
71
               $siteId = 0,
72
    ): Response {
73
        $data = [];
74
        $sortField = 'sourceName';
75
        $sortType = 'ASC';
76
        // Figure out the sorting type
77
        if ($sort !== '') {
78
            if (strpos($sort, '|') === false) {
79
                $sortField = $sort;
80
            } else {
81
                list($sortField, $sortType) = explode('|', $sort);
82
            }
83
        }
84
        $sortType = strtoupper($sortType);
85
        $sortType = self::SORT_MAP[$sortType] ?? self::SORT_MAP['DESC'];
86
        $sortParams = [
87
            $sortField => $sortType,
88
        ];
89
        // Validate untrusted data
90
        if (!in_array($sortField, self::ALLOWED_SORT_FIELDS, true)) {
91
            throw new BadRequestHttpException(Craft::t('seomatic', 'Invalid sort field specified.'));
92
        }
93
        if ($sortField !== 'sourceName') {
94
            $sortParams = array_merge($sortParams, [
0 ignored issues
show
The assignment to $sortParams is dead and can be removed.
Loading history...
95
                'sourceName' => self::SORT_MAP['ASC'],
96
            ]);
97
        }
98
99
        // Query the db table
100
        $offset = ($page - 1) * $per_page;
101
        $currentSiteHandle = '';
102
        if ((int)$siteId !== 0) {
103
            $site = Craft::$app->getSites()->getSiteById($siteId);
104
            if ($site !== null) {
105
                $currentSiteHandle = $site->handle;
106
            }
107
        }
108
        $metaBundles = Seomatic::$plugin->metaBundles->getContentMetaBundlesForSiteId($siteId, $filter);
109
        $count = 0;
0 ignored issues
show
The assignment to $count is dead and can be removed.
Loading history...
110
        if ($metaBundles) {
111
            $count = count($metaBundles);
112
            // Sort it manually
113
            ArrayHelper::multisort($metaBundles, $sortField, $sortType);
114
            $metaBundles = array_slice($metaBundles, $offset, $per_page);
115
            $dataArray = [];
116
            // Add in the `addLink` field
117
            foreach ($metaBundles as $metaBundle) {
118
                $dataItem = [];
119
                if ($metaBundle !== null) {
120
                    $sourceBundleType = $metaBundle->sourceBundleType;
121
                    $sourceHandle = $metaBundle->sourceHandle;
122
                    // For all the emojis
123
                    $dataItem['sourceName'] = html_entity_decode($metaBundle->sourceName, ENT_NOQUOTES, 'UTF-8');
124
                    $dataItem['sourceType'] = $metaBundle->sourceType;
125
                    $dataItem['contentSeoUrl'] = UrlHelper::cpUrl(
126
                        "seomatic/edit-content/general/{$sourceBundleType}/{$sourceHandle}/{$currentSiteHandle}"
127
                    );
128
                    // Fill in the number of entries
129
                    $entries = 0;
130
                    $seoElement = null;
131
                    if ($metaBundle->sourceBundleType) {
132
                        $seoElement = Seomatic::$plugin->seoElements->getSeoElementByMetaBundleType(
133
                            $metaBundle->sourceBundleType
134
                        );
135
                    }
136
                    /** @var SeoElementInterface $seoElement */
137
                    if ($seoElement !== null) {
138
                        // Ensure `null` so that the resulting element query is correct
139
                        if (empty($metaBundle->metaSitemapVars->sitemapLimit)) {
140
                            $metaBundle->metaSitemapVars->sitemapLimit = null;
141
                        }
142
                        $query = $seoElement::sitemapElementsQuery($metaBundle);
143
                        $entries = $query->count();
144
                    }
145
                    $dataItem['entries'] = $entries;
146
                    // Basic configuration setup
147
                    $dataItem['title'] = $metaBundle->metaGlobalVars->seoTitle !== '' ? 'enabled' : 'disabled';
148
                    $dataItem['description'] = $metaBundle->metaGlobalVars->seoDescription !== '' ? 'enabled' : 'disabled';
149
                    $dataItem['image'] = $metaBundle->metaGlobalVars->seoImage !== '' ? 'enabled' : 'disabled';
150
                    $dataItem['sitemap'] = $metaBundle->metaSitemapVars->sitemapUrls ? 'enabled' : 'disabled';
151
                    $dataItem['sitemapPriority'] = $metaBundle->metaSitemapVars->sitemapPriority;
152
                    $dataItem['sitemapFrequency'] = $metaBundle->metaSitemapVars->sitemapChangeFreq;
153
                    $dataItem['robots'] = $metaBundle->metaGlobalVars->robots;
154
                    // Calculate the setup stat
155
                    $stat = 0;
156
                    $numGrades = count(SettingsController::SETUP_GRADES);
157
                    $numFields = count(SettingsController::SEO_SETUP_FIELDS);
158
                    foreach (SettingsController::SEO_SETUP_FIELDS as $setupField => $setupLabel) {
159
                        $stat += (int)!empty($metaBundle->metaGlobalVars[$setupField]);
160
                        $value = $variables['contentSetupChecklist'][$setupField]['value'] ?? 0;
161
                        $variables['contentSetupChecklist'][$setupField] = [
162
                            'label' => $setupLabel,
163
                            'value' => $value + (int)!empty($metaBundle->metaGlobalVars[$setupField]),
164
                        ];
165
                    }
166
                    $stat = round($numGrades - (($stat * $numGrades) / $numFields));
167
                    if ($stat >= $numGrades) {
168
                        $stat = $numGrades - 1;
169
                    }
170
                    $dataItem['setup'] = SettingsController::SETUP_GRADES[$stat];
171
172
                    $dataArray[] = $dataItem;
173
                }
174
            }
175
            // Format the data for the API
176
            $data['data'] = $dataArray;
177
            $data['links']['pagination'] = [
178
                'total' => $count,
179
                'per_page' => $per_page,
180
                'current_page' => $page,
181
                'last_page' => ceil($count / $per_page),
182
                'next_page_url' => null,
183
                'prev_page_url' => null,
184
                'from' => $offset + 1,
185
                'to' => $offset + ($count > $per_page ? $per_page : $count),
186
            ];
187
        }
188
189
        return $this->asJson($data);
190
    }
191
192
    // Protected Methods
193
    // =========================================================================
194
}
195