Completed
Push — master ( a8e226...21664d )
by Andrew
01:38
created

GenerateDescriptionFromContent()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 3
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
        // Variables
39
        $config = SiteConfig::current_site_config();
40
        $owner = $this->owner;
41
42
        // Remove framework default metadata group
43
        $fields->removeByName(array('Metadata'));
44
45
        //// Metadata
46
47
        $tab = 'Root.Metadata.SEO';
48
49
        // Canonical
50
        if ($config->CanonicalEnabled()) {
51
            $fields->addFieldsToTab($tab, array(
52
                ReadonlyField::create('ReadonlyMetaCanonical', 'link rel="canonical"', $owner->AbsoluteLink())
53
            ));
54
        }
55
56
        // Title
57
        if ($config->TitleEnabled()) {
58
            $fields->addFieldsToTab($tab, array(
59
                TextField::create('MetaTitle', 'meta title')
60
                    ->setAttribute('placeholder', $owner->GenerateTitle())
61
            ));
62
        }
63
64
        // Description
65
        $fields->addFieldsToTab($tab, array(
66
            TextareaField::create('MetaDescription', 'meta description')
67
                ->setAttribute('placeholder', $owner->GenerateDescriptionFromContent())
68
        ));
69
70
        // ExtraMeta
71
        if ($config->ExtraMetaEnabled()) {
72
            $fields->addFieldsToTab($tab, array(
73
                TextareaField::create('ExtraMeta', 'Custom Metadata')
74
            ));
75
        }
76
77
        //// Full Output
78
79
        $tab = 'Root.Metadata.FullOutput';
80
81
        // monospaced, HTML SEO output
82
        $fields->addFieldsToTab($tab, array(
83
            LiteralField::create('HeaderMetadata', '<pre class="bold">$Metadata()</pre>'),
84
            LiteralField::create('LiteralMetadata', '<pre>' . nl2br(htmlentities(trim($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
        $owner = $this->owner;
100
101
        // begin SEO
102
        $metadata = PHP_EOL . $owner->MarkupComment('SEO');
103
104
        // metadata
105
        $metadata .= $owner->MarkupComment('Metadata');
106
107
        // charset
108
        if ($config->CharsetEnabled()) {
109
            $metadata .= '<meta charset="' . $config->Charset() . '" />' . PHP_EOL;
110
        }
111
112
        // canonical
113
        if ($config->CanonicalEnabled()) {
114
            $metadata .= $owner->MarkupLink('canonical', $owner->AbsoluteLink());
115
        }
116
117
        // title
118
        if ($config->TitleEnabled()) {
119
            // ternary setter
120
            $title = ($owner->MetaTitle) ? $owner->MetaTitle : $owner->GenerateTitle();
121
            // safe output
122
            $metadata .= '<title>' . htmlentities($title, ENT_QUOTES, $config->Charset()) . '</title>' . PHP_EOL;
123
        }
124
125
        // description
126
        $metadata .= $owner->MarkupMeta('description', $owner->GenerateDescription(), true, $config->Charset());
127
128
        // extra metadata
129
        if ($config->ExtraMetaEnabled()) {
130
            if ($extraMeta = $owner->ExtraMeta != '') {
0 ignored issues
show
Unused Code introduced by
$extraMeta is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
131
                $metadata .= $owner->MarkupComment('Extra Metadata');
132
                $metadata .= $owner->ExtraMeta . PHP_EOL;
133
            }
134
        }
135
136
        // extension update hook
137
        $owner->extend('updateMetadata', $config, $owner, $metadata);
138
139
        // end
140
        $metadata .= $owner->MarkupComment('END SEO');
141
142
        // return
143
        return $metadata;
144
    }
145
146
147
    /* Helper Methods
148
    ------------------------------------------------------------------------------*/
149
150
    /**
151
     * Returns a given string as a HTML comment.
152
     *
153
     * @var string $comment
154
     *
155
     * @return string
156
     */
157
    public function MarkupComment($comment)
158
    {
159
        return '<!-- ' . $comment . ' -->' . PHP_EOL;
160
    }
161
162
    /**
163
     * Returns markup for a HTML meta element.
164
     *
165
     * @var string $name
166
     * @var string $content
167
     * @var bool $encode
168
     *
169
     * @return string
170
     */
171
    public function MarkupMeta($name, $content, $encode = false)
172
    {
173
        return '<meta name="' . $name . '" content="' . $this->encodeContent($content, $encode) . '" />' . PHP_EOL;
174
    }
175
176
    /**
177
     * Returns markup for a HTML link element.
178
     *
179
     * @param string $rel
180
     * @param string $href
181
     * @param string $type
182
     * @param string $sizes
183
     *
184
     * @return string
185
     */
186
    public function MarkupLink($rel, $href, $type = '', $sizes = '')
187
    {
188
        // start fragment
189
        $return = '<link rel="' . $rel . '" href="' . $href . '"';
190
        // if type
191
        if ($type) {
192
            $return .= ' type="' . $type . '"';
193
        }
194
        // if sizes
195
        if ($sizes) {
196
            $return .= ' sizes="' . $sizes . '"';
197
        }
198
        // end fragment
199
        $return .= ' />' . PHP_EOL;
200
        // return
201
        return $return;
202
    }
203
204
205
    /* Meta Methods
206
    ------------------------------------------------------------------------------*/
207
208
    /**
209
     * Generates HTML title based on configuration settings.
210
     *
211
     * @return string|null
212
     */
213
    public function GenerateTitle()
214
    {
215
        return SiteConfig::current_site_config()->GenerateTitle($this->owner->Title);
216
    }
217
218
    /**
219
     * Returns description from the page `MetaDescription`, or the first paragraph of the `Content` attribute.
220
     *
221
     * @return string|null
222
     */
223
    public function GenerateDescription()
224
    {
225
        if ($this->owner->MetaDescription) {
226
            return $this->owner->MetaDescription;
227
        } else {
228
            return $this->owner->GenerateDescriptionFromContent();
229
        }
230
    }
231
232
    /**
233
     * Generates description from the first paragraph of the `Content` attribute.
234
     *
235
     * @return bool|string
236
     */
237
    public function GenerateDescriptionFromContent()
238
    {
239
        // check for content
240
        if ($content = trim($this->owner->Content)) {
241
            // pillage first paragraph from page content
242
            if (preg_match('/<p>(.*?)<\/p>/i', $content, $match)) {
243
                // is HTML
244
                $content = $match[0];
245
            } else {
246
                // is plain text
247
                $content = explode(PHP_EOL, $content);
248
                $content = $content[0];
249
            }
250
            // decode (no harm done) & return
251
            return trim(html_entity_decode(strip_tags($content)));
252
        } else {
253
            // none
254
            return false;
255
        }
256
    }
257
258
    /**
259
     * Returns a plain or HTML-encoded string according to the current charset & encoding settings.
260
     *
261
     * @param string $content
262
     * @param bool $encode
263
     *
264
     * @return string
265
     */
266
    public function encodeContent($content, $encode = true) {
267
        if ($encode) {
268
            return htmlentities($content, ENT_QUOTES, $this->owner->Charset);
269
        } else {
270
            return $content;
271
        }
272
    }
273
274
}
275