Issues (216)

src/Extensions/ElementalPageExtension.php (4 issues)

1
<?php
2
3
namespace DNADesign\Elemental\Extensions;
4
5
use DNADesign\Elemental\Models\BaseElement;
6
use DNADesign\Elemental\Models\ElementalArea;
7
use SilverStripe\CMS\Model\SiteTree;
8
use SilverStripe\Control\Controller;
9
use SilverStripe\View\Parsers\HTML4Value;
10
use SilverStripe\View\SSViewer;
11
12
/**
13
 * @method ElementalArea ElementalArea()
14
 * @property int ElementalAreaID
15
 */
16
class ElementalPageExtension extends ElementalAreasExtension
17
{
18
    private static $has_one = [
0 ignored issues
show
The private property $has_one is not used, and could be removed.
Loading history...
19
        'ElementalArea' => ElementalArea::class,
20
    ];
21
22
    private static $owns = [
0 ignored issues
show
The private property $owns is not used, and could be removed.
Loading history...
23
        'ElementalArea',
24
    ];
25
26
    private static $cascade_duplicates = [
0 ignored issues
show
The private property $cascade_duplicates is not used, and could be removed.
Loading history...
27
        'ElementalArea',
28
    ];
29
30
    /**
31
     * The delimiter to separate distinct elements in indexed content.
32
     *
33
     * When using the getElementsForSearch() method to index all elements in a single field,
34
     * a custom delimiter can be used help to avoid false positive results for phrase queries.
35
     *
36
     * @config
37
     * @var string
38
     */
39
    private static $search_index_element_delimiter = ' ';
0 ignored issues
show
The private property $search_index_element_delimiter is not used, and could be removed.
Loading history...
40
41
    /**
42
     * Returns the contents of each ElementalArea has_one's markup for use in Solr or Elastic search indexing
43
     *
44
     * @return string
45
     */
46
    public function getElementsForSearch()
47
    {
48
        $oldThemes = SSViewer::get_themes();
49
        SSViewer::set_themes(SSViewer::config()->get('themes'));
50
        try {
51
            $output = [];
52
            $this->loopThroughElements(function (BaseElement $element) use (&$output) {
53
                if ($element->getSearchIndexable()) {
54
                    $content = $element->getContentForSearchIndex();
55
                    if ($content) {
56
                        $output[] = $content;
57
                    }
58
                }
59
            });
60
        } finally {
61
            // Reset theme if an exception occurs, if you don't have a
62
            // try / finally around code that might throw an Exception,
63
            // CMS layout can break on the response. (SilverStripe 4.1.1)
64
            SSViewer::set_themes($oldThemes);
65
        }
66
        return implode($this->owner->config()->get('search_index_element_delimiter') ?? '', $output);
67
    }
68
69
    /**
70
     * @see SiteTree::getAnchorsOnPage()
71
     */
72
    public function updateAnchorsOnPage(array &$anchors): void
73
    {
74
        if (!($this->owner instanceof SiteTree)) {
75
            return;
76
        }
77
        $this->loopThroughElements(function (BaseElement $element) use (&$anchors) {
78
            $anchors = array_merge($anchors, $element->getAnchorsInContent());
79
        });
80
    }
81
82
    public function MetaTags(&$tags)
83
    {
84
        if (!Controller::has_curr()) {
85
            return;
86
        }
87
        $controller = Controller::curr();
88
        $request = $controller->getRequest();
89
        if ($request->getVar('ElementalPreview') !== null) {
90
            $html = HTML4Value::create($tags);
91
            $xpath = "//meta[@name='x-page-id' or @name='x-cms-edit-link']";
92
            $removeTags = $html->query($xpath);
93
            $body = $html->getBody();
94
            foreach ($removeTags as $tag) {
95
                $body->removeChild($tag);
96
            }
97
            $tags = $html->getContent();
98
        }
99
    }
100
101
    /**
102
     * Call some function over all elements belonging to this page
103
     */
104
    private function loopThroughElements(callable $callback): void
105
    {
106
        foreach ($this->owner->hasOne() as $key => $class) {
107
            if ($class !== ElementalArea::class) {
108
                continue;
109
            }
110
            /** @var ElementalArea $area */
111
            $area = $this->owner->$key();
112
            if ($area) {
113
                foreach ($area->Elements() as $element) {
114
                    $callback($element);
115
                }
116
            }
117
        }
118
    }
119
}
120