Issues (7)

src/ContactFormExtensions.php (2 issues)

Labels
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\events\RegisterUrlRulesEvent;
20
use craft\events\TemplateEvent;
21
use craft\helpers\App;
22
use craft\mail\Message;
23
use craft\services\Plugins;
24
use craft\web\twig\variables\CraftVariable;
25
use craft\web\UrlManager;
26
use craft\web\View;
27
use rias\contactformextensions\models\Settings;
28
use rias\contactformextensions\services\ContactFormExtensionsService as ContactFormExtensionsServiceService;
29
use rias\contactformextensions\variables\ContactFormExtensionsVariable;
30
use yii\base\Event;
31
32
/**
33
 * Craft plugins are very much like little applications in and of themselves. We’ve made
34
 * it as simple as we can, but the training wheels are off. A little prior knowledge is
35
 * going to be required to write a plugin.
36
 *
37
 * For the purposes of the plugin docs, we’re going to assume that you know PHP and SQL,
38
 * as well as some semi-advanced concepts like object-oriented programming and PHP namespaces.
39
 *
40
 * https://craftcms.com/docs/plugins/introduction
41
 *
42
 * @author    Rias
43
 *
44
 * @since     1.0.0
45
 *
46
 * @property  ContactFormExtensionsServiceService $contactFormExtensionsService
47
 * @property  Settings $settings
48
 *
49
 * @method    Settings getSettings()
50
 */
51
class ContactFormExtensions extends Plugin
52
{
53
    // Static Properties
54
    // =========================================================================
55
56
    /**
57
     * Static property that is an instance of this plugin class so that it can be accessed via
58
     * ContactFormExtensions::$plugin.
59
     *
60
     * @var ContactFormExtensions
61
     */
62
    public static $plugin;
63
64
    public $name;
65
66
    // Public Methods
67
    // =========================================================================
68
69
    /**
70
     * Set our $plugin static property to this class so that it can be accessed via
71
     * CraftContactFormExtensions::$plugin.
72
     *
73
     * Called after the plugin class is instantiated; do any one-time initialization
74
     * here such as hooks and events.
75
     *
76
     * If you have a '/vendor/autoload.php' file, it will be loaded for you automatically;
77
     * you do not need to load it in your init() method.
78
     */
79
    public function init()
80
    {
81
        parent::init();
82
        self::$plugin = $this;
83
84
        if (!Craft::$app->plugins->isPluginInstalled('contact-form') && !Craft::$app->request->getIsConsoleRequest()) {
85
            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
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

85
            Craft::$app->session->/** @scrutinizer ignore-call */ 
86
                                  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...
86
        }
87
88
        Event::on(View::class, View::EVENT_BEFORE_RENDER_TEMPLATE, function (TemplateEvent $e) {
89
            if (
90
                $e->template === 'settings/plugins/_settings' &&
91
                $e->variables['plugin'] === $this
92
            ) {
93
                // Add the tabs
94
                $e->variables['tabs'] = [
95
                    ['label' => 'Settings', 'url' => '#settings-tab-settings'],
96
                    ['label' => 'reCAPTCHA', 'url' => '#settings-tab-recaptcha'],
97
                ];
98
            }
99
        });
100
101
        Event::on(UrlManager::class, UrlManager::EVENT_REGISTER_CP_URL_RULES, function (RegisterUrlRulesEvent $event) {
102
            $event->rules = array_merge($event->rules, [
103
                'contact-form-extensions/submissions/<submissionId:\d+>'                       => 'contact-form-extensions/submissions/show-submission',
104
                'contact-form-extensions/submissions/<submissionId:\d+>/<siteHandle:{handle}>' => 'contact-form-extensions/submissions/show-submission',
105
            ]);
106
        });
107
108
        Event::on(Mailer::class, Mailer::EVENT_BEFORE_SEND, function (SendEvent $e) {
109
            if ($e->isSpam) {
110
                return;
111
            }
112
113
            if ($this->settings->recaptcha) {
114
                $recaptcha = $this->contactFormExtensionsService->getRecaptcha();
115
                $captchaResponse = Craft::$app->request->getParam('g-recaptcha-response');
116
117
                if (!$recaptcha->verifyResponse($captchaResponse, $_SERVER['REMOTE_ADDR'])) {
0 ignored issues
show
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

117
                if (!$recaptcha->verifyResponse(/** @scrutinizer ignore-type */ $captchaResponse, $_SERVER['REMOTE_ADDR'])) {
Loading history...
118
                    $e->isSpam = true;
119
                    $e->handled = true;
120
121
                    return;
122
                }
123
            }
124
125
            $submission = $e->submission;
126
            if ($this->settings->enableDatabase) {
127
                $this->contactFormExtensionsService->saveSubmission($submission);
128
            }
129
130
            // Set the overridden "toEmail" setting
131
            if (is_array($e->submission->message) && array_key_exists('toEmail', $e->submission->message)) {
132
                $email = Craft::$app->security->validateData($e->submission->message['toEmail']);
133
                $e->toEmails = explode(',', $email);
134
            }
135
136
            if ($this->settings->enableTemplateOverwrite) {
137
                // First set the template mode to the Site templates
138
                Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE);
139
140
                // Render the set template
141
                $html = Craft::$app->view->renderTemplate(
142
                    $this->settings->notificationTemplate,
143
                    ['submission' => $e->submission]
144
                );
145
146
                // Update the message body
147
                $e->message->setHtmlBody($html);
148
149
                // Set the template mode back to Control Panel
150
                Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_CP);
151
            }
152
        });
153
154
        Event::on(Mailer::class, Mailer::EVENT_AFTER_SEND, function (SendEvent $e) {
155
            if ($this->settings->enableConfirmationEmail) {
156
                // First set the template mode to the Site templates
157
                Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE);
158
159
                // Check if template is overridden in form
160
                $template = null;
161
                if (is_array($e->submission->message) && array_key_exists('template', $e->submission->message)) {
162
                    $template = '_emails\\'.Craft::$app->security->validateData($e->submission->message['template']);
163
                } else {
164
                    // Render the set template
165
                    $template = $this->settings->confirmationTemplate;
166
                }
167
                $html = Craft::$app->view->renderTemplate(
168
                    $template,
169
                    ['submission' => $e->submission]
170
                );
171
172
                // Create the confirmation email
173
                $message = new Message();
174
                $message->setTo($e->submission->fromEmail);
175
                if (isset(App::mailSettings()->fromEmail)) {
176
                    $message->setFrom(App::mailSettings()->fromEmail);
177
                } else {
178
                    $message->setFrom($e->message->getTo());
179
                }
180
                $message->setHtmlBody($html);
181
                $message->setSubject($this->settings->getConfirmationSubject());
182
183
                // Send the mail
184
                Craft::$app->mailer->send($message);
185
186
                // Set the template mode back to Control Panel
187
                Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_CP);
188
            }
189
        });
