Passed
Pull Request — master (#51)
by
unknown
04:28 queued 01:33
created

ContactFormExtensions::settingsHtml()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 14
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Craft Contact Form Extensions plugin for Craft CMS 3.x.
4
 *
5
 * Adds extensions to the Craft CMS contact form plugin.
6
 *
7
 * @link      https://rias.be
8
 *
9
 * @copyright Copyright (c) 2018 Rias
10
 */
11
12
namespace rias\contactformextensions;
13
14
use Craft;
15
use craft\base\Plugin;
16
use craft\contactform\events\SendEvent;
17
use craft\contactform\Mailer;
18
use craft\contactform\models\Submission;
19
use craft\elements\Asset;
20
use craft\events\RegisterUrlRulesEvent;
21
use craft\events\TemplateEvent;
22
use craft\helpers\App;
23
use craft\mail\Message;
24
use craft\services\Plugins;
25
use craft\web\twig\variables\CraftVariable;
26
use craft\web\UrlManager;
27
use craft\web\View;
28
use rias\contactformextensions\models\Settings;
29
use rias\contactformextensions\services\ContactFormExtensionsService as ContactFormExtensionsServiceService;
30
use rias\contactformextensions\variables\ContactFormExtensionsVariable;
31
use yii\base\Event;
32
33
/**
34
 * Craft plugins are very much like little applications in and of themselves. We’ve made
35
 * it as simple as we can, but the training wheels are off. A little prior knowledge is
36
 * going to be required to write a plugin.
37
 *
38
 * For the purposes of the plugin docs, we’re going to assume that you know PHP and SQL,
39
 * as well as some semi-advanced concepts like object-oriented programming and PHP namespaces.
40
 *
41
 * https://craftcms.com/docs/plugins/introduction
42
 *
43
 * @author    Rias
44
 *
45
 * @since     1.0.0
46
 *
47
 * @property  ContactFormExtensionsServiceService $contactFormExtensionsService
48
 * @property  Settings $settings
49
 *
50
 * @method    Settings getSettings()
51
 */
52
class ContactFormExtensions extends Plugin
53
{
54
    // Static Properties
55
    // =========================================================================
56
57
    /**
58
     * Static property that is an instance of this plugin class so that it can be accessed via
59
     * ContactFormExtensions::$plugin.
60
     *
61
     * @var ContactFormExtensions
62
     */
63
    public static $plugin;
64
65
    public $name;
66
67
    // Public Methods
68
    // =========================================================================
69
70
    /**
71
     * Set our $plugin static property to this class so that it can be accessed via
72
     * CraftContactFormExtensions::$plugin.
73
     *
74
     * Called after the plugin class is instantiated; do any one-time initialization
75
     * here such as hooks and events.
76
     *
77
     * If you have a '/vendor/autoload.php' file, it will be loaded for you automatically;
78
     * you do not need to load it in your init() method.
79
     */
80
    public function init()
81
    {
82
        parent::init();
83
        self::$plugin = $this;
84
85
        if (!Craft::$app->plugins->isPluginInstalled('contact-form') && !Craft::$app->request->getIsConsoleRequest()) {
86
            Craft::$app->session->setNotice(Craft::t('contact-form-extensions', 'The Contact Form plugin is not installed or activated, Contact Form Extensions does not work without it.'));
0 ignored issues
show
Bug introduced by
The method setNotice() does not exist on null. ( Ignorable by Annotation )

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

86
            Craft::$app->session->/** @scrutinizer ignore-call */ 
87
                                  setNotice(Craft::t('contact-form-extensions', 'The Contact Form plugin is not installed or activated, Contact Form Extensions does not work without it.'));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
87
        }
88
89
        Event::on(View::class, View::EVENT_BEFORE_RENDER_TEMPLATE, function (TemplateEvent $e) {
90
            if (
91
                $e->template === 'settings/plugins/_settings' &&
92
                $e->variables['plugin'] === $this
93
            ) {
94
                // Add the tabs
95
                $e->variables['tabs'] = [
96
                    ['label' => 'Settings', 'url' => '#settings-tab-settings'],
97
                    ['label' => 'reCAPTCHA', 'url' => '#settings-tab-recaptcha'],
98
                ];
99
            }
100
        });
101
102
        Event::on(UrlManager::class, UrlManager::EVENT_REGISTER_CP_URL_RULES, function (RegisterUrlRulesEvent $event) {
103
            $event->rules = array_merge($event->rules, [
104
                'contact-form-extensions/submissions/<submissionId:\d+>'                       => 'contact-form-extensions/submissions/show-submission',
105
                'contact-form-extensions/submissions/<submissionId:\d+>/<siteHandle:{handle}>' => 'contact-form-extensions/submissions/show-submission',
106
            ]);
107
        });
108
109
        Event::on(Mailer::class, Mailer::EVENT_BEFORE_SEND, function (SendEvent $e) {
110
            if ($e->isSpam) {
111
                return;
112
            }
113
114
            if ($this->settings->recaptcha) {
115
                $recaptcha = $this->contactFormExtensionsService->getRecaptcha();
116
                $captchaResponse = Craft::$app->request->getParam('g-recaptcha-response');
117
118
                if (!$recaptcha->verifyResponse($captchaResponse, $_SERVER['REMOTE_ADDR'])) {
0 ignored issues
show
Bug introduced by
It seems like $captchaResponse can also be of type array and array; however, parameter $response of AlbertCht\InvisibleReCap...ptcha::verifyResponse() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

118
                if (!$recaptcha->verifyResponse(/** @scrutinizer ignore-type */ $captchaResponse, $_SERVER['REMOTE_ADDR'])) {
Loading history...
119
                    $e->isSpam = true;
120
                    $e->handled = true;
121
122
                    return;
123
                }
124
            }
125
126
            $submission = $e->submission;
127
128
            $attNames = [];
129
            if ($this->settings->attachmentVolumeHandle && $submission->attachment) {
130
                $volume = Craft::$app->getVolumes()->getVolumeByHandle($this->settings->attachmentVolumeHandle);
131
                if ($volume) {
132
                    foreach ($submission->attachment as $attachment) {
133
                        $date = date_create();
134
                        $asset = new Asset();
135
                        $asset->tempFilePath = $attachment->tempName;
136
                        $asset->filename = $date->getTimestamp().'_'.$attachment->name;
137
                        $asset->newFolderId = Craft::$app->assets->getRootFolderByVolumeId($volume->id)->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface craft\base\VolumeInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
138
                        $asset->volumeId = $volume->id;
139
                        $asset->avoidFilenameConflicts = true;
140
                        $asset->setScenario(Asset::SCENARIO_CREATE);
141
                        $result = Craft::$app->getElements()->saveElement($asset);
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
142
                        array_push($attNames, $asset->filename);
143
                    }
144
                }
145
            }
146
147
            if ($this->settings->enableDatabase) {
148
                $this->contactFormExtensionsService->saveSubmission($submission, implode(', ', $attNames));
149
            }
150
151
            // Set the overridden "toEmail" setting
152
            if (array_key_exists('toEmail', $e->submission->message)) {
0 ignored issues
show
Bug introduced by
It seems like $e->submission->message can also be of type null and string; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

152
            if (array_key_exists('toEmail', /** @scrutinizer ignore-type */ $e->submission->message)) {
Loading history...
153
                $email = Craft::$app->security->validateData($e->submission->message['toEmail']);
154
                $e->toEmails = explode(',', $email);
155
            }
156
157
            if ($this->settings->enableTemplateOverwrite) {
158
                // First set the template mode to the Site templates
159
                Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE);
160
161
                // Render the set template
162
                $html = Craft::$app->view->renderTemplate(
163
                    $this->settings->notificationTemplate,
164
                    ['submission' => $e->submission]
165
                );
166
167
                // Update the message body
168
                $e->message->setHtmlBody($html);
169
170
                // Set the template mode back to Control Panel
171
                Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_CP);
172
            }
173
        });
174
175
        Event::on(Mailer::class, Mailer::EVENT_AFTER_SEND, function (SendEvent $e) {
176
            if ($this->settings->enableConfirmationEmail) {
177
                // First set the template mode to the Site templates
178
                Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE);
179
180
                // Check if template is overridden in form
181
                $template = null;
182
                if (array_key_exists('template', $e->submission->message)) {
0 ignored issues
show
Bug introduced by
It seems like $e->submission->message can also be of type null and string; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

182
                if (array_key_exists('template', /** @scrutinizer ignore-type */ $e->submission->message)) {
Loading history...
183
                    $template = '_emails\\'.Craft::$app->security->validateData($e->submission->message['template']);
184
                } else {
185
                    // Render the set template
186
                    $template = $this->settings->confirmationTemplate;
187
                }
188
                $html = Craft::$app->view->renderTemplate(
189
                    $template,
190
                    ['submission' => $e->submission]
191
                );
192
193
                // Create the confirmation email
194
                $message = new Message();
195
                $message->setTo($e->submission->fromEmail);
196
                if (isset(App::mailSettings()->fromEmail)) {
197
                    $message->setFrom(App::mailSettings()->fromEmail);
198
                } else {
199
                    $message->setFrom($e->message->getTo());
200
                }
201
                $message->setHtmlBody($html);
202
                $message->setSubject($this->settings->getConfirmationSubject());
203
204
                // Send the mail
205
                Craft::$app->mailer->send($message);
206
207
                // Set the template mode back to Control Panel
208
                Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_CP);
209
            }
210
        });
211
212
        Event::on(
213
            CraftVariable::class,
214
            CraftVariable::EVENT_INIT,
215
            function (Event $event) {
216
                /** @var CraftVariable $variable */
217
                $variable = $event->sender;
218
                $variable->set('contactFormExtensions', ContactFormExtensionsVariable::class);
219
            }
220
        );
221
    }
222
223
    /**
224
     * {@inheritdoc}
225
     */
226
    public function getCpNavItem()
227
    {
228
        if (!$this->settings->enableDatabase) {
229
            return;
230
        }
231
232
        $navItem = parent::getCpNavItem();
233
234
        $navItem['label'] = Craft::t('contact-form-extensions', 'Form Submissions');
235
236
        return $navItem;
237
    }
238
239
    // Protected Methods
240
    // =========================================================================
241
242
    /**
243
     * Creates and returns the model used to store the plugin’s settings.
244
     *
245
     * @return \craft\base\Model|null
246
     */
247
    protected function createSettingsModel()
248
    {
249
        return new Settings();
250
    }
251
252
    /**
253
     * Returns the rendered settings HTML, which will be inserted into the content
254
     * block on the settings page.
255
     *
256
     * @throws \Twig_Error_Loader
257
     * @throws \yii\base\Exception
258
     *
259
     * @return string The rendered settings HTML
260
     */
261
    protected function settingsHtml(): string
262
    {
263
        // Get and pre-validate the settings
264
        $settings = $this->getSettings();
265
        $settings->validate();
266
267
        // Get the settings that are being defined by the config file
268
        $overrides = Craft::$app->getConfig()->getConfigFromFile(strtolower($this->handle));
269
270
        return Craft::$app->view->renderTemplate(
271
            'contact-form-extensions/settings',
272
            [
273
                'settings'  => $this->getSettings(),
274
                'overrides' => array_keys($overrides),
275
            ]
276
        );
277
    }
278
}
279