getSEOFields()   B
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 8.7972
c 0
b 0
f 0
cc 4
eloc 13
nc 8
nop 0
1
<?php
2
/**
3
 * Extends SiteTree with basic metadata fields, as well as the main `Metadata()` method.
4
 *
5
 * @package silverstripe-seo
6
 * @subpackage metadata
7
 * @author Andrew Gerber <[email protected]>
8
 * @version 1.0.0
9
 */
10
11
/**
12
 * Class SEO_Metadata_SiteTree_DataExtension
13
 */
14
class SEO_Metadata_SiteTree_DataExtension extends DataExtension
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
15
{
16
17
    /* Overload Model
18
    ------------------------------------------------------------------------------*/
19
20
    /**
21
     * Database attributes.
22
     *
23
     * @var array $db
24
     */
25
    private static $db = array(
0 ignored issues
show
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
26
        'MetaTitle' => 'Varchar(128)',
27
        'MetaDescription' => 'Text', // redundant, but included for backwards-compatibility
28
        'ExtraMeta' => 'HTMLText', // redundant, but included for backwards-compatibility
29
    );
30
31
32
    /* Overload Methods
33
    ------------------------------------------------------------------------------*/
34
35
    // @todo @inheritdoc ?? or does it happen automagically as promised?
36
    public function updateCMSFields(FieldList $fields)
37
    {
38
        // Remove framework default metadata group
39
        $fields->removeByName(array('Metadata'));
40
        // Add SEO
41
        $fields->addFieldsToTab('Root.Metadata.SEO', $this->owner->getSEOFields());
42
        // Add full output
43
        $fields->addFieldsToTab('Root.Metadata.FullOutput', $this->owner->getFullOutput());
44
    }
45
46
    /**
47
     * Gets SEO fields.
48
     *
49
     * @return array
50
     */
51
    public function getSEOFields()
52
    {
53
        // Variables
54
        $config = SiteConfig::current_site_config();
55
        $SEO = [];
56
        // Canonical
57
        if ($config->CanonicalEnabled()) {
58
            $SEO[] = ReadonlyField::create('ReadonlyMetaCanonical', 'link rel="canonical"', $this->owner->AbsoluteLink());
59
        }
60
        // Title
61
        if ($config->TitleEnabled()) {
62
            $SEO[] = TextField::create('MetaTitle', 'meta title')
63
                ->setAttribute('placeholder', $this->owner->GenerateTitle());
64
        }
65
        // Description
66
        $SEO[] = TextareaField::create('MetaDescription', 'meta description')
67
            ->setAttribute('placeholder', $this->owner->GenerateDescriptionFromContent());
68
        // ExtraMeta
69
        if ($config->ExtraMetaEnabled()) {
70
            $SEO[] = TextareaField::create('ExtraMeta', 'Custom Metadata');
71
        }
72
        return $SEO;
73
    }
74
75
    /**
76
     * Gets the full output.
77
     *
78
     * @return array
79
     */
80
    public function getFullOutput()
81
    {
82
        return array(
83
            LiteralField::create('HeaderMetadata', '<pre class="bold">$Metadata()</pre>'),
84
            LiteralField::create('LiteralMetadata', '<pre>' . nl2br(htmlentities(trim($this->owner->Metadata()), ENT_QUOTES)) . '</pre>')
85
        );
86
    }
87
88
    /**
89
     * Main function to format & output metadata as an HTML string.
90
     *
91
     * Use the `updateMetadata($config, $owner, $metadata)` update hook when extending `DataExtension`s.
92
     *
93
     * @return string
94
     */
95
    public function Metadata()
96
    {
97
        // variables
98
        $config = SiteConfig::current_site_config();
99
        // begin SEO
100
        $metadata = PHP_EOL . $this->owner->MarkupComment('SEO');
101
        // register extension update hook
102
        $this->owner->extend('updateMetadata', $config, $this->owner, $metadata);
103
        // end
104
        $metadata .= $this->owner->MarkupComment('END SEO');
105
        // return
106
        return $metadata;
107
    }
108
109
110
    /* Template Methods
111
    ------------------------------------------------------------------------------*/
112
113
    /**
114
     * Updates metadata fields.
115
     *
116
     * @param SiteConfig $config
117
     * @param SiteTree $owner
118
     * @param string $metadata
119
     *
120
     * @return void
121
     */
122
    public function updateMetadata(SiteConfig $config, SiteTree $owner, &$metadata)
123
    {
124
        // metadata
125
        $metadata .= $owner->MarkupComment('Metadata');
126
        // charset
127
        if ($config->CharsetEnabled()) {
128
            $metadata .= '<meta charset="' . $config->Charset() . '" />' . PHP_EOL;
129
        }
130
        // canonical
131
        if ($config->CanonicalEnabled()) {
132
            $metadata .= $owner->MarkupLink('canonical', $owner->AbsoluteLink());
133
        }
134
        // title
135
        if ($config->TitleEnabled()) {
136
            $metadata .= '<title>' . $owner->encodeContent($owner->GenerateTitle(), $config->Charset()) . '</title>' . PHP_EOL;
137
        }
138
        // description
139
        if ($description = $owner->GenerateDescription()) {
140
            $metadata .= $owner->MarkupMeta('description', $description, $config->Charset());
141
        }
142
        // extra metadata
143
        if ($config->ExtraMetaEnabled()) {
144
            $metadata .= $owner->MarkupComment('Extra Metadata');
145
            $metadata .= $owner->GenerateExtraMeta();
146
        }
147
    }
148
149
150
    /* Markup Methods
151
    ------------------------------------------------------------------------------*/
152
153
    /**
154
     * Returns a given string as a HTML comment.
155
     *
156
     * @param string $comment
157
     *
158
     * @return string
159
     */
160
    public function MarkupComment($comment)
161
    {
162
        return '<!-- ' . $comment . ' -->' . PHP_EOL;
163
    }
164
165
    /**
166
     * Returns markup for a HTML meta element. Can be flagged for encoding.
167
     *
168
     * @param string $name
169
     * @param string $content
170
     * @param string|null $encode
171
     *
172
     * @return string
173
     */
174
    public function MarkupMeta($name, $content, $encode = null)
175
    {
176
        if ($encode !== null) {
177
            return '<meta name="' . $name . '" content="' . $this->encodeContent($content, $encode) . '" />' . PHP_EOL;
178
        } else {
179
            return '<meta name="' . $name . '" content="' . $content . '" />' . PHP_EOL;
180
        }
181
    }
182
183
    /**
184
     * Returns markup for a HTML link element.
185
     *
186
     * @param string $rel
187
     * @param string $href
188
     * @param string|null $type
189
     * @param string|null $sizes
190
     *
191
     * @return string
192
     */
193
    public function MarkupLink($rel, $href, $type = null, $sizes = null)
194
    {
195
        // start fragment
196
        $return = '<link rel="' . $rel . '" href="' . $href . '"';
197
        // if type
198
        if ($type !== null) {
199
            $return .= ' type="' . $type . '"';
200
        }
201
        // if sizes
202
        if ($sizes !== null) {
203
            $return .= ' sizes="' . $sizes . '"';
204
        }
205
        // end fragment
206
        $return .= ' />' . PHP_EOL;
207
        // return
208
        return $return;
209
    }
210
211
212
    /* Generation Methods
213
    ------------------------------------------------------------------------------*/
214
215
    /**
216
     * Generates HTML title based on configuration settings.
217
     *
218
     * @return string|null
219
     */
220
    public function GenerateTitle()
221
    {
222
        if ($this->owner->MetaTitle) {
223
            return $this->owner->MetaTitle;
224
        } else {
225
            return SiteConfig::current_site_config()->GenerateTitle($this->owner->Title);
226
        }
227
    }
228
229
    /**
230
     * Generates description from the page `MetaDescription`, or the first paragraph of the `Content` attribute.
231
     *
232
     * @return string|null
233
     */
234
    public function GenerateDescription()
235
    {
236
        if ($this->owner->MetaDescription) {
237
            return $this->owner->MetaDescription;
238
        } else {
239
            return $this->owner->GenerateDescriptionFromContent();
240
        }
241
    }
242
243
    /**
244
     * Generates description from the first paragraph of the `Content` attribute.
245
     *
246
     * @return string|null
247
     */
248
    public function GenerateDescriptionFromContent()
249
    {
250
        // check for content
251
        if ($content = trim($this->owner->Content)) {
252
            // pillage first paragraph from page content
253
            if (preg_match('/<p>(.*?)<\/p>/i', $content, $match)) {
254
                // is HTML
255
                $content = $match[0];
256
            } else {
257
                // is plain text
258
                $content = explode(PHP_EOL, $content);
259
                $content = $content[0];
260
            }
261
            // decode (no harm done) & return
262
            return trim(html_entity_decode(strip_tags($content)));
263
        } else {
264
            return null;
265
        }
266
    }
267
268
    /**
269
     * Generates extra metadata.
270
     *
271
     * @return string
272
     */
273
    public function GenerateExtraMeta()
274
    {
275
        if ($this->owner->ExtraMeta) {
276
            return $this->owner->ExtraMeta . PHP_EOL;
277
        } else {
278
            return $this->owner->MarkupComment('none');
279
        }
280
    }
281
282
283
    /* Utility Methods
284
    --------------------------------------------------------------------------*/
285
286
    /**
287
     * Returns a plain or HTML-encoded string according to the current charset & encoding settings.
288
     *
289
     * @param string $content
290
     * @param string $charset
291
     *
292
     * @return string
293
     */
294
    public function encodeContent($content, $charset)
295
    {
296
        return htmlentities($content, ENT_QUOTES, $charset);
297
    }
298
299
}
300