Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
SeoFieldsTrait
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 5
90
0.00% covered (danger)
0.00%
0 / 1
 getStandardSeoFields
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 getAllSeoFields
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 emptySeoFields
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 emptyTranslationFields
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 updateEmptySeoFields
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2declare(strict_types=1);
3
4namespace App\Model\Table;
5
6use Cake\Datasource\EntityInterface;
7
8/**
9 * SeoFieldsTrait
10 *
11 * Provides common SEO field management functionality for Table classes.
12 * This trait consolidates duplicate SEO field handling logic that was
13 * previously scattered across multiple table classes.
14 */
15trait SeoFieldsTrait
16{
17    /**
18     * Get the standard SEO fields used across the application
19     *
20     * @return array<string> List of standard SEO field names
21     */
22    protected function getStandardSeoFields(): array
23    {
24        return [
25            'meta_title',
26            'meta_description',
27            'meta_keywords',
28            'facebook_description',
29            'linkedin_description',
30            'twitter_description',
31            'instagram_description',
32        ];
33    }
34
35    /**
36     * Get all SEO fields for this table (override in table classes if needed)
37     *
38     * @return array<string> List of all SEO field names for this table
39     */
40    protected function getAllSeoFields(): array
41    {
42        return $this->getStandardSeoFields();
43    }
44
45    /**
46     * Checks if any of the SEO fields are empty
47     *
48     * @param \Cake\Datasource\EntityInterface $entity The entity to check
49     * @return array<string> List of empty SEO field names
50     */
51    public function emptySeoFields(EntityInterface $entity): array
52    {
53        $seoFields = $this->getAllSeoFields();
54
55        return array_filter($seoFields, fn($field) => empty($entity->{$field}));
56    }
57
58    /**
59     * Checks if any of the original language fields for translation are empty
60     *
61     * @param \Cake\Datasource\EntityInterface $entity The entity to check
62     * @return array<string> List of empty translation field names
63     */
64    public function emptyTranslationFields(EntityInterface $entity): array
65    {
66        if ($this->behaviors()->has('Translate')) {
67            $config = $this->behaviors()->get('Translate')->getConfig();
68
69            return array_filter($config['fields'], fn($field) => empty($entity->{$field}));
70        }
71
72        return [];
73    }
74
75    /**
76     * Update only empty SEO fields with new values
77     *
78     * @param \Cake\Datasource\EntityInterface $entity The entity to update
79     * @param array<string, string> $seoData Array of SEO field values
80     * @return array<string> List of fields that were updated
81     */
82    public function updateEmptySeoFields(EntityInterface $entity, array $seoData): array
83    {
84        $emptyFields = $this->emptySeoFields($entity);
85        $updatedFields = [];
86
87        foreach ($emptyFields as $field) {
88            if (isset($seoData[$field]) && !empty($seoData[$field])) {
89                $entity->{$field} = $seoData[$field];
90                $updatedFields[] = $field;
91            }
92        }
93
94        return $updatedFields;
95    }
96}