190
191
        Event::on(
192
            CraftVariable::class,
193
            CraftVariable::EVENT_INIT,
194
            function (Event $event) {
195
                /** @var CraftVariable $variable */
196
                $variable = $event->sender;
197
                $variable->set('contactFormExtensions', ContactFormExtensionsVariable::class);
198
            }
199
        );
200
    }
201
202
    /**
203
     * {@inheritdoc}
204
     */
205
    public function getCpNavItem()
206
    {
207
        if (!$this->settings->enableDatabase) {
208
            return;
209
        }
210
211
        $navItem = parent::getCpNavItem();
212
213
        $navItem['label'] = Craft::t('contact-form-extensions', 'Form Submissions');
214
215
        return $navItem;
216
    }
217
218
    // Protected Methods
219
    // =========================================================================
220
221
    /**
222
     * Creates and returns the model used to store the plugin’s settings.
223
     *
224
     * @return \craft\base\Model|null
225
     */
226
    protected function createSettingsModel()
227
    {
228
        return new Settings();
229
    }
230
231
    /**
232
     * Returns the rendered settings HTML, which will be inserted into the content
233
     * block on the settings page.
234
     *
235
     * @throws \Twig_Error_Loader
236
     * @throws \yii\base\Exception
237
     *
238
     * @return string The rendered settings HTML
239
     */
240
    protected function settingsHtml(): string
241
    {
242
        // Get and pre-validate the settings
243
        $settings = $this->getSettings();
244
        $settings->validate();
245
246
        // Get the settings that are being defined by the config file
247
        $overrides = Craft::$app->getConfig()->getConfigFromFile(strtolower($this->handle));
248
249
        return Craft::$app->view->renderTemplate(
250
            'contact-form-extensions/settings',
251
            [
252
                'settings'  => $this->getSettings(),
253
                'overrides' => array_keys($overrides),
254
            ]
255
        );
256
    }
257
}
258