Completed
Push — master ( 54991b...612227 )
by Dev
13:09
created

AppExtension::renderEncodedMail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 5
rs 10
ccs 0
cts 0
cp 0
crap 2
1
<?php
2
3
namespace PiedWeb\CMSBundle\Twig;
4
5
use Cocur\Slugify\Slugify;
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\EntityManagerInterface;
8
use Exception;
9
use PiedWeb\CMSBundle\Entity\Media;
10
use PiedWeb\CMSBundle\Entity\PageInterface as Page;
11
use PiedWeb\CMSBundle\Service\MainContentManager;
12
use PiedWeb\CMSBundle\Service\PageCanonicalService;
13
use PiedWeb\RenderAttributes\AttributesTrait;
14
use Twig\Environment as Twig;
15
use Twig\Extension\AbstractExtension;
16
use Twig\TwigFilter;
17
use Twig\TwigFunction;
18
19
class AppExtension extends AbstractExtension
20
{
21
    use AttributesTrait;
22
23
    /** @var PageCanonicalService */
24
    protected $pageCanonical;
25
26
    /** @var EntityManagerInterface */
27
    private $em;
28
29
    /** @var string */
30
    private $page_class;
31
32
    public function __construct(EntityManager $em, string $page_class, PageCanonicalService $pageCanonical)
33
    {
34
        $this->em = $em;
35
        $this->pageCanonical = $pageCanonical;
36
        $this->page_class = $page_class;
37
    }
38
39
    public function getFilters()
40
    {
41
        return [
42
            //new TwigFilter('markdown', [AppExtension::class, 'markdownToHtml'], ['is_safe' => ['all']]),
43
            new TwigFilter('html_entity_decode', 'html_entity_decode'),
44
            new TwigFilter('preg_replace', [AppExtension::class, 'pregReplace']),
45
            new TwigFilter(
46
                'punctuation_beautifer',
47
                [MainContentManager::class, 'punctuationBeautifer'],
48
                ['is_safe' => ['html']]
49
            ),
50
        ];
51
    }
52
53
    public static function pregReplace($subject, $pattern, $replacement)
54
    {
55
        return preg_replace($pattern, $replacement, $subject);
56
    }
57
58
    public function getFunctions()
59
    {
60
        return [
61
            new TwigFunction('homepage', [$this->pageCanonical, 'generatePathForHomepage']),
62
            new TwigFunction('page', [$this->pageCanonical, 'generatePathForPage']),
63
            new TwigFunction('jslink', [AppExtension::class, 'renderJavascriptLink'], [
64
                'is_safe' => ['html'],
65
                'needs_environment' => true,
66
            ]),
67
            new TwigFunction('link', [AppExtension::class, 'renderJavascriptLink'], [
68
                'is_safe' => ['html'],
69
                'needs_environment' => true,
70
            ]),
71
            new TwigFunction('mail', [AppExtension::class, 'renderEncodedMail'], [
72
                'is_safe' => ['html'],
73
                'needs_environment' => true,
74
            ]),
75
            new TwigFunction(
76
                'bookmark', // = anchor
77
                [AppExtension::class, 'renderTxtAnchor'],
78
                ['is_safe' => ['html'], 'needs_environment' => true]
79
            ),
80
            new TwigFunction(
81
                'anchor', // = bookmark
82
                [AppExtension::class, 'renderTxtAnchor'],
83
                ['is_safe' => ['html'], 'needs_environment' => true]
84
            ),
85
            new TwigFunction(
86
                'isCurrentPage',
87
                [$this, 'isCurrentPage'],
88
                ['is_safe' => ['html'], 'needs_environment' => false]
89
            ),
90
            new TwigFunction(
91
                'gallery',
92
                [$this, 'renderGallery'],
93
                ['is_safe' => ['html'], 'needs_environment' => true]
94
            ),
95
            new TwigFunction(
96
                'video',
97
                [$this, 'renderVideo'],
98
                ['is_safe' => ['html'], 'needs_environment' => true]
99
            ),
100
            new TwigFunction(
101
                'encode',
102
                [AppExtension::class, 'encode'],
103
                ['is_safe' => ['html']]
104
            ),
105
            new TwigFunction(
106
                'list',
107
                [$this, 'renderPagesList'],
108
                ['is_safe' => ['html'], 'needs_environment' => true]
109
            ),
110
            new TwigFunction('isInternalImage', [AppExtension::class, 'isInternalImage']),
111
            new TwigFunction('getImageFrom', [AppExtension::class, 'transformInlineImageToMedia']),
112
            new TwigFunction('getEmbedCode', [AppExtension::class, 'getEmbedCode']),
113
            new TwigFunction('extract', [$this, 'extract'], ['is_safe' => ['html'], 'needs_environment' => true]),
114
        ];
115
    }
116
117
    public function extract(Twig $env, string $name, Page $page)
118
    {
119
        $mainContentManager = new MainContentManager($env, $page); // todo cache it ?!
120
121
        $extractorFunction = 'get'.ucfirst($name);
122
123
        if (!method_exists($mainContentManager, $extractorFunction)) {
124
            throw new Exception('`'.$name.'` does not exist');
125
        }
126
127
        return $mainContentManager->$extractorFunction();
128
    }
129
130
    public static function getEmbedCode(
131
        $embed_code
132
    ) {
133
        if ($id = self::getYoutubeVideo($embed_code)) {
134
            $embed_code = '<iframe src=https://www.youtube-nocookie.com/embed/'.$id.' frameborder=0'
135
                    .' allow=autoplay;encrypted-media allowfullscreen class=w-100></iframe>';
136
        }
137
138
        return $embed_code;
139
    }
140
141
    public function renderVideo(
142
        Twig $env,
143
        $embed_code,
144
        $image,
145
        $alt,
146
        $btn_title = null,
147
        $btn_style = null
148
    ) {
149
        $embed_code = self::getEmbedCode($embed_code);
150
151
        $params = [
152
            'embed_code' => $embed_code,
153
            'image' => $image,
154
            'alt' => $alt,
155
        ];
156
157
        if (null !== $btn_title) {
158
            $params['btn_title'] = $btn_title;
159
        }
160
        if (null !== $btn_style) {
161
            $params['btn_style'] = $btn_style;
162
        }
163
164
        return $env->render('@PiedWebCMS/component/_video.html.twig', $params);
165
    }
166
167
    protected static function getYoutubeVideo($url)
168
    {
169
        if (preg_match('~^(?:https?://)?(?:www[.])?(?:youtube[.]com/watch[?]v=|youtu[.]be/)([^&]{11})~', $url, $m)) {
170
            return $m[1];
171
        }
172
    }
173
174
    public function renderPagesList(
175
        Twig $env,
176
        string $containing = '',
177
        int $number = 3,
178
        string $orderBy = 'createdAt',
179
        string $template = '@PiedWebCMS/page/_pages_list.html.twig'
180
    ) {
181
        $qb = $this->em->getRepository($this->page_class)->getQueryToFindPublished('p');
0 ignored issues
show
Bug introduced by
The method getQueryToFindPublished() does not exist on Doctrine\Persistence\ObjectRepository. It seems like you code against a sub-type of Doctrine\Persistence\ObjectRepository such as Doctrine\ORM\EntityRepository. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

181
        $qb = $this->em->getRepository($this->page_class)->/** @scrutinizer ignore-call */ getQueryToFindPublished('p');
Loading history...
182
        $qb->andWhere('p.mainContent LIKE :containing')->setParameter('containing', '%'.$containing.'%');
183
        $qb->orderBy('p.'.$orderBy, 'DESC');
184
        $qb->setMaxResults($number);
185
186
        $pages = $qb->getQuery()->getResult();
187
188
        return $env->render($template, ['pages' => $pages]);
189
    }
190
191
    public static function isInternalImage(string $media): bool
192
    {
193
        return 0 === strpos($media, '/media/default/');
194
    }
195
196
    public static function transformInlineImageToMedia(string $src)
197
    {
198
        if (self::isInternalImage($src)) {
199
            $src = substr($src, strlen('/media/default/'));
200
201
            $media = new Media();
202
            $media->setRelativeDir('/media');
203
            $media->setMedia($src);
204
            $media->setSlug(preg_replace('@(\.jpg|\.jpeg|\.png|\.gif)$@', '', $src), true);
205
206
            return $media;
207
        }
208
209
        $media = new Media();
210
        $media->setRelativeDir($src);
211
        $media->setMedia('');
212
        $media->setSlug('', true);
213
214
        return $media;
215
    }
216
217
    public function renderGallery(Twig $env, Page $currentPage, $filterImageFrom = 1, $length = 1001)
218
    {
219
        return $env->render('@PiedWebCMS/page/_gallery.html.twig', [
220
            'page' => $currentPage,
221
            'galleryFilterFrom' => $filterImageFrom - 1,
222
            'length' => $length,
223
        ]);
224
    }
225
226
    public function isCurrentPage(string $uri, ?Page $currentPage)
227
    {
228
        return
229
            null === $currentPage || $uri != $this->pageCanonical->generatePathForPage($currentPage->getRealSlug())
230
            ? false
231
            : true;
232
    }
233
234
    public static function renderTxtAnchor(Twig $env, $name)
235
    {
236
        $slugify = new Slugify();
237
        $name = $slugify->slugify($name);
238
239
        return $env->render('@PiedWebCMS/component/_txt_anchor.html.twig', ['name' => $name]);
240
    }
241
242
    public static function renderEncodedMail(Twig $env, $mail, $class = '')
243
    {
244
        return $env->render('@PiedWebCMS/component/_encoded_mail.html.twig', [
245
            'mail' => str_rot13($mail),
246
            'class' => $class,
247
        ]);
248
    }
249
250
    public static function renderJavascriptLink(Twig $env, $anchor, $path, $attr = [])
251
    {
252
        if (0 === strpos($path, 'http://')) {
253
            $path = '-'.substr($path, 7);
254
        } elseif (0 === strpos($path, 'https://')) {
255
            $path = '_'.substr($path, 8);
256
        } elseif (0 === strpos($path, 'mailto:')) {
257
            $path = '@'.substr($path, 7);
258
        }
259
260
        return $env->render(
261
            '@PiedWebCMS/component/_javascript_link.html.twig',
262
            [
263
            'attr' => self::mergeAndMapAttributes($attr, ['class' => 'a', 'data-rot' => str_rot13($path)]),
264
            'anchor' => $anchor,
265
            ]
266
        );
267
    }
268
269
    public static function encode($string)
270
    {
271
        return str_rot13($string);
272
    }
273
}
274