Completed
Push — master ( 71f037...5c5d5d )
by Andrew
04:58
created

updateMetadata()   C

Complexity

Conditions 7
Paths 36

Size

Total Lines 34
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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