Issues (66)

src/Traits/SeoManagerTrait.php (6 issues)

Labels
Severity
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: sergeykarakhanyan
5
 * Date: 10/30/18
6
 * Time: 12:00
7
 */
8
9
namespace Lionix\SeoManager\Traits;
10
11
use Illuminate\Support\Facades\File;
12
use Lionix\SeoManager\Models\SeoManager;
13
use Illuminate\Support\Facades\Schema;
14
15
trait SeoManagerTrait
16
{
17
    protected $exceptRoutes = [
18
        'api',
19
        'telescope',
20
        '_debugbar'
21
    ];
22
23
    protected $exceptColumns = [
24
        "password",
25
        "remember_token",
26
    ];
27
28
    public function __construct()
29
    {
30
        $this->exceptRoutes = array_merge($this->exceptRoutes, config('seo-manager.except_routes'));
0 ignored issues
show
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

30
        $this->exceptRoutes = array_merge($this->exceptRoutes, /** @scrutinizer ignore-call */ config('seo-manager.except_routes'));
Loading history...
31
        $this->exceptColumns = array_merge($this->exceptColumns, config('seo-manager.except_columns'));
32
    }
33
34
    /**
35
     * Detect Parameters from the URI
36
     * @param $uri
37
     * @return mixed
38
     */
39
    private function getParamsFromURI($uri)
40
    {
41
        preg_match_all('/{(.*?)}/', $uri, $output_array);
42
43
        return $output_array[1];
44
    }
45
46
    /**
47
     * Check if the given data is URI param
48
     * @param $param
49
     * @return bool
50
     */
51
    private function isParam($param)
52
    {
53
        $pattern_params = '/{(.*?)}/';
54
        preg_match_all($pattern_params, $param, $output_params);
55
        if (!empty($output_params[1])) {
56
            return true;
57
        }
58
        return false;
59
    }
60
61
    /**
62
     * Check if the given data is Title
63
     * @param $param
64
     * @return bool
65
     */
66
    private function isTitle($param)
67
    {
68
        $pattern_title = '/~(.*?)~/';
69
        preg_match_all($pattern_title, $param, $pattern_title);
70
        if (!empty($pattern_title[1])) {
71
            return true;
72
        }
73
        return false;
74
    }
75
76
    /**
77
     * Remove unnecessary characters from param
78
     * @param $param
79
     * @return string
80
     */
81
    private function cleanParam($param)
82
    {
83
        return strtolower(str_replace(['{', '}'], '', $param));
84
    }
85
86
    /**
87
     * Remove routes which shouldn't be imported to Seo Manager
88
     * @return array
89
     */
90
    private function cleanRoutes()
91
    {
92
        $routes = \Route::getRoutes();
93
        $getRoutes = array_keys($routes->get('GET'));
94
        foreach ($getRoutes as $key => $route) {
95
            foreach ($this->exceptRoutes as $rule) {
96
                if (strpos($route, $rule) !== FALSE) {
97
                    unset($getRoutes[$key]);
98
                }
99
            }
100
        }
101
        return $getRoutes;
102
    }
103
104
    /**
105
     * @return array
106
     * @throws \ReflectionException
107
     */
108
    private function getAllModels()
109
    {
110
        $path = base_path('app') . '/' . config('seo-manager.models_path');
0 ignored issues
show
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
        $path = base_path('app') . '/' . /** @scrutinizer ignore-call */ config('seo-manager.models_path');
Loading history...
The function base_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
        $path = /** @scrutinizer ignore-call */ base_path('app') . '/' . config('seo-manager.models_path');
Loading history...
111
112
        $models = File::allFiles($path);
113
        $cleanModelNames = [];
114
        foreach ($models as $model) {
115
            $modelPath = $this->cleanFilePath($model);
116
            $reflectionClass =(new \ReflectionClass($modelPath))->getParentClass();
117
            if($reflectionClass !== false){
118
                if($reflectionClass->getName() === "Illuminate\Database\Eloquent\Model" || $reflectionClass->getName() === "Illuminate\Foundation\Auth\User"){
119
                    $cleanModel = [
120
                        'path' => $modelPath,
121
                        'name' => str_replace('.php', '', $model->getFilename())
122
                    ];
123
                    array_push($cleanModelNames, $cleanModel);
124
                }
125
            }
126
        }
127
        return $cleanModelNames;
128
    }
129
130
    /**
131
     * Get Model all Columns
132
     * @param $model
133
     * @return array
134
     */
135
    public function getColumns($model)
136
    {
137
        $appends = [];
138
        if (method_exists((new $model), 'getAppends')) {
139
            $appends = (new $model)->getAppends();
140
        }
141
        $table = (new $model)->getTable();
142
        $columns = $this->getCleanColumns(Schema::getColumnListing($table));
143
        return array_merge($columns, $appends);
144
    }
145
146
    /**
147
     * Clean model file path
148
     * @param $file
149
     * @return string
150
     */
151
    private function cleanFilePath($file)
152
    {
153
        return '\\' . ucfirst(str_replace('/', '\\', substr($file, strpos($file, 'app'), -4)));
154
    }
155
156
    /**
157
     * Remove unnecessary columns from table columns list
158
     * @param $columns
159
     * @return array
160
     */
161
    private function getCleanColumns($columns)
162
    {
163
        return array_diff($columns, $this->exceptColumns);
164
    }
165
166
    /**
167
     * Import Routes to SeoManager database
168
     * @return array|\Illuminate\Database\Eloquent\Collection|static[]
0 ignored issues
show
The type Illuminate\Database\Eloquent\Collection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
169
     */
170
    private function importRoutes()
171
    {
172
        $routes = $this->cleanRoutes();
173
        foreach ($routes as $uri) {
174
            $data = [
175
                'uri' => $uri,
176
                'params' => $this->getParamsFromURI($uri),
177
                'keywords' => [],
178
                'title_dynamic' => []
179
            ];
180
            if (!SeoManager::where('uri', $uri)->first()) {
181
                $seoManager = new SeoManager();
182
                $seoManager->fill($data);
183
                $seoManager->save();
184
            }
185
        }
186
187
        $routes = SeoManager::all();
188
        return $routes;
189
    }
190
191
    /**
192
     * Get mapped Seo Data from Database for Current Route
193
     * @param $property
194
     * @return mixed
195
     */
196
    private function getMetaData($property)
197
    {
198
        $route = \Route::current();
199
        if (is_null($route)){
200
            return null;
201
        }
202
        $uri = $route->uri();
203
        $seoManager = SeoManager::where('uri', $uri)->first();
204
        if(is_null($seoManager)){
205
            return null;
206
        }
207
        $metaData = [];
208
        if(count($seoManager->keywords) > 0){
209
            $metaData['keywords'] = implode(', ', $seoManager->keywords);
210
        }
211
        if($seoManager->description){
212
            $metaData['description'] = $seoManager->description;
213
        }
214
        if($seoManager->title){
215
            $metaData['title'] = $seoManager->title;
216
        }
217
        if($seoManager->url){
218
            $metaData['url'] = $seoManager->url;
219
        }else{
220
            $metaData['url'] = url()->full();
0 ignored issues
show
The function url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

220
            $metaData['url'] = /** @scrutinizer ignore-call */ url()->full();
Loading history...
221
        }
222
        if($seoManager->author){
223
            $metaData['author'] = $seoManager->author;
224
        }
225
        if ($seoManager->mapping !== null) {
226
            $metaData['title_dynamic'] = $this->getDynamicTitle($seoManager->title_dynamic, $seoManager, $route->parameters);
227
        }
228
        if ($seoManager->og_data) {
229
            $ogData = $this->getOgData($seoManager, $route->parameters);
230
            if($property === 'og_data'){
231
                $metaData['og_data'] = $ogData;
232
            }else{
233
                foreach ($ogData as $key => $og) {
234
                    $metaData[$key] = $og;
235
                }
236
            }
237
        }
238
239
        if($property !== null && !empty($property)){
240
            if(isset($metaData[$property])){
241
                return $metaData[$property];
242
            }else{
243
                return null;
244
            }
245
        }
246
        return $metaData;
247
    }
248
249
    /**
250
     * Get dynamic title based on user configs for current route
251
     * @param $params
252
     * @param $manager
253
     * @param $routeParams
254
     * @return string
255
     */
256
    private function getDynamicTitle($params, $manager, $routeParams = null)
257
    {
258
        $dynamicTitle = '';
259
        if(is_array($params)){
260
            foreach ($params as $param) {
261
                if ($this->isParam($param)) {
262
                    $param = $this->cleanParam($param);
263
                    $paramsArray = explode('-', $param);
264
                    $mapping = $manager->mapping[$paramsArray[0]];
265
                    $model = $mapping['model']['path'];
266
                    $findBy = $mapping['find_by'];
267
                    $selectedColumns = $mapping['selectedColumns'];
268
269
                    if (in_array($paramsArray[1], $selectedColumns)) {
270
                        $mappedTitle = (new $model);
271
272
                        if ($routeParams) {
273
                            $value = is_a($routeParams[$paramsArray[0]], $model) ? $routeParams[$paramsArray[0]]->$findBy : $routeParams[$paramsArray[0]];
274
                            $mappedTitle = $mappedTitle->where($findBy, $value)->first();
275
                        } else {
276
                            $mappedTitle = $mappedTitle->first();
277
                        }
278
279
                        if ($mappedTitle) {
280
                            $dynamicTitle .= optional($mappedTitle)->{$paramsArray[1]} . ' ';
281
                        }
282
                    }
283
                } elseif ($this->isTitle($param)) {
284
                    $dynamicTitle .= $manager->title . ' ';
285
                } else {
286
                    $dynamicTitle .= $param . ' ';
287
                }
288
            }
289
        }
290
        return $dynamicTitle;
291
    }
292
293
    /**
294
     * Get Open Graph Dynamic Data
295
     * @param $seoManager
296
     * @param $routeParams
297
     * @return array
298
     */
299
    private function getOgData($seoManager, $routeParams)
300
    {
301
        $dataArray = [];
302
        $value = '';
303
        foreach ($seoManager->og_data as $key => $og) {
304
            if (is_array(reset($og['data']))) {
305
                foreach ($og['data'] as $ogKey => $data) {
306
                    if ($data['mapped']) {
307
                        $value = $this->getMappedValue($data['value'], $seoManager, $routeParams);
308
                    } elseif ($data['value']) {
309
                        $value = $data['value'];
310
                    }
311
                    if ($data['value']) {
312
                        $dataArray['og:' . $key . ':' . $ogKey] = $value;
313
                    }
314
                }
315
            } else {
316
                if ($og['data']['mapped']) {
317
                    $value = $this->getMappedValue($og['data']['value'], $seoManager, $routeParams);
318
                } elseif ($og['data']['value']) {
319
                    $value = $og['data']['value'];
320
                } elseif ($key === 'url') {
321
                    $value = url()->full();
0 ignored issues
show
The function url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

321
                    $value = /** @scrutinizer ignore-call */ url()->full();
Loading history...
322
                }
323
                if ($og['data']['value'] || $key === 'url') {
324
                    $dataArray['og:' . $key] = $value;
325
                }
326
            }
327
        }
328
        return $dataArray;
329
    }
330
331
    /**
332
     * Get Open Graph Data Values based on Mapped Params
333
     * @param $value
334
     * @param $manager
335
     * @param $routeParams
336
     * @return mixed
337
     */
338
    private function getMappedValue($value, $manager, $routeParams)
339
    {
340
        $paramsArray = explode('-', strtolower($value));
341
        $mapping = $manager->mapping[$paramsArray[0]];
342
        $model = $mapping['model']['path'];
343
        $findBy = $mapping['find_by'];
344
        $selectedColumns = $mapping['selectedColumns'];
345
        $mapped = null;
346
        if (in_array($paramsArray[1], $selectedColumns)) {
347
            $mapped = (new $model);
348
            if ($routeParams) {
349
                $mapped = $mapped->where($findBy, $routeParams[$paramsArray[0]])->first();
350
            }else{
351
                $mapped = $mapped->first();
352
            }
353
        }
354
        return optional($mapped)->{$paramsArray[1]};
355
    }
356
}
357