| 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
|
|||||
| 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
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 |
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.