Creative Mail – Easier WordPress & WooCommerce Email Marketing - Version 1.6.0

Version Description

Download this release

Release Info

Developer constantcontact
Plugin Icon 128x128 Creative Mail – Easier WordPress & WooCommerce Email Marketing
Version 1.6.0
Comparing to
See all releases

Code changes from version 1.5.4 to 1.6.0

Files changed (83) hide show
  1. CHANGELOG.md +5 -0
  2. README.md +5 -4
  3. composer.json +11 -1
  4. composer.lock +347 -3
  5. creative-mail-plugin.php +33 -32
  6. readme.txt +10 -4
  7. src/Helpers/EncryptionHelper.php +17 -10
  8. src/Helpers/EnvironmentHelper.php +9 -13
  9. src/Helpers/OptionsHelper.php +26 -20
  10. src/Helpers/ValidationHelper.php +2 -2
  11. src/Integrations/Integration.php +5 -3
  12. src/Managers/AdminManager.php +52 -44
  13. src/Managers/ApiManager.php +222 -176
  14. src/Managers/CheckoutManager.php +202 -183
  15. src/Managers/DatabaseManager.php +4 -2
  16. src/Managers/EmailManager.php +69 -54
  17. src/Managers/FormManager.php +6 -6
  18. src/Managers/IntegrationManager.php +10 -15
  19. src/Managers/RaygunManager.php +20 -15
  20. src/Models/CheckoutSave.php +2 -2
  21. src/Modules/Blog/Models/BlogAttachment.php +1 -0
  22. src/Modules/Blog/Models/BlogInformation.php +1 -0
  23. src/Modules/Contacts/Handlers/BaseContactFormPluginHandler.php +4 -0
  24. src/Modules/Contacts/Handlers/BlueHostBuilderPluginHandler.php +6 -5
  25. src/Modules/Contacts/Handlers/ContactFormSevenPluginHandler.php +36 -0
  26. src/Modules/Contacts/Handlers/CreativeMailPluginHandler.php +8 -5
  27. src/Modules/Contacts/Handlers/FormidablePluginHandler.php +42 -36
  28. src/Modules/Contacts/Handlers/GravityFormsPluginHandler.php +16 -14
  29. src/Modules/Contacts/Handlers/NinjaFormsPluginHandler.php +90 -79
  30. src/Modules/Contacts/Handlers/WooCommercePluginHandler.php +13 -4
  31. src/Modules/Contacts/Handlers/WpFormsPluginHandler.php +17 -16
  32. src/Modules/Contacts/Managers/ContactsSyncManager.php +0 -2
  33. src/Modules/Contacts/Models/ContactModel.php +1 -1
  34. src/Modules/Contacts/Processors/ContactsSyncBackgroundProcessor.php +17 -13
  35. src/Modules/Contacts/Services/ContactsSyncService.php +16 -14
  36. src/Modules/DashboardWidgetModule.php +3 -2
  37. src/Modules/FeedbackNoticeModule.php +3 -3
  38. src/Modules/WooCommerce/Emails/AbandonedCartEmail.php +2 -4
  39. src/Modules/WooCommerce/Models/WCInformationModel.php +1 -0
  40. src/Modules/WooCommerce/Models/WCStoreInformation.php +1 -1
  41. src/views/activated-integrations.php +1 -0
  42. src/views/admin-dashboard-widget/most-recent-campaigns.php +3 -1
  43. src/views/admin-dashboard-widget/woocommerce.php +9 -3
  44. src/views/admin-feedback-notice/many-contacts.php +9 -5
  45. src/views/admin-get-started-banner.php +3 -1
  46. src/views/pending-setup.php +1 -0
  47. src/views/settings-internal.php +17 -9
  48. src/views/settings.php +7 -7
  49. src/views/unlink.php +2 -1
  50. vendor/autoload.php +1 -1
  51. vendor/bin/phpstan.phar +0 -0
  52. vendor/composer/autoload_classmap.php +31 -0
  53. vendor/composer/autoload_files.php +11 -0
  54. vendor/composer/autoload_psr4.php +3 -0
  55. vendor/composer/autoload_real.php +22 -4
  56. vendor/composer/autoload_static.php +62 -5
  57. vendor/composer/installed.json +355 -0
  58. vendor/phpstan/extension-installer/.github/workflows/build.yml +113 -0
  59. vendor/phpstan/extension-installer/.github/workflows/release.yml +33 -0
  60. vendor/phpstan/extension-installer/.gitignore +3 -0
  61. vendor/phpstan/extension-installer/LICENSE +21 -0
  62. vendor/phpstan/extension-installer/README.md +73 -0
  63. vendor/phpstan/extension-installer/build-cs/.gitignore +2 -0
  64. vendor/phpstan/extension-installer/build-cs/composer.json +7 -0
  65. vendor/phpstan/extension-installer/build.xml +90 -0
  66. vendor/phpstan/extension-installer/composer.json +30 -0
  67. vendor/phpstan/extension-installer/phpcs.xml +57 -0
  68. vendor/phpstan/extension-installer/phpstan.neon +2 -0
  69. vendor/phpstan/extension-installer/src/Plugin.php +149 -0
  70. vendor/phpstan/phpstan/LICENSE +21 -0
  71. vendor/phpstan/phpstan/README.md +102 -0
  72. vendor/phpstan/phpstan/bootstrap.php +60 -0
  73. vendor/phpstan/phpstan/composer.json +18 -0
  74. vendor/phpstan/phpstan/conf/bleedingEdge.neon +2 -0
  75. vendor/phpstan/phpstan/phpstan +8 -0
  76. vendor/phpstan/phpstan/phpstan.phar +0 -0
  77. vendor/phpstan/phpstan/phpstan.phar.asc +16 -0
  78. vendor/symfony/polyfill-php73/LICENSE +19 -0
  79. vendor/symfony/polyfill-php73/Php73.php +43 -0
  80. vendor/symfony/polyfill-php73/README.md +18 -0
  81. vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php +16 -0
  82. vendor/symfony/polyfill-php73/bootstrap.php +31 -0
  83. vendor/symfony/polyfill-php73/composer.json +36 -0
CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
  Changelog
2
  =========
3
 
 
 
 
 
 
4
  #### 1.5.4 - September 5th, 2022
5
  - Migration to WordPress version 6.0.2
6
  - Checkout mail templates update
1
  Changelog
2
  =========
3
 
4
+ #### 1.6.0 - October 12th, 2022
5
+ - Security update
6
+ - Bug fixes
7
+ - Support to sync Address Fields for Contact Form 7
8
+
9
  #### 1.5.4 - September 5th, 2022
10
  - Migration to WordPress version 6.0.2
11
  - Checkout mail templates update
README.md CHANGED
@@ -1,14 +1,14 @@
1
  === Creative Mail – Easier WordPress & WooCommerce Email Marketing ===
2
  Contributors: Constant Contact
3
  Tags: email, marketing, newsletter, subscribe, contact form, constant contact, crm, automations, ecommerce, promotion, offers, retargeting
4
- Requires at least: 4.6
5
  Tested up to: 6.0.2
6
- Stable tag: 1.5.4
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
- Requires PHP: 5.6
10
  Website: https://www.creativemail.com
11
- WC requires at least: 3.0.0
12
  WC tested up to: 6.8.2
13
 
14
  Creative Mail was designed specifically for WordPress and WooCommerce.
@@ -93,6 +93,7 @@ Creative Mail by Constant Contact [Privacy Notice](https://www.endurance.com/pri
93
  6. Enhance your brand with LogoBuilder
94
 
95
  == Changelog ==
 
96
  * 1.5.4 - Migration to WordPress version 6.0.2 and Checkout mail templates update
97
  * 1.5.3 - README update
98
  * 1.5.2 - Small bug fix for PHP versions previous to 7.1
1
  === Creative Mail – Easier WordPress & WooCommerce Email Marketing ===
2
  Contributors: Constant Contact
3
  Tags: email, marketing, newsletter, subscribe, contact form, constant contact, crm, automations, ecommerce, promotion, offers, retargeting
4
+ Requires at least: 4.9
5
  Tested up to: 6.0.2
6
+ Stable tag: 1.6.0
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ Requires PHP: 7.2
10
  Website: https://www.creativemail.com
11
+ WC requires at least: 3.6.0
12
  WC tested up to: 6.8.2
13
 
14
  Creative Mail was designed specifically for WordPress and WooCommerce.
93
  6. Enhance your brand with LogoBuilder
94
 
95
  == Changelog ==
96
+ * 1.6.0 - Security update, Bug fixes and Support to sync Address Fields for Contact Form 7
97
  * 1.5.4 - Migration to WordPress version 6.0.2 and Checkout mail templates update
98
  * 1.5.3 - README update
99
  * 1.5.2 - Small bug fix for PHP versions previous to 7.1
composer.json CHANGED
@@ -1,6 +1,10 @@
1
  {
2
  "config": {
3
- "optimize-autoloader": true
 
 
 
 
4
  },
5
  "require": {
6
  "defuse/php-encryption": "^2.2",
@@ -24,5 +28,11 @@
24
  "CreativeMail\\Blocks\\": "src/blocks/",
25
  "CreativeMail\\": "src/"
26
  }
 
 
 
 
 
 
27
  }
28
  }
1
  {
2
  "config": {
3
+ "optimize-autoloader": true,
4
+ "allow-plugins": {
5
+ "dealerdirect/phpcodesniffer-composer-installer": true,
6
+ "phpstan/extension-installer": true
7
+ }
8
  },
9
  "require": {
10
  "defuse/php-encryption": "^2.2",
28
  "CreativeMail\\Blocks\\": "src/blocks/",
29
  "CreativeMail\\": "src/"
30
  }
31
+ },
32
+ "require-dev": {
33
+ "phpstan/phpstan": "^1.8",
34
+ "szepeviktor/phpstan-wordpress": "^1.1",
35
+ "phpstan/extension-installer": "^1.1",
36
+ "php-stubs/woocommerce-stubs": "^6.9"
37
  }
38
  }
composer.lock CHANGED
@@ -4,7 +4,7 @@
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
- "content-hash": "2432870f0eed5d73f35f7f6fcb058336",
8
  "packages": [
9
  {
10
  "name": "a5hleyrich/wp-background-processing",
@@ -395,7 +395,351 @@
395
  "time": "2021-12-12T21:44:58+00:00"
396
  }
397
  ],
398
- "packages-dev": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  "aliases": [],
400
  "minimum-stability": "stable",
401
  "stability-flags": [],
@@ -407,5 +751,5 @@
407
  "ext-zip": "*"
408
  },
409
  "platform-dev": [],
410
- "plugin-api-version": "2.0.0"
411
  }
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
+ "content-hash": "29273c6343a1bdf1ea050939233aab9b",
8
  "packages": [
9
  {
10
  "name": "a5hleyrich/wp-background-processing",
395
  "time": "2021-12-12T21:44:58+00:00"
396
  }
397
  ],
398
+ "packages-dev": [
399
+ {
400
+ "name": "php-stubs/woocommerce-stubs",
401
+ "version": "v6.9.3",
402
+ "source": {
403
+ "type": "git",
404
+ "url": "https://github.com/php-stubs/woocommerce-stubs.git",
405
+ "reference": "870c0c0abcd5ae9a8be58fc797123a4d882e604e"
406
+ },
407
+ "dist": {
408
+ "type": "zip",
409
+ "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/870c0c0abcd5ae9a8be58fc797123a4d882e604e",
410
+ "reference": "870c0c0abcd5ae9a8be58fc797123a4d882e604e",
411
+ "shasum": ""
412
+ },
413
+ "require": {
414
+ "php-stubs/wordpress-stubs": "^5.3 || ^6.0"
415
+ },
416
+ "require-dev": {
417
+ "php": "~7.1 || ~8.0",
418
+ "php-stubs/generator": "^0.8.0"
419
+ },
420
+ "suggest": {
421
+ "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
422
+ "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
423
+ },
424
+ "type": "library",
425
+ "notification-url": "https://packagist.org/downloads/",
426
+ "license": [
427
+ "MIT"
428
+ ],
429
+ "description": "WooCommerce function and class declaration stubs for static analysis.",
430
+ "homepage": "https://github.com/php-stubs/woocommerce-stubs",
431
+ "keywords": [
432
+ "PHPStan",
433
+ "static analysis",
434
+ "woocommerce",
435
+ "wordpress"
436
+ ],
437
+ "support": {
438
+ "issues": "https://github.com/php-stubs/woocommerce-stubs/issues",
439
+ "source": "https://github.com/php-stubs/woocommerce-stubs/tree/v6.9.3"
440
+ },
441
+ "time": "2022-09-20T23:28:43+00:00"
442
+ },
443
+ {
444
+ "name": "php-stubs/wordpress-stubs",
445
+ "version": "v6.0.1",
446
+ "source": {
447
+ "type": "git",
448
+ "url": "https://github.com/php-stubs/wordpress-stubs.git",
449
+ "reference": "e04781a84e364615a7b5f70fdc345c8253ca5b8f"
450
+ },
451
+ "dist": {
452
+ "type": "zip",
453
+ "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/e04781a84e364615a7b5f70fdc345c8253ca5b8f",
454
+ "reference": "e04781a84e364615a7b5f70fdc345c8253ca5b8f",
455
+ "shasum": ""
456
+ },
457
+ "replace": {
458
+ "giacocorsiglia/wordpress-stubs": "*"
459
+ },
460
+ "require-dev": {
461
+ "nikic/php-parser": "< 4.12.0",
462
+ "php": "~7.3 || ~8.0",
463
+ "php-stubs/generator": "^0.8.1",
464
+ "phpdocumentor/reflection-docblock": "^5.3",
465
+ "phpstan/phpstan": "^1.2"
466
+ },
467
+ "suggest": {
468
+ "paragonie/sodium_compat": "Pure PHP implementation of libsodium",
469
+ "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
470
+ "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
471
+ },
472
+ "type": "library",
473
+ "notification-url": "https://packagist.org/downloads/",
474
+ "license": [
475
+ "MIT"
476
+ ],
477
+ "description": "WordPress function and class declaration stubs for static analysis.",
478
+ "homepage": "https://github.com/php-stubs/wordpress-stubs",
479
+ "keywords": [
480
+ "PHPStan",
481
+ "static analysis",
482
+ "wordpress"
483
+ ],
484
+ "support": {
485
+ "issues": "https://github.com/php-stubs/wordpress-stubs/issues",
486
+ "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.0.1"
487
+ },
488
+ "time": "2022-07-15T11:10:45+00:00"
489
+ },
490
+ {
491
+ "name": "phpstan/extension-installer",
492
+ "version": "1.1.0",
493
+ "source": {
494
+ "type": "git",
495
+ "url": "https://github.com/phpstan/extension-installer.git",
496
+ "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051"
497
+ },
498
+ "dist": {
499
+ "type": "zip",
500
+ "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
501
+ "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
502
+ "shasum": ""
503
+ },
504
+ "require": {
505
+ "composer-plugin-api": "^1.1 || ^2.0",
506
+ "php": "^7.1 || ^8.0",
507
+ "phpstan/phpstan": ">=0.11.6"
508
+ },
509
+ "require-dev": {
510
+ "composer/composer": "^1.8",
511
+ "phing/phing": "^2.16.3",
512
+ "php-parallel-lint/php-parallel-lint": "^1.2.0",
513
+ "phpstan/phpstan-strict-rules": "^0.11 || ^0.12"
514
+ },
515
+ "type": "composer-plugin",
516
+ "extra": {
517
+ "class": "PHPStan\\ExtensionInstaller\\Plugin"
518
+ },
519
+ "autoload": {
520
+ "psr-4": {
521
+ "PHPStan\\ExtensionInstaller\\": "src/"
522
+ }
523
+ },
524
+ "notification-url": "https://packagist.org/downloads/",
525
+ "license": [
526
+ "MIT"
527
+ ],
528
+ "description": "Composer plugin for automatic installation of PHPStan extensions",
529
+ "support": {
530
+ "issues": "https://github.com/phpstan/extension-installer/issues",
531
+ "source": "https://github.com/phpstan/extension-installer/tree/1.1.0"
532
+ },
533
+ "time": "2020-12-13T13:06:13+00:00"
534
+ },
535
+ {
536
+ "name": "phpstan/phpstan",
537
+ "version": "1.8.2",
538
+ "source": {
539
+ "type": "git",
540
+ "url": "https://github.com/phpstan/phpstan.git",
541
+ "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c"
542
+ },
543
+ "dist": {
544
+ "type": "zip",
545
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c53312ecc575caf07b0e90dee43883fdf90ca67c",
546
+ "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c",
547
+ "shasum": ""
548
+ },
549
+ "require": {
550
+ "php": "^7.2|^8.0"
551
+ },
552
+ "conflict": {
553
+ "phpstan/phpstan-shim": "*"
554
+ },
555
+ "bin": [
556
+ "phpstan",
557
+ "phpstan.phar"
558
+ ],
559
+ "type": "library",
560
+ "autoload": {
561
+ "files": [
562
+ "bootstrap.php"
563
+ ]
564
+ },
565
+ "notification-url": "https://packagist.org/downloads/",
566
+ "license": [
567
+ "MIT"
568
+ ],
569
+ "description": "PHPStan - PHP Static Analysis Tool",
570
+ "support": {
571
+ "issues": "https://github.com/phpstan/phpstan/issues",
572
+ "source": "https://github.com/phpstan/phpstan/tree/1.8.2"
573
+ },
574
+ "funding": [
575
+ {
576
+ "url": "https://github.com/ondrejmirtes",
577
+ "type": "github"
578
+ },
579
+ {
580
+ "url": "https://github.com/phpstan",
581
+ "type": "github"
582
+ },
583
+ {
584
+ "url": "https://www.patreon.com/phpstan",
585
+ "type": "patreon"
586
+ },
587
+ {
588
+ "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
589
+ "type": "tidelift"
590
+ }
591
+ ],
592
+ "time": "2022-07-20T09:57:31+00:00"
593
+ },
594
+ {
595
+ "name": "symfony/polyfill-php73",
596
+ "version": "v1.26.0",
597
+ "source": {
598
+ "type": "git",
599
+ "url": "https://github.com/symfony/polyfill-php73.git",
600
+ "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85"
601
+ },
602
+ "dist": {
603
+ "type": "zip",
604
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85",
605
+ "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85",
606
+ "shasum": ""
607
+ },
608
+ "require": {
609
+ "php": ">=7.1"
610
+ },
611
+ "type": "library",
612
+ "extra": {
613
+ "branch-alias": {
614
+ "dev-main": "1.26-dev"
615
+ },
616
+ "thanks": {
617
+ "name": "symfony/polyfill",
618
+ "url": "https://github.com/symfony/polyfill"
619
+ }
620
+ },
621
+ "autoload": {
622
+ "files": [
623
+ "bootstrap.php"
624
+ ],
625
+ "psr-4": {
626
+ "Symfony\\Polyfill\\Php73\\": ""
627
+ },
628
+ "classmap": [
629
+ "Resources/stubs"
630
+ ]
631
+ },
632
+ "notification-url": "https://packagist.org/downloads/",
633
+ "license": [
634
+ "MIT"
635
+ ],
636
+ "authors": [
637
+ {
638
+ "name": "Nicolas Grekas",
639
+ "email": "p@tchwork.com"
640
+ },
641
+ {
642
+ "name": "Symfony Community",
643
+ "homepage": "https://symfony.com/contributors"
644
+ }
645
+ ],
646
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
647
+ "homepage": "https://symfony.com",
648
+ "keywords": [
649
+ "compatibility",
650
+ "polyfill",
651
+ "portable",
652
+ "shim"
653
+ ],
654
+ "support": {
655
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0"
656
+ },
657
+ "funding": [
658
+ {
659
+ "url": "https://symfony.com/sponsor",
660
+ "type": "custom"
661
+ },
662
+ {
663
+ "url": "https://github.com/fabpot",
664
+ "type": "github"
665
+ },
666
+ {
667
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
668
+ "type": "tidelift"
669
+ }
670
+ ],
671
+ "time": "2022-05-24T11:49:31+00:00"
672
+ },
673
+ {
674
+ "name": "szepeviktor/phpstan-wordpress",
675
+ "version": "v1.1.3",
676
+ "source": {
677
+ "type": "git",
678
+ "url": "https://github.com/szepeviktor/phpstan-wordpress.git",
679
+ "reference": "e644df734e1bbe95810e0f617d17df091048a94e"
680
+ },
681
+ "dist": {
682
+ "type": "zip",
683
+ "url": "https://api.github.com/repos/szepeviktor/phpstan-wordpress/zipball/e644df734e1bbe95810e0f617d17df091048a94e",
684
+ "reference": "e644df734e1bbe95810e0f617d17df091048a94e",
685
+ "shasum": ""
686
+ },
687
+ "require": {
688
+ "php": "^7.2 || ^8.0",
689
+ "php-stubs/wordpress-stubs": "^4.7 || ^5.0 || ^6.0",
690
+ "phpstan/phpstan": "^1.6",
691
+ "symfony/polyfill-php73": "^1.12.0"
692
+ },
693
+ "require-dev": {
694
+ "composer/composer": "^2.1.14",
695
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7",
696
+ "php-parallel-lint/php-parallel-lint": "^1.1",
697
+ "phpstan/phpstan-strict-rules": "^1.2",
698
+ "phpunit/phpunit": "^8 || ^9",
699
+ "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^0.6"
700
+ },
701
+ "type": "phpstan-extension",
702
+ "extra": {
703
+ "phpstan": {
704
+ "includes": [
705
+ "extension.neon"
706
+ ]
707
+ }
708
+ },
709
+ "autoload": {
710
+ "psr-4": {
711
+ "SzepeViktor\\PHPStan\\WordPress\\": "src/"
712
+ }
713
+ },
714
+ "notification-url": "https://packagist.org/downloads/",
715
+ "license": [
716
+ "MIT"
717
+ ],
718
+ "description": "WordPress extensions for PHPStan",
719
+ "keywords": [
720
+ "PHPStan",
721
+ "code analyse",
722
+ "code analysis",
723
+ "static analysis",
724
+ "wordpress"
725
+ ],
726
+ "support": {
727
+ "issues": "https://github.com/szepeviktor/phpstan-wordpress/issues",
728
+ "source": "https://github.com/szepeviktor/phpstan-wordpress/tree/v1.1.3"
729
+ },
730
+ "funding": [
731
+ {
732
+ "url": "https://www.paypal.me/szepeviktor",
733
+ "type": "custom"
734
+ },
735
+ {
736
+ "url": "https://github.com/szepeviktor",
737
+ "type": "github"
738
+ }
739
+ ],
740
+ "time": "2022-09-22T13:14:50+00:00"
741
+ }
742
+ ],
743
  "aliases": [],
744
  "minimum-stability": "stable",
745
  "stability-flags": [],
751
  "ext-zip": "*"
752
  },
753
  "platform-dev": [],
754
+ "plugin-api-version": "2.3.0"
755
  }
creative-mail-plugin.php CHANGED
@@ -9,50 +9,51 @@
9
  * Plugin URI: https://wordpress.org/plugins/creative-mail-by-constant-contact/
10
  * Description: Free email marketing designed specifically for WordPress, Jetpack and WooCommerce. Send newsletters, promotions, updates and transactional e-commerce emails. Simple and easy, powered by Constant Contact’s rock solid reliability.
11
  * Author: Constant Contact
12
- * Version: 1.5.4
13
  * Author URI: https://www.constantcontact.com
14
- * WC requires at least: 3.0.0
15
  * WC tested up to: 6.8.2
16
  */
17
  use CreativeMail\CreativeMail;
18
  use CreativeMail\Blocks\LoadBlock;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  function _load_ce4wp_plugin()
20
  {
21
  global $creativemail;
22
 
23
- if($creativemail != null) {
24
  return true;
25
  }
26
 
27
- define('CE4WP_PLUGIN_DIR', __DIR__ . '/');
28
- define('CE4WP_PLUGIN_URL', plugin_dir_url(__FILE__) . '/');
29
- define('CE4WP_PLUGIN_FILE', __FILE__);
30
- define('CE4WP_PLUGIN_VERSION', '1.5.4');
31
- define('CE4WP_INSTANCE_UUID_KEY', 'ce4wp_instance_uuid');
32
- define('CE4WP_INSTANCE_HANDSHAKE_TOKEN', 'ce4wp_handshake_token');
33
- define('CE4WP_INSTANCE_HANDSHAKE_EXPIRATION', 'ce4wp_handshake_expiration');
34
- define('CE4WP_INSTANCE_ID_KEY', 'ce4wp_instance_id');
35
- define('CE4WP_INSTANCE_API_KEY_KEY', 'ce4wp_instance_api_key');
36
- define('CE4WP_ENCRYPTION_KEY_KEY', 'ce4wp_encryption_key');
37
- define('CE4WP_CONNECTED_ACCOUNT_ID', 'ce4wp_connected_account_id');
38
- define('CE4WP_ACTIVATED_PLUGINS', 'ce4wp_activated_plugins');
39
- define('CE4WP_MANAGED_EMAIL_NOTIFICATIONS', 'ce4wp_managed_email_notifications');
40
- define('CE4WP_ACCEPTED_CONSENT', 'ce4wp_accepted_consent');
41
- define('CE4WP_SYNCHRONIZE_ACTION', 'ce4wp_synchronize_contacts');
42
- define('CE4WP_CHECKOUT_CHECKBOX_TEXT', 'ce4wp_checkout_checkbox_text');
43
- define('CE4WP_CHECKOUT_CHECKBOX_ENABLED', 'ce4wp_checkout_checkbox_enabled');
44
- define('CE4WP_APP_GATEWAY_URL', 'https://app-gateway.creativemail.com/');
45
- define('CE4WP_APP_URL', 'https://app.creativemail.com/');
46
- define('CE4WP_ENVIRONMENT', 'PRODUCTION');
47
- define('CE4WP_BUILD_NUMBER', '1766');
48
- define('CE4WP_RAYGUN_PHP_KEY', 'Z85xL3mkgnW13Ri9DajGUg');
49
- define('CE4WP_BATCH_SIZE', 500);
50
- define('CE4WP_WC_API_KEY_ID', 'ce4wp_woocommerce_api_key_id');
51
- define('CE4WP_WC_API_CONSUMER_KEY', 'ce4wp_woocommerce_consumer_key');
52
- define('CE4WP_REFERRED_BY', 'ce4wp_referred_by');
53
- define('CE4WP_HIDE_BANNER', 'ce4wp_hide_banner');
54
-
55
- // Load all the required files
56
  if (file_exists(__DIR__ . '/vendor/autoload.php')) {
57
  include_once __DIR__ . '/vendor/autoload.php';
58
  }
9
  * Plugin URI: https://wordpress.org/plugins/creative-mail-by-constant-contact/
10
  * Description: Free email marketing designed specifically for WordPress, Jetpack and WooCommerce. Send newsletters, promotions, updates and transactional e-commerce emails. Simple and easy, powered by Constant Contact’s rock solid reliability.
11
  * Author: Constant Contact
12
+ * Version: 1.6.0
13
  * Author URI: https://www.constantcontact.com
14
+ * WC requires at least: 3.6.0
15
  * WC tested up to: 6.8.2
16
  */
17
  use CreativeMail\CreativeMail;
18
  use CreativeMail\Blocks\LoadBlock;
19
+
20
+ define('CE4WP_PLUGIN_DIR', __DIR__ . '/');
21
+ define('CE4WP_PLUGIN_URL', plugin_dir_url(__FILE__) . '/');
22
+ define('CE4WP_PLUGIN_FILE', __FILE__);
23
+ define('CE4WP_PLUGIN_VERSION', '1.6.0');
24
+ define('CE4WP_INSTANCE_UUID_KEY', 'ce4wp_instance_uuid');
25
+ define('CE4WP_INSTANCE_HANDSHAKE_TOKEN', 'ce4wp_handshake_token');
26
+ define('CE4WP_INSTANCE_HANDSHAKE_EXPIRATION', 'ce4wp_handshake_expiration');
27
+ define('CE4WP_INSTANCE_ID_KEY', 'ce4wp_instance_id');
28
+ define('CE4WP_INSTANCE_API_KEY_KEY', 'ce4wp_instance_api_key');
29
+ define('CE4WP_ENCRYPTION_KEY_KEY', 'ce4wp_encryption_key');
30
+ define('CE4WP_CONNECTED_ACCOUNT_ID', 'ce4wp_connected_account_id');
31
+ define('CE4WP_ACTIVATED_PLUGINS', 'ce4wp_activated_plugins');
32
+ define('CE4WP_MANAGED_EMAIL_NOTIFICATIONS', 'ce4wp_managed_email_notifications');
33
+ define('CE4WP_ACCEPTED_CONSENT', 'ce4wp_accepted_consent');
34
+ define('CE4WP_SYNCHRONIZE_ACTION', 'ce4wp_synchronize_contacts');
35
+ define('CE4WP_CHECKOUT_CHECKBOX_TEXT', 'ce4wp_checkout_checkbox_text');
36
+ define('CE4WP_CHECKOUT_CHECKBOX_ENABLED', 'ce4wp_checkout_checkbox_enabled');
37
+ define('CE4WP_APP_GATEWAY_URL', 'https://app-gateway.creativemail.com/');
38
+ define('CE4WP_APP_URL', 'https://app.creativemail.com/');
39
+ define('CE4WP_ENVIRONMENT', 'PRODUCTION');
40
+ define('CE4WP_BUILD_NUMBER', '1834');
41
+ define('CE4WP_RAYGUN_PHP_KEY', 'Z85xL3mkgnW13Ri9DajGUg');
42
+ define('CE4WP_BATCH_SIZE', 500);
43
+ define('CE4WP_WC_API_KEY_ID', 'ce4wp_woocommerce_api_key_id');
44
+ define('CE4WP_WC_API_CONSUMER_KEY', 'ce4wp_woocommerce_consumer_key');
45
+ define('CE4WP_REFERRED_BY', 'ce4wp_referred_by');
46
+ define('CE4WP_HIDE_BANNER', 'ce4wp_hide_banner');
47
+
48
  function _load_ce4wp_plugin()
49
  {
50
  global $creativemail;
51
 
52
+ if ($creativemail != null) {
53
  return true;
54
  }
55
 
56
+ // Load all the required files.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  if (file_exists(__DIR__ . '/vendor/autoload.php')) {
58
  include_once __DIR__ . '/vendor/autoload.php';
59
  }
readme.txt CHANGED
@@ -1,14 +1,14 @@
1
  === Creative Mail – Easier WordPress & WooCommerce Email Marketing ===
2
  Contributors: Constant Contact
3
  Tags: email, marketing, newsletter, subscribe, contact form, constant contact, crm, automations, ecommerce, promotion, offers, retargeting
4
- Requires at least: 4.6
5
  Tested up to: 6.0.2
6
- Stable tag: 1.5.4
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
- Requires PHP: 5.6
10
  Website: https://www.creativemail.com
11
- WC requires at least: 3.0.0
12
  WC tested up to: 6.8.2
13
 
14
  Creative Mail was designed specifically for WordPress and WooCommerce.
@@ -102,6 +102,7 @@ Creative Mail by Constant Contact [Privacy Notice](https://www.endurance.com/pri
102
  6. Enhance your brand with LogoBuilder
103
 
104
  == Changelog ==
 
105
  * 1.5.4 - Migration to WordPress version 6.0.2 and Checkout mail templates update
106
  * 1.5.3 - README update
107
  * 1.5.2 - Small bug fix for PHP versions previous to 7.1
@@ -127,6 +128,11 @@ Creative Mail by Constant Contact [Privacy Notice](https://www.endurance.com/pri
127
  * 1.3.2 - Fixes an issue where the contact sync might cause a critical error.
128
  * 1.3.1 - Add the ability to show the amount of recovered revenue via abandoned carts.
129
  * 1.3.0 - Support for abandoned cart emails
 
 
 
 
 
130
 
131
  == Installation ==
132
 
1
  === Creative Mail – Easier WordPress & WooCommerce Email Marketing ===
2
  Contributors: Constant Contact
3
  Tags: email, marketing, newsletter, subscribe, contact form, constant contact, crm, automations, ecommerce, promotion, offers, retargeting
4
+ Requires at least: 4.9
5
  Tested up to: 6.0.2
6
+ Stable tag: 1.6.0
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ Requires PHP: 7.2
10
  Website: https://www.creativemail.com
11
+ WC requires at least: 3.6.0
12
  WC tested up to: 6.8.2
13
 
14
  Creative Mail was designed specifically for WordPress and WooCommerce.
102
  6. Enhance your brand with LogoBuilder
103
 
104
  == Changelog ==
105
+ * 1.6.0 - Security update, Bug fixes and Support to sync Address Fields for Contact Form 7
106
  * 1.5.4 - Migration to WordPress version 6.0.2 and Checkout mail templates update
107
  * 1.5.3 - README update
108
  * 1.5.2 - Small bug fix for PHP versions previous to 7.1
128
  * 1.3.2 - Fixes an issue where the contact sync might cause a critical error.
129
  * 1.3.1 - Add the ability to show the amount of recovered revenue via abandoned carts.
130
  * 1.3.0 - Support for abandoned cart emails
131
+ * 1.2.4 - Introduces a 'Reset' button on the settings page for accounts that are stuck.
132
+ * 1.2.3 - Fixes an issue where the banner would show up again after being dismissed.
133
+ * 1.2.2 - Introduction of multistep automations and fixes a couple of small issues in the CreativeMail widgets
134
+ * 1.2.1 - Fixes an issue where some users would experience an issue where our UI was blocked by pop-up blockers.
135
+ * 1.2.0 - Context aware notifications, add support for Ninja forms, add support for Caldera forms
136
 
137
  == Installation ==
138
 
src/Helpers/EncryptionHelper.php CHANGED
@@ -5,7 +5,10 @@ namespace CreativeMail\Helpers;
5
 
6
  use CreativeMail\Managers\RaygunManager;
7
  use Defuse\Crypto\Crypto;
 
 
8
  use Defuse\Crypto\Key;
 
9
 
10
  class EncryptionHelper
11
  {
@@ -14,8 +17,8 @@ class EncryptionHelper
14
  * Will get the previously used encryption key, or will generate a new key of no key is present.
15
  *
16
  * @return Key
17
- * @throws \Defuse\Crypto\Exception\BadFormatException
18
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
19
  */
20
  private static function get_encryption_key()
21
  {
@@ -25,7 +28,9 @@ class EncryptionHelper
25
  update_option(CE4WP_ENCRYPTION_KEY_KEY, $key->saveToAsciiSafeString());
26
  }
27
  else {
28
- $key = Key::loadFromAsciiSafeString($key);
 
 
29
  }
30
 
31
  return $key;
@@ -39,8 +44,8 @@ class EncryptionHelper
39
  * @param $autoload bool Should this option be auto loaded.
40
  *
41
  * @return bool
42
- * @throws \Defuse\Crypto\Exception\BadFormatException
43
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
44
  */
45
  public static function update_option($option, $value, $autoload = null)
46
  {
@@ -54,8 +59,8 @@ class EncryptionHelper
54
  * @param $value mixed The value that should be stored encrypted
55
  * @param $autoload bool Should this option be auto loaded.
56
  *
57
- * @throws \Defuse\Crypto\Exception\BadFormatException
58
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
59
  */
60
  public static function add_option($option, $value, $autoload = true)
61
  {
@@ -77,11 +82,13 @@ class EncryptionHelper
77
  return $default;
78
  } else {
79
  try {
80
- return Crypto::decrypt($encrypted, self::get_encryption_key());
81
- } catch ( \Exception $e ) {
 
 
82
  RaygunManager::get_instance()->exception_handler($e);
83
- return $encrypted;
84
  }
85
  }
 
86
  }
87
  }
5
 
6
  use CreativeMail\Managers\RaygunManager;
7
  use Defuse\Crypto\Crypto;
8
+ use Defuse\Crypto\Exception\BadFormatException;
9
+ use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
10
  use Defuse\Crypto\Key;
11
+ use Exception;
12
 
13
  class EncryptionHelper
14
  {
17
  * Will get the previously used encryption key, or will generate a new key of no key is present.
18
  *
19
  * @return Key
20
+ * @throws BadFormatException
21
+ * @throws EnvironmentIsBrokenException
22
  */
23
  private static function get_encryption_key()
24
  {
28
  update_option(CE4WP_ENCRYPTION_KEY_KEY, $key->saveToAsciiSafeString());
29
  }
30
  else {
31
+ if (is_string($key)) {
32
+ $key = Key::loadFromAsciiSafeString($key);
33
+ }
34
  }
35
 
36
  return $key;
44
  * @param $autoload bool Should this option be auto loaded.
45
  *
46
  * @return bool
47
+ * @throws BadFormatException
48
+ * @throws EnvironmentIsBrokenException
49
  */
50
  public static function update_option($option, $value, $autoload = null)
51
  {
59
  * @param $value mixed The value that should be stored encrypted
60
  * @param $autoload bool Should this option be auto loaded.
61
  *
62
+ * @throws BadFormatException
63
+ * @throws EnvironmentIsBrokenException
64
  */
65
  public static function add_option($option, $value, $autoload = true)
66
  {
82
  return $default;
83
  } else {
84
  try {
85
+ if (is_string($encrypted)) {
86
+ return Crypto::decrypt($encrypted, self::get_encryption_key());
87
+ }
88
+ } catch ( Exception $e ) {
89
  RaygunManager::get_instance()->exception_handler($e);
 
90
  }
91
  }
92
+ return $encrypted;
93
  }
94
  }
src/Helpers/EnvironmentHelper.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
 
4
  namespace CreativeMail\Helpers;
@@ -29,10 +29,10 @@ class EnvironmentHelper
29
  */
30
  public static function get_environment()
31
  {
32
-
33
  $environment = CE4WP_ENVIRONMENT;
 
34
  if ($environment === "{ENV}") {
35
- return EnvironmentNames::DEVELOPMENT;
36
  }
37
 
38
  return $environment;
@@ -41,23 +41,19 @@ class EnvironmentHelper
41
  /**
42
  * Gets the url of the app-gateway.
43
  *
44
- * @param null $path
45
  *
46
  * @return string
47
  */
48
- public static function get_app_gateway_url($path = null)
49
  {
50
  $url = CE4WP_APP_GATEWAY_URL;
 
51
  if ($url === '{GATEWAY_URL}') {
52
  $url = 'https://app-gateway.creativemail.com/';
53
  }
54
-
55
- if (is_null($path)) {
56
- return $url;
57
- }
58
-
59
- if (isset($path) && !empty($path)) {
60
- return $url.$path;
61
  }
62
 
63
  return $url;
@@ -72,7 +68,7 @@ class EnvironmentHelper
72
  {
73
  $url = CE4WP_APP_URL;
74
  if ($url === '{APP_URL}') {
75
- return 'https://app.creativemail.com/';
76
  }
77
 
78
  return $url;
1
+ <?php declare(strict_types = 1);
2
 
3
 
4
  namespace CreativeMail\Helpers;
29
  */
30
  public static function get_environment()
31
  {
 
32
  $environment = CE4WP_ENVIRONMENT;
33
+
34
  if ($environment === "{ENV}") {
35
+ $environment = EnvironmentNames::DEVELOPMENT;
36
  }
37
 
38
  return $environment;
41
  /**
42
  * Gets the url of the app-gateway.
43
  *
44
+ * @param string $path
45
  *
46
  * @return string
47
  */
48
+ public static function get_app_gateway_url($path = '')
49
  {
50
  $url = CE4WP_APP_GATEWAY_URL;
51
+
52
  if ($url === '{GATEWAY_URL}') {
53
  $url = 'https://app-gateway.creativemail.com/';
54
  }
55
+ if (!empty($path)) {
56
+ $url .= $path;
 
 
 
 
 
57
  }
58
 
59
  return $url;
68
  {
69
  $url = CE4WP_APP_URL;
70
  if ($url === '{APP_URL}') {
71
+ $url = 'https://app.creativemail.com/';
72
  }
73
 
74
  return $url;
src/Helpers/OptionsHelper.php CHANGED
@@ -3,6 +3,8 @@
3
  namespace CreativeMail\Helpers;
4
 
5
  use CreativeMail\Models\OptionsSchema;
 
 
6
 
7
  /**
8
  * Class CE4WP_OptionsHelper
@@ -20,14 +22,15 @@ class OptionsHelper
20
  */
21
  public static function get_instance_uuid()
22
  {
23
-
24
  // Do we already have a UUID?
25
  $instanceUuid = get_option(CE4WP_INSTANCE_UUID_KEY, null);
26
- if ($instanceUuid === null) {
27
 
28
- // Just generate one and store it
 
29
  $instanceUuid = uniqid();
30
  add_option(CE4WP_INSTANCE_UUID_KEY, $instanceUuid);
 
 
31
  }
32
 
33
  return $instanceUuid;
@@ -62,7 +65,8 @@ class OptionsHelper
62
  */
63
  public static function get_handshake_expiration()
64
  {
65
- return get_option(CE4WP_INSTANCE_HANDSHAKE_EXPIRATION, null);
 
66
  }
67
 
68
  /**
@@ -72,7 +76,8 @@ class OptionsHelper
72
  */
73
  public static function get_wc_consumer_key()
74
  {
75
- return EncryptionHelper::get_option(CE4WP_WC_API_CONSUMER_KEY, null);
 
76
  }
77
 
78
  /**
@@ -80,8 +85,8 @@ class OptionsHelper
80
  *
81
  * @param $value string
82
  *
83
- * @throws \Defuse\Crypto\Exception\BadFormatException
84
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
85
  */
86
  public static function set_wc_consumer_key($value)
87
  {
@@ -91,7 +96,7 @@ class OptionsHelper
91
  /**
92
  * Deletes the consumer key.
93
  *
94
- * @return int|null
95
  */
96
  public static function delete_wc_consumer_key()
97
  {
@@ -105,7 +110,8 @@ class OptionsHelper
105
  */
106
  public static function get_wc_api_key_id()
107
  {
108
- return get_option(CE4WP_WC_API_KEY_ID, null);
 
109
  }
110
 
111
  /**
@@ -121,7 +127,7 @@ class OptionsHelper
121
  /**
122
  * Deletes the api key id.
123
  *
124
- * @return int|null
125
  */
126
  public static function delete_wc_api_key_id()
127
  {
@@ -211,11 +217,11 @@ class OptionsHelper
211
  /**
212
  * Gets the API key that can be used to interact with the Creative Mail platform.
213
  *
214
- * @return string|null
215
  */
216
  public static function get_instance_api_key()
217
  {
218
- return EncryptionHelper::get_option(CE4WP_INSTANCE_API_KEY_KEY, null);
219
  }
220
 
221
  /**
@@ -223,8 +229,8 @@ class OptionsHelper
223
  *
224
  * @param $value string
225
  *
226
- * @throws \Defuse\Crypto\Exception\BadFormatException
227
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
228
  */
229
  public static function set_instance_api_key($value)
230
  {
@@ -242,7 +248,7 @@ class OptionsHelper
242
  }
243
 
244
  /**
245
- * Sets a string representing all the plugins that were activated for synchronization during the setup process.
246
  *
247
  * @param $plugins
248
  */
@@ -254,7 +260,7 @@ class OptionsHelper
254
  /**
255
  * Get managed email notification array or string
256
  *
257
- * @return string|array
258
  */
259
  public static function get_managed_email_notifications()
260
  {
@@ -264,7 +270,7 @@ class OptionsHelper
264
  foreach ( $rows as $row ) {
265
  $name = $row->option_name;
266
  if ($name === CE4WP_MANAGED_EMAIL_NOTIFICATIONS ) {
267
- //convert old to new format
268
  return self::convert_managed_email_notifications($row->option_value);
269
  }
270
 
@@ -344,13 +350,13 @@ class OptionsHelper
344
  }
345
 
346
  /**
347
- * Gets an string value representing who referred this customer
348
  *
349
- * @return string|null
350
  */
351
  public static function get_referred_by()
352
  {
353
- return get_option(CE4WP_REFERRED_BY, null);
354
  }
355
 
356
  /**
3
  namespace CreativeMail\Helpers;
4
 
5
  use CreativeMail\Models\OptionsSchema;
6
+ use Defuse\Crypto\Exception\BadFormatException;
7
+ use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
8
 
9
  /**
10
  * Class CE4WP_OptionsHelper
22
  */
23
  public static function get_instance_uuid()
24
  {
 
25
  // Do we already have a UUID?
26
  $instanceUuid = get_option(CE4WP_INSTANCE_UUID_KEY, null);
 
27
 
28
+ if ($instanceUuid === null) {
29
+ // Just generate one and store it.
30
  $instanceUuid = uniqid();
31
  add_option(CE4WP_INSTANCE_UUID_KEY, $instanceUuid);
32
+ } else {
33
+ $instanceUuid = (string) $instanceUuid;
34
  }
35
 
36
  return $instanceUuid;
65
  */
66
  public static function get_handshake_expiration()
67
  {
68
+ $handshake_expiration = get_option(CE4WP_INSTANCE_HANDSHAKE_EXPIRATION, null);
69
+ return !empty($handshake_expiration) ? (int) $handshake_expiration : null;
70
  }
71
 
72
  /**
76
  */
77
  public static function get_wc_consumer_key()
78
  {
79
+ $wc_consumer_key = get_option(CE4WP_WC_API_CONSUMER_KEY, null);
80
+ return is_string($wc_consumer_key) ? $wc_consumer_key : null;
81
  }
82
 
83
  /**
85
  *
86
  * @param $value string
87
  *
88
+ * @throws BadFormatException
89
+ * @throws EnvironmentIsBrokenException
90
  */
91
  public static function set_wc_consumer_key($value)
92
  {
96
  /**
97
  * Deletes the consumer key.
98
  *
99
+ * @return bool
100
  */
101
  public static function delete_wc_consumer_key()
102
  {
110
  */
111
  public static function get_wc_api_key_id()
112
  {
113
+ $wc_api_key_id = get_option(CE4WP_WC_API_KEY_ID, null);
114
+ return !empty($wc_api_key_id) && is_numeric($wc_api_key_id) ? (int) $wc_api_key_id : null;
115
  }
116
 
117
  /**
127
  /**
128
  * Deletes the api key id.
129
  *
130
+ * @return bool
131
  */
132
  public static function delete_wc_api_key_id()
133
  {
217
  /**
218
  * Gets the API key that can be used to interact with the Creative Mail platform.
219
  *
220
+ * @return string
221
  */
222
  public static function get_instance_api_key()
223
  {
224
+ return EncryptionHelper::get_option(CE4WP_INSTANCE_API_KEY_KEY);
225
  }
226
 
227
  /**
229
  *
230
  * @param $value string
231
  *
232
+ * @throws BadFormatException
233
+ * @throws EnvironmentIsBrokenException
234
  */
235
  public static function set_instance_api_key($value)
236
  {
248
  }
249
 
250
  /**
251
+ * Sets a string represeadminnting all the plugins that were activated for synchronization during the setup process.
252
  *
253
  * @param $plugins
254
  */
260
  /**
261
  * Get managed email notification array or string
262
  *
263
+ * @return array
264
  */
265
  public static function get_managed_email_notifications()
266
  {
270
  foreach ( $rows as $row ) {
271
  $name = $row->option_name;
272
  if ($name === CE4WP_MANAGED_EMAIL_NOTIFICATIONS ) {
273
+ // Convert old to new format.
274
  return self::convert_managed_email_notifications($row->option_value);
275
  }
276
 
350
  }
351
 
352
  /**
353
+ * Gets a string value representing who referred this customer
354
  *
355
+ * @return string
356
  */
357
  public static function get_referred_by()
358
  {
359
+ return get_option(CE4WP_REFERRED_BY, '');
360
  }
361
 
362
  /**
src/Helpers/ValidationHelper.php CHANGED
@@ -7,6 +7,6 @@ class ValidationHelper
7
  {
8
  public static function is_null_or_empty($value)
9
  {
10
- return !isset($value) || empty($value);
11
  }
12
- }
7
  {
8
  public static function is_null_or_empty($value)
9
  {
10
+ return empty($value);
11
  }
12
+ }
src/Integrations/Integration.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace CreativeMail\Integrations;
4
 
 
 
5
  /**
6
  * Class Integration
7
  *
@@ -25,8 +27,8 @@ class Integration
25
  *
26
  * @param $slug string The slug that you want to use for this integration.
27
  * @param $name string The display name of the plugin
28
- * @param $class string The path the the plugin class that should be used to check if the plugin required for this integration is installed.
29
- * @param $integration_handler string The name of the class that should be instantiated when this integration gets activated.
30
  * @param $hide_from_suggestions boolean If you want to hide this plugin from the suggestion list, set this to true
31
  * @param $url string The link to the plugin store, default will set it based on the slug
32
  * @param $has_multiple_plugins boolean If true the plugin will search using the basename (some plugins have different directories depending on license)
@@ -77,7 +79,7 @@ class Integration
77
  /**
78
  * Gets the name of the class that should be instantiated when activating this integration.
79
  *
80
- * @return string
81
  */
82
  public function get_integration_handler()
83
  {
2
 
3
  namespace CreativeMail\Integrations;
4
 
5
+ use CreativeMail\Modules\Contacts\Handlers\BaseContactFormPluginHandler;
6
+
7
  /**
8
  * Class Integration
9
  *
27
  *
28
  * @param $slug string The slug that you want to use for this integration.
29
  * @param $name string The display name of the plugin
30
+ * @param $class string The path the plugin class that should be used to check if the plugin required for this integration is installed.
31
+ * @param $integration_handler object The class that should be instantiated when this integration gets activated.
32
  * @param $hide_from_suggestions boolean If you want to hide this plugin from the suggestion list, set this to true
33
  * @param $url string The link to the plugin store, default will set it based on the slug
34
  * @param $has_multiple_plugins boolean If true the plugin will search using the basename (some plugins have different directories depending on license)
79
  /**
80
  * Gets the name of the class that should be instantiated when activating this integration.
81
  *
82
+ * @return object
83
  */
84
  public function get_integration_handler()
85
  {
src/Managers/AdminManager.php CHANGED
@@ -109,7 +109,6 @@ class AdminManager
109
  if (is_null($sso))
110
  {
111
  $current_user = wp_get_current_user();
112
-
113
  $redirectUrl = EnvironmentHelper::get_app_gateway_url('wordpress/v1.0/instances/open?clearSession=true&redirectUrl=');
114
  $onboardingUrl = EnvironmentHelper::get_app_url() . 'marketing/onboarding/signup?wp_site_name=' . $this->instance_name
115
  . '&wp_site_uuid=' . $this->instance_uuid
@@ -122,11 +121,10 @@ class AdminManager
122
  . '&last_name=' . urlencode( $current_user->user_lastname )
123
  . '&email=' . urlencode( $current_user->user_email );
124
  $referred_by = OptionsHelper::get_referred_by();
125
- if (isset($referred_by)) {
 
126
  $utm_campaign = '';
127
- if (is_array($referred_by) && array_key_exists('plugin', $referred_by) && array_key_exists('source', $referred_by)) {
128
- $utm_campaign = $referred_by['plugin'] . $referred_by['source'];
129
- } else if (is_string($referred_by)) {
130
  $utm_campaign = str_replace(';', '|', $referred_by);
131
  }
132
  $onboardingUrl .= '&utm_source=wordpress&utm_medium=plugin&utm_campaign=' . $utm_campaign;
@@ -138,7 +136,7 @@ class AdminManager
138
 
139
  function request_single_sign_on_url()
140
  {
141
- // Check for nonce security
142
  $this->check_nonce();
143
 
144
  $linkReference = array_key_exists('link_reference', $_POST) ? $_POST['link_reference'] : null;
@@ -152,7 +150,7 @@ class AdminManager
152
 
153
  function deactivate_survey_post()
154
  {
155
- // Check for nonce security
156
  $this->check_nonce();
157
 
158
  $instance_id = OptionsHelper::get_instance_id();
@@ -204,7 +202,7 @@ class AdminManager
204
  if (!$this->should_show_deactivation_modal()) {
205
  return;
206
  }
207
- wp_enqueue_script('ce4wp_deactivate_survey', CE4WP_PLUGIN_URL.'assets/js/deactivation.js', null,null,true);
208
  wp_localize_script('ce4wp_deactivate_survey', self::ADMIN_CE4WP_DATA_VAR, array(
209
  'url' => admin_url('admin-ajax.php'),
210
  'nonce' => $this->create_nonce()
@@ -215,7 +213,7 @@ class AdminManager
215
  if (!$this->should_show_deactivation_modal()) {
216
  return;
217
  }
218
- wp_enqueue_style('ce4wp_deactivate_survey', CE4WP_PLUGIN_URL.'assets/css/deactivation.css', null,null,null);
219
  }
220
 
221
  function show_deactivation_modal() {
@@ -269,6 +267,7 @@ class AdminManager
269
 
270
  $install_date = date_create($install_date);
271
  $date_now = date_create(date('Y-m-d G:i:s'));
 
272
  $date_diff = date_diff($install_date, $date_now);
273
 
274
  if ($date_diff->format("%d") < 7 ) {
@@ -375,7 +374,7 @@ class AdminManager
375
  */
376
  public function add_assets()
377
  {
378
- wp_register_style('ce4wp_admin', CE4WP_PLUGIN_URL . 'assets/css/admin.css', null, CE4WP_PLUGIN_VERSION);
379
  wp_enqueue_style('ce4wp_admin');
380
  wp_enqueue_style('ce4wp-font-poppins', 'https://fonts.googleapis.com/css?family=Poppins:400,500');
381
  wp_enqueue_script('wp-api');
@@ -384,7 +383,7 @@ class AdminManager
384
 
385
  if ($this->is_cm_screen_and_show_footer())
386
  {
387
- wp_enqueue_script('ce4wp_admin_footer_rating', CE4WP_PLUGIN_URL . 'assets/js/footer_rating.js', 'wp-api', CE4WP_PLUGIN_VERSION, true);
388
  }
389
  }
390
 
@@ -399,59 +398,68 @@ class AdminManager
399
  ? array( $this, 'show_dashboard' )
400
  : array( $this, 'show_setup' );
401
 
402
- // Create the root menu item
403
- $icon = file_get_contents(CE4WP_PLUGIN_DIR . 'assets/images/icon.svg');
404
  // Filter to change the menu position if there is any conflict.
405
  $position = apply_filters( 'ce4wp_menu_position', '35.5' );
 
406
  add_menu_page('Creative Mail', esc_html__('Creative Mail', self::DOMAIN_CE4WP), 'manage_options', 'creativemail', $main_action, 'data:image/svg+xml;base64,' . base64_encode($icon), $position);
407
 
408
  $sub_actions = array();
409
 
410
  if ($hasConnectedAccount) {
411
- array_push($sub_actions, array(
412
- 'title' => esc_html__('Campaigns', self::DOMAIN_CE4WP),
413
- 'text' => '<span id="ce4wp-menu-campaigns" data-link_reference="5166faec-1dbb-4434-bad0-bb2f75898f92">'. __( 'Campaigns', self::DOMAIN_CE4WP) .'</span>',
414
- 'slug' => 'creativemail_campaigns',
415
  'callback' => null
416
- ));
417
- array_push($sub_actions, array(
418
- 'title' => esc_html__('Contacts', self::DOMAIN_CE4WP),
419
- 'text' => '<span id="ce4wp-menu-contacts" data-link_reference="836b20fc-9ff1-41b2-912b-a8646caf05a4">'. __( 'Contacts', self::DOMAIN_CE4WP) .'</span>',
420
- 'slug' => 'creativemail_contacts',
421
  'callback' => null
422
- ));
423
- array_push($sub_actions, array(
424
- 'title' => esc_html__('WooCommerce', self::DOMAIN_CE4WP),
425
- 'text' => '<span id="ce4wp-menu-woocommerce" data-link_reference="1fabdbe2-95ed-4e1e-a2f3-ba0278f5096f">'. __( 'WooCommerce', self::DOMAIN_CE4WP) .'</span>',
426
- 'slug' => 'creativemail_woocommerce',
427
  'callback' => null
428
- ));
429
- array_push($sub_actions, array(
430
- 'title' => esc_html__('Automation', self::DOMAIN_CE4WP),
431
- 'text' => '<span id="ce4wp-menu-automation" data-link_reference="d5baea05-c603-4cca-852e-f8e82414f6b0">'. __( 'Automation', self::DOMAIN_CE4WP) .'</span>',
432
- 'slug' => 'creativemail_automation',
433
  'callback' => null
434
- ));
435
  }
436
-
437
- array_push($sub_actions, array(
438
- 'title' => esc_html__('Settings', self::DOMAIN_CE4WP),
439
- 'text' => __( 'Settings', self::DOMAIN_CE4WP),
440
- 'slug' => 'creativemail_settings',
441
- 'callback' => array( $this, 'show_settings_page' )
442
- ));
443
 
444
  foreach ($sub_actions as $sub_action) {
445
- add_submenu_page('creativemail', 'Creative Mail - ' . $sub_action['title'], $sub_action['text'], 'manage_options', $sub_action['slug'], $sub_action['callback']);
 
 
 
 
 
 
 
 
446
  }
447
 
448
- //add woocommerce sub menu page
449
  add_submenu_page(
450
  self::ADMIN_WOOCOMMERCE,
451
  esc_html__('Creative Mail', self::DOMAIN_CE4WP),
452
  esc_html__('Creative Mail', self::DOMAIN_CE4WP),
453
  'manage_woocommerce',
454
  'ce4wp-woo-settings',
 
455
  $main_action
456
  );
457
  }
@@ -536,7 +544,7 @@ class AdminManager
536
  }
537
 
538
  private function enqueue_dashboard_js() {
539
- wp_enqueue_script('ce4wp_dashboard', CE4WP_PLUGIN_URL.'assets/js/dashboard.js', 'jquery',CE4WP_PLUGIN_VERSION);
540
  wp_localize_script('ce4wp_dashboard', self::ADMIN_CE4WP_DATA_VAR, array(
541
  'url' => admin_url('admin-ajax.php'),
542
  'nonce' => $this->create_nonce()
@@ -564,7 +572,7 @@ class AdminManager
564
  $instance_api_key = OptionsHelper::get_instance_api_key();
565
  $connected_account_id = OptionsHelper::get_connected_account_id();
566
 
567
- if (isset($instance_id) && isset($instance_api_key) && isset($connected_account_id)) {
568
  try {
569
  return SsoHelper::generate_sso_link($instance_id, $instance_api_key, $connected_account_id, $linkReference, $linkParameters);
570
  }
109
  if (is_null($sso))
110
  {
111
  $current_user = wp_get_current_user();
 
112
  $redirectUrl = EnvironmentHelper::get_app_gateway_url('wordpress/v1.0/instances/open?clearSession=true&redirectUrl=');
113
  $onboardingUrl = EnvironmentHelper::get_app_url() . 'marketing/onboarding/signup?wp_site_name=' . $this->instance_name
114
  . '&wp_site_uuid=' . $this->instance_uuid
121
  . '&last_name=' . urlencode( $current_user->user_lastname )
122
  . '&email=' . urlencode( $current_user->user_email );
123
  $referred_by = OptionsHelper::get_referred_by();
124
+
125
+ if (!empty($referred_by)) {
126
  $utm_campaign = '';
127
+ if (is_string($referred_by)) {
 
 
128
  $utm_campaign = str_replace(';', '|', $referred_by);
129
  }
130
  $onboardingUrl .= '&utm_source=wordpress&utm_medium=plugin&utm_campaign=' . $utm_campaign;
136
 
137
  function request_single_sign_on_url()
138
  {
139
+ // Check for nonce security.
140
  $this->check_nonce();
141
 
142
  $linkReference = array_key_exists('link_reference', $_POST) ? $_POST['link_reference'] : null;
150
 
151
  function deactivate_survey_post()
152
  {
153
+ // Check for nonce security.
154
  $this->check_nonce();
155
 
156
  $instance_id = OptionsHelper::get_instance_id();
202
  if (!$this->should_show_deactivation_modal()) {
203
  return;
204
  }
205
+ wp_enqueue_script('ce4wp_deactivate_survey', CE4WP_PLUGIN_URL.'assets/js/deactivation.js', [],CE4WP_PLUGIN_VERSION,true);
206
  wp_localize_script('ce4wp_deactivate_survey', self::ADMIN_CE4WP_DATA_VAR, array(
207
  'url' => admin_url('admin-ajax.php'),
208
  'nonce' => $this->create_nonce()
213
  if (!$this->should_show_deactivation_modal()) {
214
  return;
215
  }
216
+ wp_enqueue_style('ce4wp_deactivate_survey', CE4WP_PLUGIN_URL.'assets/css/deactivation.css', [],CE4WP_PLUGIN_VERSION,'');
217
  }
218
 
219
  function show_deactivation_modal() {
267
 
268
  $install_date = date_create($install_date);
269
  $date_now = date_create(date('Y-m-d G:i:s'));
270
+ // @phpstan-ignore-next-line
271
  $date_diff = date_diff($install_date, $date_now);
272
 
273
  if ($date_diff->format("%d") < 7 ) {
374
  */
375
  public function add_assets()
376
  {
377
+ wp_register_style('ce4wp_admin', CE4WP_PLUGIN_URL . 'assets/css/admin.css', [], CE4WP_PLUGIN_VERSION);
378
  wp_enqueue_style('ce4wp_admin');
379
  wp_enqueue_style('ce4wp-font-poppins', 'https://fonts.googleapis.com/css?family=Poppins:400,500');
380
  wp_enqueue_script('wp-api');
383
 
384
  if ($this->is_cm_screen_and_show_footer())
385
  {
386
+ wp_enqueue_script('ce4wp_admin_footer_rating', CE4WP_PLUGIN_URL . 'assets/js/footer_rating.js', ['wp-api'], CE4WP_PLUGIN_VERSION, true);
387
  }
388
  }
389
 
398
  ? array( $this, 'show_dashboard' )
399
  : array( $this, 'show_setup' );
400
 
401
+ // Create the root menu item.
402
+ $icon = (string) file_get_contents(CE4WP_PLUGIN_DIR . 'assets/images/icon.svg');
403
  // Filter to change the menu position if there is any conflict.
404
  $position = apply_filters( 'ce4wp_menu_position', '35.5' );
405
+ // @phpstan-ignore-next-line
406
  add_menu_page('Creative Mail', esc_html__('Creative Mail', self::DOMAIN_CE4WP), 'manage_options', 'creativemail', $main_action, 'data:image/svg+xml;base64,' . base64_encode($icon), $position);
407
 
408
  $sub_actions = array();
409
 
410
  if ($hasConnectedAccount) {
411
+ $sub_actions[] = array(
412
+ 'title' => esc_html__('Campaigns', self::DOMAIN_CE4WP),
413
+ 'text' => '<span id="ce4wp-menu-campaigns" data-link_reference="5166faec-1dbb-4434-bad0-bb2f75898f92">' . __('Campaigns', self::DOMAIN_CE4WP) . '</span>',
414
+ 'slug' => 'creativemail_campaigns',
415
  'callback' => null
416
+ );
417
+ $sub_actions[] = array(
418
+ 'title' => esc_html__('Contacts', self::DOMAIN_CE4WP),
419
+ 'text' => '<span id="ce4wp-menu-contacts" data-link_reference="836b20fc-9ff1-41b2-912b-a8646caf05a4">' . __('Contacts', self::DOMAIN_CE4WP) . '</span>',
420
+ 'slug' => 'creativemail_contacts',
421
  'callback' => null
422
+ );
423
+ $sub_actions[] = array(
424
+ 'title' => esc_html__('WooCommerce', self::DOMAIN_CE4WP),
425
+ 'text' => '<span id="ce4wp-menu-woocommerce" data-link_reference="1fabdbe2-95ed-4e1e-a2f3-ba0278f5096f">' . __('WooCommerce', self::DOMAIN_CE4WP) . '</span>',
426
+ 'slug' => 'creativemail_woocommerce',
427
  'callback' => null
428
+ );
429
+ $sub_actions[] = array(
430
+ 'title' => esc_html__('Automation', self::DOMAIN_CE4WP),
431
+ 'text' => '<span id="ce4wp-menu-automation" data-link_reference="d5baea05-c603-4cca-852e-f8e82414f6b0">' . __('Automation', self::DOMAIN_CE4WP) . '</span>',
432
+ 'slug' => 'creativemail_automation',
433
  'callback' => null
434
+ );
435
  }
436
+ $sub_actions[] = array(
437
+ 'title' => esc_html__('Settings', self::DOMAIN_CE4WP),
438
+ 'text' => __('Settings', self::DOMAIN_CE4WP),
439
+ 'slug' => 'creativemail_settings',
440
+ 'callback' => array($this, 'show_settings_page')
441
+ );
 
442
 
443
  foreach ($sub_actions as $sub_action) {
444
+ add_submenu_page(
445
+ 'creativemail',
446
+ 'Creative Mail - ' . $sub_action['title'],
447
+ $sub_action['text'],
448
+ 'manage_options',
449
+ $sub_action['slug'],
450
+ // @phpstan-ignore-next-line
451
+ $sub_action['callback']
452
+ );
453
  }
454
 
455
+ // Add woocommerce sub-menu page.
456
  add_submenu_page(
457
  self::ADMIN_WOOCOMMERCE,
458
  esc_html__('Creative Mail', self::DOMAIN_CE4WP),
459
  esc_html__('Creative Mail', self::DOMAIN_CE4WP),
460
  'manage_woocommerce',
461
  'ce4wp-woo-settings',
462
+ // @phpstan-ignore-next-line
463
  $main_action
464
  );
465
  }
544
  }
545
 
546
  private function enqueue_dashboard_js() {
547
+ wp_enqueue_script('ce4wp_dashboard', CE4WP_PLUGIN_URL.'assets/js/dashboard.js', ['jquery'],CE4WP_PLUGIN_VERSION);
548
  wp_localize_script('ce4wp_dashboard', self::ADMIN_CE4WP_DATA_VAR, array(
549
  'url' => admin_url('admin-ajax.php'),
550
  'nonce' => $this->create_nonce()
572
  $instance_api_key = OptionsHelper::get_instance_api_key();
573
  $connected_account_id = OptionsHelper::get_connected_account_id();
574
 
575
+ if (isset($instance_id) && !empty($instance_api_key) && isset($connected_account_id)) {
576
  try {
577
  return SsoHelper::generate_sso_link($instance_id, $instance_api_key, $connected_account_id, $linkReference, $linkParameters);
578
  }
src/Managers/ApiManager.php CHANGED
@@ -13,6 +13,9 @@ use CreativeMail\Modules\Blog\Models\BlogInformation;
13
  use CreativeMail\Modules\Blog\Models\BlogPost;
14
  use CreativeMail\Modules\WooCommerce\Models\WCInformationModel;
15
  use CreativeMail\Modules\WooCommerce\Models\WCProductModel;
 
 
 
16
  use WP_Error;
17
  use WP_REST_Response;
18
 
@@ -82,7 +85,7 @@ class ApiManager
82
 
83
  public function validate_callback()
84
  {
85
- //never cache our rest endpoints
86
  nocache_headers();
87
 
88
  if (! array_key_exists("HTTP_X_API_KEY", $_SERVER) ) {
@@ -90,13 +93,13 @@ class ApiManager
90
  }
91
 
92
  $apiKey = $_SERVER["HTTP_X_API_KEY"];
93
- // Verify handshake expiration
94
  $expiration = OptionsHelper::get_handshake_expiration();
95
  if ($expiration === null || $expiration < time() ) {
96
  return new WP_Error('rest_unauthorized', 'Unauthorized', array( self::HTTP_STATUS => 401 ));
97
  }
98
 
99
- // Verify handshake
100
  if ($apiKey === OptionsHelper::get_handshake_token() ) {
101
  return true;
102
  }
@@ -106,7 +109,7 @@ class ApiManager
106
 
107
  public function add_rest_endpoints()
108
  {
109
- // Add the endpoint to handle the callback
110
  $routes = array (
111
  array (
112
  self::ROUTE_PATH => '/callback',
@@ -149,12 +152,7 @@ class ApiManager
149
  self::ROUTE_PATH => '/managed_email_notifications',
150
  self::ROUTE_METHODS => 'POST',
151
  self::ROUTE_CALLBACK => function ($request) {
152
- if(!CreativeMail::get_instance()->get_integration_manager()->get_permalinks_enabled()) {
153
- return $this->modify_response(new WP_REST_Response(array( 'message' => 'Please enable pretty permalinks in the WordPress settings.'), 400));
154
- }
155
-
156
- $result = CreativeMail::get_instance()->get_email_manager()->set_managed_email_notifications(json_decode($request->get_body()));
157
- return $this->modify_response(new WP_REST_Response($result, 200));
158
  }
159
  ),
160
  array (
@@ -190,47 +188,7 @@ class ApiManager
190
  self::ROUTE_PATH => '/wc_products',
191
  self::ROUTE_METHODS => 'GET',
192
  self::ROUTE_CALLBACK => function ($request) {
193
- $productData = array();
194
- $products = array();
195
- $active_plugins = apply_filters('active_plugins', get_option('active_plugins'));
196
- if (in_array('woocommerce/woocommerce.php', $active_plugins)) {
197
- $page = 1;
198
- $limit = 25;
199
-
200
- $pageFromRequest = $request->get_param('page');
201
- if(!empty($pageFromRequest) && $pageFromRequest != '{page}') {
202
- $page = $pageFromRequest;
203
- }
204
-
205
- $pageLimitFromRequest = $request->get_param('limit');
206
- if(!empty($pageLimitFromRequest) && $pageLimitFromRequest != '{limit}') {
207
- $limit = $pageLimitFromRequest;
208
- }
209
-
210
- $types = array_merge( array_keys( wc_get_product_types() ) );
211
-
212
- if (in_array('woocommerce-bookings/woocommerce-bookings.php', $active_plugins)) {
213
- array_push($types, 'booking');
214
- }
215
-
216
- // Get 25 most recent products
217
- $products = wc_get_products(
218
- array(
219
- 'limit' => $limit,
220
- 'paginate' => true,
221
- 'paged' => $page,
222
- 'type' => $types
223
- )
224
- );
225
-
226
- foreach ($products->products as $product) {
227
- array_push($productData, new WCProductModel($product->get_data()));
228
- }
229
- }
230
- $response = new WP_REST_Response($productData, 200);
231
- $response->header( 'X-WP-Total', $products->total );
232
- $response->header( 'X-WP-TotalPages', $products->max_num_pages );
233
- return $this->modify_response($response);
234
  }
235
  ),
236
  array (
@@ -244,62 +202,21 @@ class ApiManager
244
  self::ROUTE_PATH => '/wp_posts',
245
  self::ROUTE_METHODS => 'GET',
246
  self::ROUTE_CALLBACK => function ($request) {
247
-
248
- $page = 1;
249
- if (property_exists($request,'page')) {
250
- $page = (int)$request['page'];
251
- }
252
-
253
- $posts = get_posts(
254
- array(
255
- 'posts_per_page' => 10,
256
- 'paged' => $page,
257
- 'post_type' => 'post'
258
- )
259
- );
260
-
261
- $postData = array();
262
- foreach ($posts as $post)
263
- {
264
- array_push($postData, new BlogPost($post));
265
- }
266
-
267
- return $this->modify_response(new WP_REST_Response($postData, 200));
268
  }
269
  ),
270
  array (
271
  self::ROUTE_PATH => '/images',
272
  self::ROUTE_METHODS => 'GET',
273
  self::ROUTE_CALLBACK => function () {
274
- $attachmentData = array();
275
- $attachments = get_posts(
276
- array(
277
- 'post_type' => 'attachment',
278
- 'post_mime_type' => 'image',
279
- 'post_status' => 'inherit',
280
- 'posts_per_page' => -1
281
- )
282
- );
283
-
284
- foreach ($attachments as $attachment)
285
- {
286
- array_push($attachmentData, new BlogAttachment($attachment));
287
- }
288
-
289
- return $this->modify_response(new WP_REST_Response($attachmentData, 200));
290
  }
291
  ),
292
  array (
293
  self::ROUTE_PATH => '/hide_banner',
294
  self::ROUTE_METHODS => 'POST',
295
  self::ROUTE_CALLBACK => function ($request) {
296
- $banner = $request->get_param('banner');
297
- if (empty($banner)) {
298
- return $this->modify_response(new WP_REST_Response('Missing banner param', 400));
299
- }
300
-
301
- OptionsHelper::set_hide_banner($banner, true);
302
- return $this->modify_response(new WP_REST_Response(null, 204));
303
  },
304
  self::ROUTE_PERMISSION_CALLBACK => function () {
305
  return true;
@@ -308,77 +225,16 @@ class ApiManager
308
  array (
309
  self::ROUTE_PATH => '/get_pages_with_ce_forms',
310
  self::ROUTE_METHODS => 'GET',
311
- self::ROUTE_CALLBACK => function ($request) {
312
- if (version_compare($GLOBALS['wp_version'], '5.5', '<')) {
313
- // This is to prevent CE from making the Gutenberg recommendation when Gutenberg isn't supported
314
- return $this->modify_response(
315
- new WP_REST_Response(
316
- array(array( 'page_id' => 1, 'post_title' => '', 'post_status' => 'published' )),
317
- 200
318
- )
319
- );
320
- }
321
-
322
- $blocks = $this->find_pages_by_content_tag("wp:ce4wp/subscribe");
323
- return $this->modify_response(new WP_REST_Response($blocks, 200));
324
- }
325
  ),
326
  array (
327
  self::ROUTE_PATH => '/check_if_previously_purchased',
328
  self::ROUTE_METHODS => 'GET',
329
  self::ROUTE_CALLBACK => function ($request) {
330
-
331
- $active_plugins = apply_filters('active_plugins', get_option('active_plugins'));
332
- if (in_array('woocommerce/woocommerce.php', $active_plugins)) {
333
-
334
- $product_ID = $request->get_param('product');
335
- $email = $request->get_param('email');
336
- $daysPassedFloat = 86400 * $request->get_param('daysPassed');
337
- $daysPassed = round($daysPassedFloat);
338
-
339
- $currentDay = new \DateTime();
340
- $currentDate = $currentDay->format('Y-m-d H:i:s');
341
- $currentTime = strtotime($currentDate);
342
-
343
- $date = new \DateTime();
344
- $date->sub(new \DateInterval("PT{$daysPassed}S"));
345
- $initial_date = $date->format('Y-m-d H:i:s');
346
- $initialTime = strtotime($initial_date);
347
- $exists = false;
348
-
349
- $order = wc_get_orders( array(
350
- 'billing_email' => $email,
351
- 'date_created' => "$initialTime...$currentTime",
352
- 'status' => array('wc-completed')
353
- ));
354
-
355
- if(!empty($product_ID)) {
356
-
357
- foreach ($order as $itemsKey => $item) {
358
- $orderData = $item->get_data();
359
-
360
- foreach($orderData['line_items'] as $lineItem) {
361
- $product = $lineItem->get_product()->get_data();
362
-
363
- foreach($product_ID as $p_ID) {
364
- if($p_ID == $product['id']) {
365
- $exists = true;
366
- }
367
- }
368
- }
369
- if($exists) {
370
- break;
371
- }
372
- }
373
- }
374
- else {
375
- if(!empty($order)) {
376
- $exists = true;
377
- }
378
- }
379
- return $this->modify_response(new WP_REST_Response($exists, 200));
380
- }
381
- }
382
  )
383
  );
384
 
@@ -387,17 +243,19 @@ class ApiManager
387
  }
388
  }
389
 
390
- private function find_pages_by_content_tag($tag){
391
  $pagesWithTag = array();
392
- $pages = get_pages(); //defaults are type=page, status=published
393
  if (empty($pages)){
394
  return null;
395
  }
396
 
397
- foreach ($pages as $page){
398
- $post_content = $page->post_content;
399
- if (strpos($post_content, $tag) !== false){
400
- array_push($pagesWithTag, ['page_id' => $page->ID, 'post_title' => $page->post_title, 'post_status' => $page->post_status]);
 
 
401
  }
402
  }
403
  return $pagesWithTag;
@@ -467,7 +325,7 @@ class ApiManager
467
  {
468
  $wcKey = CreativeMail::get_instance()->get_api_manager()->get_or_generate_key();
469
  $key = sha1(OptionsHelper::get_instance_api_key() . OptionsHelper::get_instance_uuid());
470
- $salt = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
471
  $salted = '';
472
  $dx = '';
473
  while ( strlen($salted) < 48 ) {
@@ -476,8 +334,8 @@ class ApiManager
476
  }
477
  $key = substr($salted, 0, 32);
478
  $iv = substr($salted, 32, 16);
479
- $cs = openssl_encrypt($wcKey->consumer_secret, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
480
- $ck = openssl_encrypt($wcKey->consumer_key, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
481
 
482
  $result = new HashSchema();
483
  $result->salt = bin2hex($salt);
@@ -702,9 +560,9 @@ class ApiManager
702
  /**
703
  * Gets or generate the configured WC REST API key.
704
  *
705
- * @since 1.1.0
706
- *
707
- * @return object|null
708
  */
709
  public function get_or_generate_key()
710
  {
@@ -726,13 +584,12 @@ class ApiManager
726
  */
727
  public function get_key_id()
728
  {
729
-
730
- return OptionsHelper::get_wc_api_key_id();
731
  }
732
 
733
  public function get_consumer_key()
734
  {
735
-
736
  return OptionsHelper::get_wc_consumer_key();
737
  }
738
 
@@ -752,4 +609,193 @@ class ApiManager
752
  {
753
  OptionsHelper::set_wc_consumer_key($key);
754
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
  }
13
  use CreativeMail\Modules\Blog\Models\BlogPost;
14
  use CreativeMail\Modules\WooCommerce\Models\WCInformationModel;
15
  use CreativeMail\Modules\WooCommerce\Models\WCProductModel;
16
+ use DateInterval;
17
+ use DateTime;
18
+ use Exception;
19
  use WP_Error;
20
  use WP_REST_Response;
21
 
85
 
86
  public function validate_callback()
87
  {
88
+ //never cache our rest endpoints.
89
  nocache_headers();
90
 
91
  if (! array_key_exists("HTTP_X_API_KEY", $_SERVER) ) {
93
  }
94
 
95
  $apiKey = $_SERVER["HTTP_X_API_KEY"];
96
+ // Verify handshake expiration.
97
  $expiration = OptionsHelper::get_handshake_expiration();
98
  if ($expiration === null || $expiration < time() ) {
99
  return new WP_Error('rest_unauthorized', 'Unauthorized', array( self::HTTP_STATUS => 401 ));
100
  }
101
 
102
+ // Verify handshake.
103
  if ($apiKey === OptionsHelper::get_handshake_token() ) {
104
  return true;
105
  }
109
 
110
  public function add_rest_endpoints()
111
  {
112
+ // Add the endpoint to handle the callback.
113
  $routes = array (
114
  array (
115
  self::ROUTE_PATH => '/callback',
152
  self::ROUTE_PATH => '/managed_email_notifications',
153
  self::ROUTE_METHODS => 'POST',
154
  self::ROUTE_CALLBACK => function ($request) {
155
+ return $this->get_managed_email_notifications($request);
 
 
 
 
 
156
  }
157
  ),
158
  array (
188
  self::ROUTE_PATH => '/wc_products',
189
  self::ROUTE_METHODS => 'GET',
190
  self::ROUTE_CALLBACK => function ($request) {
191
+ return $this->get_wc_products($request);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  }
193
  ),
194
  array (
202
  self::ROUTE_PATH => '/wp_posts',
203
  self::ROUTE_METHODS => 'GET',
204
  self::ROUTE_CALLBACK => function ($request) {
205
+ return $this->get_wp_posts($request);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
207
  ),
208
  array (
209
  self::ROUTE_PATH => '/images',
210
  self::ROUTE_METHODS => 'GET',
211
  self::ROUTE_CALLBACK => function () {
212
+ return $this->get_images();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  }
214
  ),
215
  array (
216
  self::ROUTE_PATH => '/hide_banner',
217
  self::ROUTE_METHODS => 'POST',
218
  self::ROUTE_CALLBACK => function ($request) {
219
+ return $this->hide_banner($request);
 
 
 
 
 
 
220
  },
221
  self::ROUTE_PERMISSION_CALLBACK => function () {
222
  return true;
225
  array (
226
  self::ROUTE_PATH => '/get_pages_with_ce_forms',
227
  self::ROUTE_METHODS => 'GET',
228
+ self::ROUTE_CALLBACK => function () {
229
+ return $this->get_pages_with_ce_forms();
230
+ },
 
 
 
 
 
 
 
 
 
 
 
231
  ),
232
  array (
233
  self::ROUTE_PATH => '/check_if_previously_purchased',
234
  self::ROUTE_METHODS => 'GET',
235
  self::ROUTE_CALLBACK => function ($request) {
236
+ return $this->check_if_previously_purchased($request);
237
+ },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  )
239
  );
240
 
243
  }
244
  }
245
 
246
+ private function find_pages_by_content_tag( $tag ){
247
  $pagesWithTag = array();
248
+ $pages = get_pages(); // Defaults are type=page, status=published.
249
  if (empty($pages)){
250
  return null;
251
  }
252
 
253
+ foreach ($pages as $page) {
254
+ if (! is_int ($page) ) {
255
+ $post_content = $page->post_content;
256
+ if (strpos($post_content, $tag) !== false){
257
+ $pagesWithTag[] = ['page_id' => $page->ID, 'post_title' => $page->post_title, 'post_status' => $page->post_status];
258
+ }
259
  }
260
  }
261
  return $pagesWithTag;
325
  {
326
  $wcKey = CreativeMail::get_instance()->get_api_manager()->get_or_generate_key();
327
  $key = sha1(OptionsHelper::get_instance_api_key() . OptionsHelper::get_instance_uuid());
328
+ $salt = (string) openssl_random_pseudo_bytes((int) openssl_cipher_iv_length('aes-256-cbc'));
329
  $salted = '';
330
  $dx = '';
331
  while ( strlen($salted) < 48 ) {
334
  }
335
  $key = substr($salted, 0, 32);
336
  $iv = substr($salted, 32, 16);
337
+ $cs = (string) openssl_encrypt($wcKey->consumer_secret, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
338
+ $ck = (string) openssl_encrypt($wcKey->consumer_key, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
339
 
340
  $result = new HashSchema();
341
  $result->salt = bin2hex($salt);
560
  /**
561
  * Gets or generate the configured WC REST API key.
562
  *
563
+ * @return object|bool
564
+ * @throws Exception
565
+ * @since 1.1.0
566
  */
567
  public function get_or_generate_key()
568
  {
584
  */
585
  public function get_key_id()
586
  {
587
+ $wc_api_key = OptionsHelper::get_wc_api_key_id();
588
+ return is_int($wc_api_key) ? $wc_api_key : 0;
589
  }
590
 
591
  public function get_consumer_key()
592
  {
 
593
  return OptionsHelper::get_wc_consumer_key();
594
  }
595
 
609
  {
610
  OptionsHelper::set_wc_consumer_key($key);
611
  }
612
+
613
+ private function get_managed_email_notifications($request)
614
+ {
615
+ if(!CreativeMail::get_instance()->get_integration_manager()->get_permalinks_enabled()) {
616
+ return $this->modify_response(new WP_REST_Response(array( 'message' => 'Please enable pretty permalinks in the WordPress settings.'), 400));
617
+ }
618
+
619
+ $result = CreativeMail::get_instance()->get_email_manager()->set_managed_email_notifications(json_decode($request->get_body()));
620
+ return $this->modify_response(new WP_REST_Response($result, 200));
621
+ }
622
+
623
+ private function get_wc_products($request)
624
+ {
625
+ $productData = array();
626
+ $products = array();
627
+ $active_plugins = apply_filters('active_plugins', get_option('active_plugins'));
628
+
629
+ if (in_array('woocommerce/woocommerce.php', $active_plugins)) {
630
+ $page = 1;
631
+ $limit = 25;
632
+ $pageFromRequest = $request->get_param('page');
633
+ $pageLimitFromRequest = $request->get_param('limit');
634
+
635
+ if(!empty($pageFromRequest) && $pageFromRequest != '{page}') {
636
+ $page = $pageFromRequest;
637
+ }
638
+ if(!empty($pageLimitFromRequest) && $pageLimitFromRequest != '{limit}') {
639
+ $limit = $pageLimitFromRequest;
640
+ }
641
+
642
+ $types = array_merge( array_keys( wc_get_product_types() ) );
643
+
644
+ if (in_array('woocommerce-bookings/woocommerce-bookings.php', $active_plugins)) {
645
+ array_push($types, 'booking');
646
+ }
647
+
648
+ // Get 25 most recent products.
649
+ $products = wc_get_products(
650
+ array(
651
+ 'limit' => $limit,
652
+ 'paginate' => true,
653
+ 'paged' => $page,
654
+ 'type' => $types
655
+ )
656
+ );
657
+
658
+ if (!is_array ($products)) {
659
+ foreach ($products->products as $product) {
660
+ array_push($productData, new WCProductModel($product->get_data()));
661
+ }
662
+ }
663
+ }
664
+ $response = new WP_REST_Response($productData, 200);
665
+ if (!is_array ($products)) {
666
+ $response->header('X-WP-Total', $products->total);
667
+ $response->header('X-WP-TotalPages', $products->max_num_pages);
668
+ }
669
+ return $this->modify_response($response);
670
+ }
671
+
672
+ private function get_wp_posts($request)
673
+ {
674
+ $page = 1;
675
+ $postData = array();
676
+
677
+ if (property_exists($request,'page')) {
678
+ $page = (int)$request['page'];
679
+ }
680
+
681
+ $posts = get_posts(
682
+ array(
683
+ 'posts_per_page' => 10,
684
+ 'paged' => $page,
685
+ 'post_type' => 'post'
686
+ )
687
+ );
688
+
689
+ foreach ($posts as $post) {
690
+ array_push($postData, new BlogPost($post));
691
+ }
692
+
693
+ return $this->modify_response(new WP_REST_Response($postData, 200));
694
+ }
695
+
696
+ private function get_images()
697
+ {
698
+ $attachmentData = array();
699
+ $attachments = get_posts(
700
+ array(
701
+ 'post_type' => 'attachment',
702
+ 'post_mime_type' => 'image',
703
+ 'post_status' => 'inherit',
704
+ 'posts_per_page' => -1
705
+ )
706
+ );
707
+
708
+ foreach ($attachments as $attachment) {
709
+ array_push($attachmentData, new BlogAttachment($attachment));
710
+ }
711
+
712
+ return $this->modify_response(new WP_REST_Response($attachmentData, 200));
713
+ }
714
+
715
+ private function hide_banner($request)
716
+ {
717
+ $banner = $request->get_param('banner');
718
+ if (empty($banner)) {
719
+ return $this->modify_response(new WP_REST_Response('Missing banner param', 400));
720
+ }
721
+
722
+ OptionsHelper::set_hide_banner($banner, true);
723
+ return $this->modify_response(new WP_REST_Response(null, 204));
724
+ }
725
+
726
+ private function get_pages_with_ce_forms()
727
+ {
728
+ if (version_compare($GLOBALS['wp_version'], '5.5', '<')) {
729
+ // This is to prevent CE from making the Gutenberg recommendation when Gutenberg isn't supported.
730
+ return $this->modify_response(
731
+ new WP_REST_Response(
732
+ array(array( 'page_id' => 1, 'post_title' => '', 'post_status' => 'published' )),
733
+ 200
734
+ )
735
+ );
736
+ }
737
+
738
+ $blocks = $this->find_pages_by_content_tag("wp:ce4wp/subscribe");
739
+ return $this->modify_response(new WP_REST_Response($blocks, 200));
740
+ }
741
+
742
+ private function check_if_previously_purchased($request)
743
+ {
744
+ $active_plugins = apply_filters('active_plugins', get_option('active_plugins'));
745
+ $exists = false;
746
+
747
+ if (in_array('woocommerce/woocommerce.php', $active_plugins)) {
748
+ $product_ID = $request->get_param('product');
749
+ $email = $request->get_param('email');
750
+ $daysPassedFloat = 86400 * $request->get_param('daysPassed');
751
+ $daysPassed = round($daysPassedFloat);
752
+
753
+ $currentDay = new DateTime();
754
+ $currentDate = $currentDay->format('Y-m-d H:i:s');
755
+ $currentTime = strtotime($currentDate);
756
+
757
+ $date = new DateTime();
758
+ $date->sub(new DateInterval("PT{$daysPassed}S"));
759
+ $initial_date = $date->format('Y-m-d H:i:s');
760
+ $initialTime = strtotime($initial_date);
761
+
762
+ $order = wc_get_orders( array(
763
+ 'billing_email' => $email,
764
+ 'date_created' => "$initialTime...$currentTime",
765
+ 'status' => array('wc-completed')
766
+ ));
767
+
768
+ if (!empty($product_ID)) {
769
+ if (is_array($order)){
770
+ $exists = $this->check_if_product_exists_by_product_id($order, $product_ID);
771
+ }
772
+ } else {
773
+ if(!empty($order)) {
774
+ $exists = true;
775
+ }
776
+ }
777
+ }
778
+ return $this->modify_response(new WP_REST_Response($exists, 200));
779
+ }
780
+
781
+ private function check_if_product_exists_by_product_id(array $order, $product_ID)
782
+ {
783
+ $exists = false;
784
+
785
+ foreach ($order as $itemsKey => $item) {
786
+ $orderData = $item->get_data();
787
+ foreach($orderData['line_items'] as $lineItem) {
788
+ $product = $lineItem->get_product()->get_data();
789
+ foreach($product_ID as $p_ID) {
790
+ if($p_ID == $product['id']) {
791
+ $exists = true;
792
+ }
793
+ }
794
+ }
795
+ if($exists) {
796
+ break;
797
+ }
798
+ }
799
+ return $exists;
800
+ }
801
  }
src/Managers/CheckoutManager.php CHANGED
@@ -186,10 +186,13 @@ class CheckoutManager
186
  }
187
  try
188
  {
189
- $data = $this->get_checkout_uuid_by_email($order->get_billing_email());
 
 
 
190
  foreach ($data as $checkout_data)
191
  {
192
- $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ) . '/v1.0/checkout/'. $checkout_data->checkout_uuid;
193
  $this->ce4wp_remote_delete($endpoint);
194
  CreativeMail::get_instance()->get_database_manager()->remove_checkout_data($checkout_data->checkout_uuid);
195
  }
@@ -209,30 +212,33 @@ class CheckoutManager
209
  * @since 1.3.0
210
  */
211
  private function update_checkout( $order_id, $endpoint ) {
 
212
  $order = wc_get_order( $order_id );
 
213
  if ( empty( $order ) ) {
214
  return;
215
  }
216
 
217
- // check if order had checkout uuid
218
- $uuid = $order->get_meta( self::META_CHECKOUT_UUID, true);
219
- // check if order is created with checkout meta
220
- if ( empty( $uuid ) ) {
221
- return;
222
- }
 
223
 
224
- // Try to find recovery date from order metadata
225
- $recovery_date = $order->get_meta( self::META_CHECKOUT_RECOVERED, true );
226
- // Remote post to CE4WP marking checkout as completed/created
227
- $requestItem = new Checkout();
228
- $requestItem->uuid = $uuid;
229
- $requestItem->order_id = $order->get_id();
230
- $requestItem->order_total = $order->get_total();
231
- $requestItem->order_currency = $order->get_currency();
232
- $requestItem->recovery_date = ( empty( $recovery_date ) || $recovery_date === self::DATETIME_ZERO ) ? null : $recovery_date;
233
 
234
  $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ) . $endpoint;
235
- // call remote endpoint to update
236
  $this->ce4wp_remote_post( $requestItem, $endpoint );
237
  }
238
 
@@ -257,17 +263,19 @@ class CheckoutManager
257
  * @since 1.3.0
258
  */
259
  public function maybe_capture_guest_checkout() {
 
260
  $data = filter_input_array( INPUT_POST, [
261
  self::NONCE => FILTER_SANITIZE_STRING,
262
  self::EMAIL => FILTER_SANITIZE_EMAIL
263
  ] );
264
 
265
- if ( empty( $data[self::NONCE] ) || ! wp_verify_nonce( $data[self::NONCE], 'woocommerce-process_checkout' ) ) {
266
- wp_send_json_error( esc_html__( 'Invalid nonce.', self::DOMAIN ) );
 
 
 
267
  }
268
 
269
- $email = filter_var( $data[self::EMAIL], FILTER_VALIDATE_EMAIL );
270
-
271
  if ( ! $email ) {
272
  wp_send_json_error( esc_html__( 'Invalid email.', self::DOMAIN ) );
273
  }
@@ -289,10 +297,13 @@ class CheckoutManager
289
  self::NONCE => FILTER_SANITIZE_STRING
290
  ]);
291
 
292
- if (empty($data[self::NONCE]) || !wp_verify_nonce($data[self::NONCE], 'woocommerce-process_checkout')) {
293
- wp_send_json_error(esc_html__('Invalid nonce.', self::DOMAIN));
 
 
294
  }
295
- // save no consent on session
 
296
  WC()->session->set( self::BILLING_EMAIL_NO_CONSENT, true);
297
 
298
  $checkout_id = WC()->session->get( self::CHECKOUT_UUID );
@@ -300,7 +311,7 @@ class CheckoutManager
300
  wp_send_json_success();
301
  }
302
 
303
- $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ) . '/v1.0/checkout/'. $checkout_id;
304
  $this->ce4wp_remote_delete( $endpoint );
305
  CreativeMail::get_instance()->get_database_manager()->change_checkout_consent( $checkout_id, false );
306
 
@@ -394,9 +405,8 @@ class CheckoutManager
394
  /**
395
  * Save current checkout data to db.
396
  *
397
- * @param string $billing_email Manually set customer billing email if provided.
398
- * @param boolean $is_checkout Manually mark current page as checkout if necessary (e.g., coming from ajax callback).
399
- * @param boolean|null $consent_checkout Manually mark consent value.
400
  *
401
  * @since 1.3.0
402
  *
@@ -410,7 +420,7 @@ class CheckoutManager
410
  if (empty($billing_email)) {
411
  $billing_email = $session_billing_email;
412
  if (empty($billing_email)) {
413
- $billing_email = WC()->checkout->get_value( self::BILLING_EMAIL );
414
  if (empty($billing_email)) {
415
  $billing_email = WC()->session->get( self::BILLING_EMAIL );
416
  }
@@ -423,33 +433,28 @@ class CheckoutManager
423
  return;
424
  }
425
 
426
- $has_no_consent = WC()->session->get( self::BILLING_EMAIL_NO_CONSENT );
427
- if( $has_no_consent === true )
428
- {
429
  return;
430
  }
431
 
432
  // Check for existing checkout session.
433
  if ( ! $uuid ) {
434
-
435
  // Only create session if cart is not empty.
436
  // This is to avoid re-creating checkout UUID during checkout process.
437
  if ( $is_checkout && empty( WC()->cart->get_cart() ) ) {
438
  return;
439
  }
440
-
441
  // Retrieve existing checkout UUID for registered users only.
442
  if ( is_user_logged_in() ) {
443
  $existing_uuid = $this->get_checkout_uuid_by_user();
444
  }
445
-
446
  // Only create session if currently on checkout page or if current user has an existing session saved.
447
  if ( ! $is_checkout && empty( $existing_uuid ) ) {
448
  return;
449
  }
450
 
451
  $uuid = isset( $existing_uuid ) && ! empty( $existing_uuid ) ? $existing_uuid : wp_generate_uuid4();
452
-
453
  WC()->session->set( 'checkout_uuid', $uuid );
454
  }
455
 
@@ -473,10 +478,10 @@ class CheckoutManager
473
  // Remote post to CE4WP create or update cart if email is provided.
474
  $requestItem = new CheckoutSave();
475
  $requestItem->data = wp_json_encode($this->get_cart_data_for_endpoint( $cart_products, $cart_coupons, $shipping_total, $shipping_taxes ) );
476
- $requestItem->uuid = $uuid;
477
  $requestItem->user_id = $user_id;
478
  $requestItem->billing_email = $billing_email;
479
- $requestItem->timestamp = strtotime( $current_time );
480
  $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ) . '/v1.0/checkout/upsert';
481
 
482
  $consent = CreativeMail::get_instance()->get_database_manager()->has_checkout_consent( $uuid );
@@ -491,6 +496,7 @@ class CheckoutManager
491
  * @since 1.3.0
492
  */
493
  private function get_cart_data_for_endpoint( $cart_products, $cart_coupons, $shipping_total=0.00, $shipping_taxes=array() ) {
 
494
  $data = new CartData();
495
  $data->products = array();
496
  $data->coupons = array();
@@ -502,7 +508,7 @@ class CheckoutManager
502
  $data->user = new User();
503
  try
504
  {
505
- // Get user first and last name of available
506
  $current_user = wp_get_current_user();
507
  if ( $current_user->exists() ) {
508
  $data->user->id = $current_user->ID;
@@ -513,8 +519,6 @@ class CheckoutManager
513
  $data->user->email = $current_user->user_email;
514
  }
515
 
516
- $dp = 2; // decimal point
517
-
518
  foreach ( $cart_products as $value )
519
  {
520
  $product = array_key_exists( 'data', $value ) ? $value['data'] : wc_get_product( $value[self::PRODUCT_ID] );
@@ -532,7 +536,8 @@ class CheckoutManager
532
  $product_data[ "regular_price" ] = $product->get_regular_price();
533
  $src = wc_placeholder_img_src();
534
  if ( $image_id = $product->get_image_id() ) {
535
- list( $src ) = wp_get_attachment_image_src( $image_id, 'full' );
 
536
  }
537
 
538
  $line_subtotal = empty( $value['line_subtotal'] ) ? 0: $value[ 'line_subtotal' ];
@@ -545,14 +550,14 @@ class CheckoutManager
545
  'product_id' => $product_id,
546
  'product_image' => $src,
547
  'product_data' => $product_data,
548
- 'sku' => is_object($product) ? $product->get_sku() : null,
549
  'product_url' => get_the_permalink( $product_id ),
550
  'variation_id' => $value[ self::VARIATION_ID ],
551
- 'subtotal' => wc_format_decimal( $line_subtotal, $dp ),
552
- 'subtotal_tax' => wc_format_decimal( $line_subtotal_tax, $dp ),
553
- 'total' => wc_format_decimal( $line_total, $dp ),
554
- 'total_tax' => wc_format_decimal( $line_tax, $dp ),
555
- 'price' => wc_format_decimal( $line_subtotal, $dp ),
556
  'quantity' => $value[ self::QUANTITY ]
557
  );
558
  }
@@ -563,7 +568,6 @@ class CheckoutManager
563
  if ( $coupon_id )
564
  {
565
  $coupon = new WC_Coupon( $coupon_id );
566
-
567
  $data->coupons[] = array(
568
  'code' => $coupon->get_code(),
569
  'amount' => $coupon->get_amount(),
@@ -600,7 +604,7 @@ class CheckoutManager
600
  $order->update_meta_data( self::META_CHECKOUT_UUID, $checkout_id );
601
 
602
  // get the recovery date if recovered
603
- $recovery_date = $this->get_checkout_recovery_date( $checkout_id );
604
  if ( !empty( $recovery_date ) && $recovery_date !== self::DATETIME_ZERO )
605
  {
606
  $order->update_meta_data( self::META_CHECKOUT_RECOVERED, $recovery_date );
@@ -729,7 +733,7 @@ class CheckoutManager
729
  private function ce4wp_remote_post( $requestItem, $endpoint ) {
730
  try
731
  {
732
- // check if abandoned cart email is managed by creative mail
733
  $enabled = CreativeMail::get_instance()->get_email_manager()->is_email_managed( 'cart_abandoned_ce4wp' );
734
  if( $enabled ) {
735
  wp_remote_post(
@@ -780,15 +784,17 @@ class CheckoutManager
780
 
781
  private function get_opt_in( $products_detail ) {
782
  $checkbox_value = $this->get_opt_in_checkbox_value( $products_detail );
783
- if ( $checkbox_value == true )
784
- return true;
 
785
  return null;
786
  }
787
 
788
  private function get_opt_out( $products_detail ) {
789
  $checkbox_value = $this->get_opt_in_checkbox_value( $products_detail );
790
- if ( $checkbox_value == false )
791
  return true;
 
792
  return null;
793
  }
794
 
@@ -801,152 +807,165 @@ class CheckoutManager
801
  if ( empty( $order ) ) {
802
  return;
803
  }
804
-
805
- $products_detail = get_post_meta($order_id);
806
-
807
  $endpoint = '/v1.0/wc/order_completed';
808
  $decimal_point = 2;
 
 
809
 
810
- // General Info
811
  $requestItem = new RequestItem();
812
  $order_model = new Order();
813
  $order_billing = new OrderBilling();
814
 
815
- $requestItem->order_id = $order->get_id();
816
- $requestItem->order_number = $order->get_order_number();
817
- $requestItem->date_created = $order->get_date_created() ? $order->get_date_created()->getTimestamp() : 0;
818
- $requestItem->date_modified = $order->get_date_modified() ? $order->get_date_modified()->getTimestamp() : 0;
819
- $requestItem->date_completed = $order->get_date_completed() ? $order->get_date_completed()->getTimestamp() : 0;
820
- $requestItem->status = $order->get_status();
821
- $requestItem->order_url = $order->get_checkout_order_received_url();
822
- $requestItem->note = $order->get_customer_note();
823
- $requestItem->customer_ip = $order->get_customer_ip_address();
824
- $requestItem->customer_user_agent = $order->get_customer_user_agent();
825
- $requestItem->customer_id = $order->get_user_id();
826
- // Order Billing
827
- $order_billing->email = $order->get_billing_email();
828
- $order_billing->opt_action_by = $this->get_opt_action_by( $products_detail );
829
- $order_billing->opt_in = $this->get_opt_in( $products_detail );
830
- $order_billing->opt_out = $this->get_opt_out( $products_detail );
831
-
832
- $order_billing->first_name = $order->get_billing_first_name();
833
- $order_billing->last_name = $order->get_billing_last_name();
834
- $order_billing->is_first_time_buyer = count( wc_get_orders( array( 'email' => $order->get_billing_email() ) ) ) <= 1;
835
- $order_billing->company = $order->get_billing_company();
836
- $order_billing->address_1 = $order->get_billing_address_1();
837
- $order_billing->address_2 = $order->get_billing_address_2();
838
- $order_billing->city = $order->get_billing_city();
839
- $order_billing->state = $order->get_billing_state();
840
- $order_billing->postcode = $order->get_billing_postcode();
841
- $order_billing->country = $order->get_billing_country();
842
- $order_billing->email = $order->get_billing_email();
843
- $order_billing->phone = $order->get_billing_phone();
844
- $order_billing->shipping = array(
845
- 'first_name' => $order->get_shipping_first_name(),
846
- 'last_name' => $order->get_shipping_last_name(),
847
- 'company' => $order->get_shipping_company(),
848
- 'address_1' => $order->get_shipping_address_1(),
849
- 'address_2' => $order->get_shipping_address_2(),
850
- 'city' => $order->get_shipping_city(),
851
- 'state' => $order->get_shipping_state(),
852
- 'postcode' => $order->get_shipping_postcode(),
853
- 'country' => $order->get_shipping_country(),
854
- 'shipping_methods' => $order->get_shipping_method()
855
- );
856
- $order_billing->payment_details = array(
857
- 'method_id' => $order->get_payment_method(),
858
- 'method_title' => $order->get_payment_method_title(),
859
- 'paid' => !is_null($order->get_date_paid()),
860
- );
861
- // Order Currency and Total Info
862
- $requestItem->total = wc_format_decimal( $order->get_total(), $decimal_point );
863
- $requestItem->subtotal = wc_format_decimal( $order->get_subtotal(), $decimal_point );
864
- $requestItem->total_tax = wc_format_decimal( $order->get_total_tax(), $decimal_point );
865
- $requestItem->shipping_total = wc_format_decimal( $order->get_shipping_total(), $decimal_point );
866
- $requestItem->cart_tax = wc_format_decimal( $order->get_cart_tax(), $decimal_point );
867
- $requestItem->shipping_tax = wc_format_decimal( $order->get_shipping_tax(), $decimal_point );
868
- $requestItem->discount_total = wc_format_decimal( $order->get_total_discount(), $decimal_point );
869
- $order_model->currency_symbol = get_woocommerce_currency_symbol();
870
- $order_model->currency = $order->get_currency();
871
- // Order Products Info
872
- $order_model->total_line_items_quantity = $order->get_item_count();
873
- // Line Items / Products array for the expected endpoint
874
- foreach ( $order->get_items() as $itemsKey => $item ) {
875
- $product = $item->get_product();
876
-
877
- if ( empty( $product ) ) {
878
- continue;
879
- }
880
 
881
- $item_meta = $item->get_formatted_meta_data();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
882
 
883
- foreach ( $item_meta as $key => $values ) {
884
- $item_meta[ $key ]->label = $values->display_key;
885
- unset( $item_meta[ $key ]->display_key );
886
- unset( $item_meta[ $key ]->display_value );
887
- }
888
 
889
- try {
890
- $product_data = array(
891
- 'images' => array(),
892
- 'downloads' => array()
893
- );
894
- $attachment_ids = $product->get_gallery_image_ids();
895
- foreach ( $attachment_ids as $attachment_id ) {
896
- $product_data[ 'images' ][] = wp_get_attachment_url( $attachment_id );
897
  }
898
 
899
- $product_data[ "on_sale" ] = $product->is_on_sale();
900
- $product_data[ "sale_price" ] = $product->get_sale_price();
901
- $product_data[ "regular_price" ] = $product->get_regular_price();
 
 
 
 
 
 
902
 
903
- if ( $product->is_downloadable() ) {
904
- $item_downloads = $item->get_item_downloads();
905
- foreach ( $item_downloads as $item_download )
906
- {
907
- $product_data[ "downloads" ][] = array(
908
- 'line_item_id' => $item->get_id(),
909
- 'product_id' => $item->get_product_id(),
910
- 'download_url' => $item_download[ "download_url" ],
911
- 'download_file' => $item_download[ "file" ],
912
- 'download_name' => $item_download[ "name" ],
913
- 'download_id' => $item_download[ "id" ],
914
- 'downloads_remaining' => $item_download[ "downloads_remaining" ],
915
- 'download_access_expires' => wc_format_datetime( $item_download[ "access_expires" ], 'U' ),
916
- 'download_limit' => $product->get_download_limit(),
917
- 'download_expiry' => $product->get_download_expiry(),
918
- );
 
 
 
 
 
 
 
919
  }
 
 
920
  }
921
- } catch ( Exception $ex ) {
922
- RaygunManager::get_instance()->exception_handler( $ex );
923
- }
924
 
925
- $src = wc_placeholder_img_src();
926
- if ( $image_id = $product->get_image_id() ) {
927
- list( $src ) = wp_get_attachment_image_src( $image_id, 'full' );
928
- }
 
929
 
930
- $order_model->line_items[] = array(
931
- 'product_id' => $item->get_product_id(),
932
- 'item_meta' => $item->get_formatted_meta_data(),
933
- 'subtotal' => wc_format_decimal($order->get_line_subtotal( $item, false, false), $decimal_point ),
934
- 'subtotal_tax' => wc_format_decimal( $item->get_subtotal_tax(), $decimal_point ),
935
- 'total' => wc_format_decimal( $order->get_line_total($item, false, false), $decimal_point ),
936
- 'total_tax' => wc_format_decimal( $item->get_total_tax(), $decimal_point ),
937
- 'price' => wc_format_decimal( $order->get_item_total($item, false, false), $decimal_point ),
938
- 'quantity' => $item->get_quantity(),
939
- 'tax_class' => $item->get_tax_class(),
940
- 'name' => $item->get_name(),
941
- 'product_image' => $src,
942
- 'product_data' => $product_data,
943
- 'sku' => is_object( $product ) ? $product->get_sku() : null,
944
- 'meta' => array_values( $item_meta ),
945
- 'product_url' => get_the_permalink( $item->get_product_id() ),
946
- 'variation_id' => $item->get_variation_id()
947
- );
 
 
 
 
 
 
948
  }
949
-
950
  $order_model->billing = $order_billing;
951
  $requestItem->order = $order_model;
952
 
186
  }
187
  try
188
  {
189
+ $data = array();
190
+ if (! is_bool($order) && is_a( $order, 'WC_Order' )) {
191
+ $data = $this->get_checkout_uuid_by_email($order->get_billing_email());
192
+ }
193
  foreach ($data as $checkout_data)
194
  {
195
+ $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ) . '/v1.0/checkout/' . $checkout_data->checkout_uuid;
196
  $this->ce4wp_remote_delete($endpoint);
197
  CreativeMail::get_instance()->get_database_manager()->remove_checkout_data($checkout_data->checkout_uuid);
198
  }
212
  * @since 1.3.0
213
  */
214
  private function update_checkout( $order_id, $endpoint ) {
215
+ $requestItem = new Checkout();
216
  $order = wc_get_order( $order_id );
217
+
218
  if ( empty( $order ) ) {
219
  return;
220
  }
221
 
222
+ if (! is_bool($order) ) {
223
+ // Check if order had checkout uuid.
224
+ $uuid = $order->get_meta(self::META_CHECKOUT_UUID, true);
225
+ // Check if order is created with checkout meta.
226
+ if (empty($uuid)) {
227
+ return;
228
+ }
229
 
230
+ // Try to find recovery date from order metadata.
231
+ $recovery_date = $order->get_meta(self::META_CHECKOUT_RECOVERED, true);
232
+ // Remote post to CE4WP marking checkout as completed/created.
233
+ $requestItem->uuid = $uuid;
234
+ $requestItem->order_id = $order->get_id();
235
+ $requestItem->order_total = $order->get_total();
236
+ $requestItem->order_currency = $order->get_currency();
237
+ $requestItem->recovery_date = (empty($recovery_date) || $recovery_date === self::DATETIME_ZERO) ? null : $recovery_date;
238
+ }
239
 
240
  $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ) . $endpoint;
241
+ // Call remote endpoint to update.
242
  $this->ce4wp_remote_post( $requestItem, $endpoint );
243
  }
244
 
263
  * @since 1.3.0
264
  */
265
  public function maybe_capture_guest_checkout() {
266
+ $email = null;
267
  $data = filter_input_array( INPUT_POST, [
268
  self::NONCE => FILTER_SANITIZE_STRING,
269
  self::EMAIL => FILTER_SANITIZE_EMAIL
270
  ] );
271
 
272
+ if (!is_bool($data)) {
273
+ if ( empty( $data[self::NONCE] ) || ! wp_verify_nonce( $data[self::NONCE], 'woocommerce-process_checkout' ) ) {
274
+ wp_send_json_error( esc_html__( 'Invalid nonce.', self::DOMAIN ) );
275
+ }
276
+ $email = filter_var( $data[self::EMAIL], FILTER_VALIDATE_EMAIL );
277
  }
278
 
 
 
279
  if ( ! $email ) {
280
  wp_send_json_error( esc_html__( 'Invalid email.', self::DOMAIN ) );
281
  }
297
  self::NONCE => FILTER_SANITIZE_STRING
298
  ]);
299
 
300
+ if (!is_bool($data)) {
301
+ if (empty($data[self::NONCE]) || !wp_verify_nonce($data[self::NONCE], 'woocommerce-process_checkout')) {
302
+ wp_send_json_error(esc_html__('Invalid nonce.', self::DOMAIN));
303
+ }
304
  }
305
+
306
+ // Save no consent on session.
307
  WC()->session->set( self::BILLING_EMAIL_NO_CONSENT, true);
308
 
309
  $checkout_id = WC()->session->get( self::CHECKOUT_UUID );
311
  wp_send_json_success();
312
  }
313
 
314
+ $endpoint = EnvironmentHelper::get_app_gateway_url('wordpress') . '/v1.0/checkout/' . (! is_array($checkout_id) ? $checkout_id : '');
315
  $this->ce4wp_remote_delete( $endpoint );
316
  CreativeMail::get_instance()->get_database_manager()->change_checkout_consent( $checkout_id, false );
317
 
405
  /**
406
  * Save current checkout data to db.
407
  *
408
+ * @param string $billing_email Manually set customer billing email if provided.
409
+ * @param boolean $is_checkout Manually mark current page as checkout if necessary (e.g., coming from ajax callback).
 
410
  *
411
  * @since 1.3.0
412
  *
420
  if (empty($billing_email)) {
421
  $billing_email = $session_billing_email;
422
  if (empty($billing_email)) {
423
+ $billing_email = WC()->checkout()->get_value( self::BILLING_EMAIL );
424
  if (empty($billing_email)) {
425
  $billing_email = WC()->session->get( self::BILLING_EMAIL );
426
  }
433
  return;
434
  }
435
 
436
+ $has_no_consent = (bool) WC()->session->get( self::BILLING_EMAIL_NO_CONSENT );
437
+ if ( $has_no_consent === true ) {
 
438
  return;
439
  }
440
 
441
  // Check for existing checkout session.
442
  if ( ! $uuid ) {
 
443
  // Only create session if cart is not empty.
444
  // This is to avoid re-creating checkout UUID during checkout process.
445
  if ( $is_checkout && empty( WC()->cart->get_cart() ) ) {
446
  return;
447
  }
 
448
  // Retrieve existing checkout UUID for registered users only.
449
  if ( is_user_logged_in() ) {
450
  $existing_uuid = $this->get_checkout_uuid_by_user();
451
  }
 
452
  // Only create session if currently on checkout page or if current user has an existing session saved.
453
  if ( ! $is_checkout && empty( $existing_uuid ) ) {
454
  return;
455
  }
456
 
457
  $uuid = isset( $existing_uuid ) && ! empty( $existing_uuid ) ? $existing_uuid : wp_generate_uuid4();
 
458
  WC()->session->set( 'checkout_uuid', $uuid );
459
  }
460
 
478
  // Remote post to CE4WP create or update cart if email is provided.
479
  $requestItem = new CheckoutSave();
480
  $requestItem->data = wp_json_encode($this->get_cart_data_for_endpoint( $cart_products, $cart_coupons, $shipping_total, $shipping_taxes ) );
481
+ $requestItem->uuid = ! is_array($uuid) ? $uuid : '';
482
  $requestItem->user_id = $user_id;
483
  $requestItem->billing_email = $billing_email;
484
+ $requestItem->timestamp = (string) strtotime( $current_time );
485
  $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ) . '/v1.0/checkout/upsert';
486
 
487
  $consent = CreativeMail::get_instance()->get_database_manager()->has_checkout_consent( $uuid );
496
  * @since 1.3.0
497
  */
498
  private function get_cart_data_for_endpoint( $cart_products, $cart_coupons, $shipping_total=0.00, $shipping_taxes=array() ) {
499
+ $decimal_point = 2;
500
  $data = new CartData();
501
  $data->products = array();
502
  $data->coupons = array();
508
  $data->user = new User();
509
  try
510
  {
511
+ // Get user first and last name of available.
512
  $current_user = wp_get_current_user();
513
  if ( $current_user->exists() ) {
514
  $data->user->id = $current_user->ID;
519
  $data->user->email = $current_user->user_email;
520
  }
521
 
 
 
522
  foreach ( $cart_products as $value )
523
  {
524
  $product = array_key_exists( 'data', $value ) ? $value['data'] : wc_get_product( $value[self::PRODUCT_ID] );
536
  $product_data[ "regular_price" ] = $product->get_regular_price();
537
  $src = wc_placeholder_img_src();
538
  if ( $image_id = $product->get_image_id() ) {
539
+ $image_src = wp_get_attachment_image_src( $image_id, 'full' );
540
+ list( $src ) = (! is_bool($image_src) ? $image_src : array('') );
541
  }
542
 
543
  $line_subtotal = empty( $value['line_subtotal'] ) ? 0: $value[ 'line_subtotal' ];
550
  'product_id' => $product_id,
551
  'product_image' => $src,
552
  'product_data' => $product_data,
553
+ 'sku' => (!is_bool($product) && !empty($product) ? $product->get_sku() : null),
554
  'product_url' => get_the_permalink( $product_id ),
555
  'variation_id' => $value[ self::VARIATION_ID ],
556
+ 'subtotal' => wc_format_decimal( $line_subtotal, $decimal_point ),
557
+ 'subtotal_tax' => wc_format_decimal( $line_subtotal_tax, $decimal_point ),
558
+ 'total' => wc_format_decimal( $line_total, $decimal_point ),
559
+ 'total_tax' => wc_format_decimal( $line_tax, $decimal_point ),
560
+ 'price' => wc_format_decimal( $line_subtotal, $decimal_point ),
561
  'quantity' => $value[ self::QUANTITY ]
562
  );
563
  }
568
  if ( $coupon_id )
569
  {
570
  $coupon = new WC_Coupon( $coupon_id );
 
571
  $data->coupons[] = array(
572
  'code' => $coupon->get_code(),
573
  'amount' => $coupon->get_amount(),
604
  $order->update_meta_data( self::META_CHECKOUT_UUID, $checkout_id );
605
 
606
  // get the recovery date if recovered
607
+ $recovery_date = $this->get_checkout_recovery_date( ! is_array($checkout_id) ? $checkout_id : '' );
608
  if ( !empty( $recovery_date ) && $recovery_date !== self::DATETIME_ZERO )
609
  {
610
  $order->update_meta_data( self::META_CHECKOUT_RECOVERED, $recovery_date );
733
  private function ce4wp_remote_post( $requestItem, $endpoint ) {
734
  try
735
  {
736
+ // Check if abandoned cart email is managed by creative mail.
737
  $enabled = CreativeMail::get_instance()->get_email_manager()->is_email_managed( 'cart_abandoned_ce4wp' );
738
  if( $enabled ) {
739
  wp_remote_post(
784
 
785
  private function get_opt_in( $products_detail ) {
786
  $checkbox_value = $this->get_opt_in_checkbox_value( $products_detail );
787
+ if ( $checkbox_value == true ) {
788
+ return true;
789
+ }
790
  return null;
791
  }
792
 
793
  private function get_opt_out( $products_detail ) {
794
  $checkbox_value = $this->get_opt_in_checkbox_value( $products_detail );
795
+ if ( $checkbox_value == false ) {
796
  return true;
797
+ }
798
  return null;
799
  }
800
 
807
  if ( empty( $order ) ) {
808
  return;
809
  }
 
 
 
810
  $endpoint = '/v1.0/wc/order_completed';
811
  $decimal_point = 2;
812
+ $products_detail = get_post_meta($order_id);
813
+ $all_orders = wc_get_orders( array( 'email' => (is_object($order) && is_a($order, 'WC_Order') ? $order->get_billing_email() : '' ) ) );
814
 
815
+ // General Info.
816
  $requestItem = new RequestItem();
817
  $order_model = new Order();
818
  $order_billing = new OrderBilling();
819
 
820
+ if (! is_bool($order) && is_a( $order, 'WC_Order' )) {
821
+ $requestItem->order_id = $order->get_id();
822
+ $requestItem->order_number = $order->get_order_number();
823
+ $requestItem->date_created = $order->get_date_created();
824
+ $requestItem->date_modified = $order->get_date_modified();
825
+ $requestItem->date_completed = $order->get_date_completed();
826
+ $requestItem->status = $order->get_status();
827
+ $requestItem->order_url = $order->get_checkout_order_received_url();
828
+ $requestItem->note = $order->get_customer_note();
829
+ $requestItem->customer_ip = $order->get_customer_ip_address();
830
+ $requestItem->customer_user_agent = $order->get_customer_user_agent();
831
+ $requestItem->customer_id = $order->get_user_id();
832
+
833
+ // Order Billing.
834
+ $order_billing->email = $order->get_billing_email();
835
+ $order_billing->opt_action_by = $this->get_opt_action_by( $products_detail );
836
+ $order_billing->opt_in = $this->get_opt_in( $products_detail );
837
+ $order_billing->opt_out = $this->get_opt_out( $products_detail );
838
+
839
+ $order_billing->first_name = $order->get_billing_first_name();
840
+ $order_billing->last_name = $order->get_billing_last_name();
841
+ $order_billing->is_first_time_buyer = count( is_array($all_orders) ? $all_orders : [''] ) <= 1;
842
+ $order_billing->company = $order->get_billing_company();
843
+ $order_billing->address_1 = $order->get_billing_address_1();
844
+ $order_billing->address_2 = $order->get_billing_address_2();
845
+ $order_billing->city = $order->get_billing_city();
846
+ $order_billing->state = $order->get_billing_state();
847
+ $order_billing->postcode = $order->get_billing_postcode();
848
+ $order_billing->country = $order->get_billing_country();
849
+ $order_billing->email = $order->get_billing_email();
850
+ $order_billing->phone = $order->get_billing_phone();
851
+ $order_billing->shipping = array(
852
+ 'first_name' => $order->get_shipping_first_name(),
853
+ 'last_name' => $order->get_shipping_last_name(),
854
+ 'company' => $order->get_shipping_company(),
855
+ 'address_1' => $order->get_shipping_address_1(),
856
+ 'address_2' => $order->get_shipping_address_2(),
857
+ 'city' => $order->get_shipping_city(),
858
+ 'state' => $order->get_shipping_state(),
859
+ 'postcode' => $order->get_shipping_postcode(),
860
+ 'country' => $order->get_shipping_country(),
861
+ 'shipping_methods' => $order->get_shipping_method()
862
+ );
863
+ $order_billing->payment_details = array(
864
+ 'method_id' => $order->get_payment_method(),
865
+ 'method_title' => $order->get_payment_method_title(),
866
+ 'paid' => !is_null($order->get_date_paid()),
867
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
868
 
869
+ // Order Currency and Total Info.
870
+ $requestItem->total = wc_format_decimal( $order->get_total(), $decimal_point );
871
+ $requestItem->subtotal = wc_format_decimal( $order->get_subtotal(), $decimal_point );
872
+ $requestItem->total_tax = wc_format_decimal( $order->get_total_tax(), $decimal_point );
873
+ $requestItem->shipping_total = wc_format_decimal( $order->get_shipping_total(), $decimal_point );
874
+ $requestItem->cart_tax = (float) wc_format_decimal( $order->get_cart_tax(), $decimal_point );
875
+ $requestItem->shipping_tax = wc_format_decimal( $order->get_shipping_tax(), $decimal_point );
876
+ $requestItem->discount_total = wc_format_decimal( $order->get_total_discount(), $decimal_point );
877
+ $order_model->currency_symbol = get_woocommerce_currency_symbol();
878
+ $order_model->currency = $order->get_currency();
879
+
880
+ // Order Products Info.
881
+ $order_model->total_line_items_quantity = $order->get_item_count();
882
+
883
+ // Line Items / Products array for the expected endpoint.
884
+ foreach ( $order->get_items() as $itemsKey => $item ) {
885
+ // @phpstan-ignore-next-line
886
+ $product = $item->get_product();
887
+
888
+ if ( empty( $product ) ) {
889
+ continue;
890
+ }
891
 
892
+ $item_meta = $item->get_formatted_meta_data();
 
 
 
 
893
 
894
+ foreach ( $item_meta as $key => $values ) {
895
+ $item_meta[ $key ]->label = $values->display_key;
896
+ unset( $item_meta[ $key ]->display_key );
897
+ unset( $item_meta[ $key ]->display_value );
 
 
 
 
898
  }
899
 
900
+ try {
901
+ $product_data = array(
902
+ 'images' => array(),
903
+ 'downloads' => array()
904
+ );
905
+ $attachment_ids = $product->get_gallery_image_ids();
906
+ foreach ( $attachment_ids as $attachment_id ) {
907
+ $product_data[ 'images' ][] = wp_get_attachment_url( $attachment_id );
908
+ }
909
 
910
+ $product_data[ "on_sale" ] = $product->is_on_sale();
911
+ $product_data[ "sale_price" ] = $product->get_sale_price();
912
+ $product_data[ "regular_price" ] = $product->get_regular_price();
913
+
914
+ if ( $product->is_downloadable() ) {
915
+ // @phpstan-ignore-next-line
916
+ $item_downloads = $item->get_item_downloads();
917
+ foreach ( $item_downloads as $item_download )
918
+ {
919
+ $product_data[ "downloads" ][] = array(
920
+ 'line_item_id' => $item->get_id(),
921
+ // @phpstan-ignore-next-line
922
+ 'product_id' => $item->get_product_id(),
923
+ 'download_url' => $item_download[ "download_url" ],
924
+ 'download_file' => $item_download[ "file" ],
925
+ 'download_name' => $item_download[ "name" ],
926
+ 'download_id' => $item_download[ "id" ],
927
+ 'downloads_remaining' => $item_download[ "downloads_remaining" ],
928
+ 'download_access_expires' => wc_format_datetime( $item_download[ "access_expires" ], 'U' ),
929
+ 'download_limit' => $product->get_download_limit(),
930
+ 'download_expiry' => $product->get_download_expiry(),
931
+ );
932
+ }
933
  }
934
+ } catch ( Exception $ex ) {
935
+ RaygunManager::get_instance()->exception_handler( $ex );
936
  }
 
 
 
937
 
938
+ $src = wc_placeholder_img_src();
939
+ if ( $image_id = $product->get_image_id() ) {
940
+ $image_src = wp_get_attachment_image_src( $image_id, 'full' );
941
+ list( $src ) = is_array($image_src) ? $image_src : array('');
942
+ }
943
 
944
+ $order_model->line_items[] = array(
945
+ // @phpstan-ignore-next-line
946
+ 'product_id' => $item->get_product_id(),
947
+ 'item_meta' => $item->get_formatted_meta_data(),
948
+ 'subtotal' => wc_format_decimal($order->get_line_subtotal( $item, false, false), $decimal_point ),
949
+ // @phpstan-ignore-next-line
950
+ 'subtotal_tax' => wc_format_decimal( $item->get_subtotal_tax(), $decimal_point ),
951
+ 'total' => wc_format_decimal( $order->get_line_total($item, false, false), $decimal_point ),
952
+ // @phpstan-ignore-next-line
953
+ 'total_tax' => wc_format_decimal( $item->get_total_tax(), $decimal_point ),
954
+ 'price' => wc_format_decimal( $order->get_item_total($item, false, false), $decimal_point ),
955
+ 'quantity' => $item->get_quantity(),
956
+ 'tax_class' => $item->get_tax_class(),
957
+ 'name' => $item->get_name(),
958
+ 'product_image' => $src,
959
+ 'product_data' => $product_data,
960
+ 'sku' => is_a($product, 'WC_Product') ? $product->get_sku() : null,
961
+ 'meta' => array_values( $item_meta ),
962
+ // @phpstan-ignore-next-line
963
+ 'product_url' => get_the_permalink( $item->get_product_id() ),
964
+ // @phpstan-ignore-next-line
965
+ 'variation_id' => $item->get_variation_id()
966
+ );
967
+ }
968
  }
 
969
  $order_model->billing = $order_billing;
970
  $requestItem->order = $order_model;
971
 
src/Managers/DatabaseManager.php CHANGED
@@ -333,11 +333,13 @@ class DatabaseManager
333
  public static function get_table_name(string $OptionName): string
334
  {
335
  global $wpdb;
 
336
  if ($OptionName == self::ABANDONED_CART_TABLE_NAME) {
337
- return $wpdb->prefix . self::ABANDONED_CART_TABLE_NAME;
338
  } else if ($OptionName == self::CONTACTS_TABLE_NAME) {
339
- return $wpdb->prefix . self::CONTACTS_TABLE_NAME;
340
  }
 
341
  }
342
 
343
  public function insert_contact($data)
333
  public static function get_table_name(string $OptionName): string
334
  {
335
  global $wpdb;
336
+ $table_name = null;
337
  if ($OptionName == self::ABANDONED_CART_TABLE_NAME) {
338
+ $table_name = $wpdb->prefix . self::ABANDONED_CART_TABLE_NAME;
339
  } else if ($OptionName == self::CONTACTS_TABLE_NAME) {
340
+ $table_name = $wpdb->prefix . self::CONTACTS_TABLE_NAME;
341
  }
342
+ return is_string($table_name)? $table_name : '';
343
  }
344
 
345
  public function insert_contact($data)
src/Managers/EmailManager.php CHANGED
@@ -4,6 +4,7 @@
4
  namespace CreativeMail\Managers;
5
 
6
  use CreativeMail\CreativeMail;
 
7
  use CreativeMail\Models\CustomerNewAccount;
8
  use CreativeMail\Models\CustomerNote;
9
  use CreativeMail\Models\CustomerResetPassword;
@@ -12,6 +13,8 @@ use CreativeMail\Models\TriggerExecution;
12
  use CreativeMail\Modules\WooCommerce\Emails\AbandonedCartEmail;
13
  use CreativeMail\Helpers\EnvironmentHelper;
14
  use CreativeMail\Helpers\OptionsHelper;
 
 
15
  use WC_Email;
16
 
17
  /**
@@ -50,16 +53,16 @@ class EmailManager
50
 
51
  public function add_hooks()
52
  {
53
- // check if woocommerce is active
54
  if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
55
  add_action('init', array($this, 'manage_emails'));
56
 
57
- // email settings table customizations
58
  add_filter('woocommerce_email_setting_columns', array($this, 'customize_email_setting_columns'));
59
  add_action('woocommerce_email_setting_column_wc_ce_status', array($this, 'render_email_status_column'));
60
  add_action('woocommerce_email_settings_before', array($this, 'redirect_managed_email_settings_to_creative_mail'));
61
 
62
- //woocommerce hooks
63
  add_action('woocommerce_new_order', array($this, 'ce_email_notification_new_order'), 10, 2);
64
  add_action('woocommerce_order_status_cancelled', array($this, 'ce_email_notification_cancelled'), 10, 2);
65
  add_action('woocommerce_order_status_failed', array($this, 'ce_email_notification_failed'), 10, 2);
@@ -68,18 +71,19 @@ class EmailManager
68
  add_action('woocommerce_order_status_completed', array($this, 'ce_email_notification_completed'), 10, 2);
69
  add_action('woocommerce_order_status_refunded', array($this, 'ce_email_notification_refunded'), 10, 2);
70
  add_action('woocommerce_after_resend_order_email', array($this, 'ce_email_notification_invoice'), 10, 2);
71
- //payment complete
 
72
  add_action('woocommerce_payment_complete', array( $this, 'ce_email_notification_payment_complete'), 10, 1);
73
- //
74
  add_action('woocommerce_new_customer_note', array( $this, 'ce_email_notification_new_customer_note'), 10, 2);
75
- //
76
  add_action('woocommerce_reset_password_notification', array( $this, 'ce_email_notification_customer_reset_password' ), 10, 2);
77
  add_action('woocommerce_created_customer', array( $this, 'ce_email_notification_customer_new_account' ), 10, 3);
78
- // replace wc email settings
79
  add_filter('woocommerce_email_settings', array($this, 'replace_wc_email_settings'));
80
  add_action('woocommerce_admin_field_ce_manage_button', array($this, 'print_ce_manage_button'));
81
- // add checkbox to checkout if enabled
82
- if (OptionsHelper::get_checkout_checkbox_enabled() === '1') {
83
  add_filter('woocommerce_after_order_notes', array($this, 'add_checkout_field'));
84
  add_action('woocommerce_checkout_update_order_meta', array($this, 'ce_checkout_order_meta'));
85
  }
@@ -89,9 +93,8 @@ class EmailManager
89
  }
90
 
91
  public function add_emails( $email_classes ) {
92
- // Add fake email
93
- $email_classes['AbandonedCartEmail'] = new AbandonedCartEmail( $email_classes );
94
-
95
  return $email_classes;
96
  }
97
 
@@ -130,10 +133,10 @@ class EmailManager
130
  'woocommerce_email_text_color' => 'text_color'
131
  );
132
 
133
- // Define options that need to be replaced
134
  $replace = array_merge(array_keys($default_setting_replacement), array('email_template_options'));
135
 
136
- // remove settings
137
  foreach ($settings as $setting_key => $setting) {
138
  if (isset($setting['id']) && in_array($setting['id'], $replace, true)) {
139
  unset($settings[$setting_key]);
@@ -178,15 +181,13 @@ class EmailManager
178
 
179
  public function set_managed_email_notifications($body)
180
  {
181
- if (empty($body) || $body === null ) {
182
  return null;
183
  }
184
 
185
- if (property_exists($body, 'name') ) {
186
- if (in_array($body->name, $this->valid_email_notification_names) ) {
187
- OptionsHelper::set_managed_email_notification($body->name, $body->active == true ? 'true' : 'false');
188
- return $body;
189
- }
190
  }
191
 
192
  return null;
@@ -261,21 +262,29 @@ class EmailManager
261
 
262
  if ( $password_generated && key_exists( "user_pass", $new_customer_data ) ) {
263
  try {
264
- $generated_password = $new_customer_data[ 'user_pass' ];
265
- $key = sha1( OptionsHelper::get_instance_api_key() . OptionsHelper::get_instance_uuid() );
266
- $salt = openssl_random_pseudo_bytes( openssl_cipher_iv_length( 'aes-256-cbc' ) );
267
  $salted = '';
268
  $dx = '';
269
- while ( strlen( $salted ) < 48 ) {
270
- $dx = md5( $dx . $key . $salt, true );
271
- $salted .= $dx;
 
 
 
 
 
 
 
 
 
 
 
272
  }
273
  $key = substr( $salted, 0, 32 );
274
  $iv = substr( $salted, 32, 16 );
275
  $gp = openssl_encrypt( $generated_password, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv );
276
- $data->salt = bin2hex( $salt );
277
- $data->generated_password = base64_encode( $gp );
278
- } catch ( \Exception $ex ) {
279
  RaygunManager::get_instance()->exception_handler( $ex );
280
  }
281
  }
@@ -288,8 +297,10 @@ class EmailManager
288
  if ( $user_login && $reset_key ) {
289
  $data = new CustomerResetPassword();
290
  $user = get_user_by( 'login', $user_login );
291
- $data->customer_id = $user->ID;
292
- $data->customer = $this->get_customer_data($user->ID);
 
 
293
  $data->account_url = $this->get_my_account_url();
294
  $data->reset_url = add_query_arg(
295
  array(
@@ -501,14 +512,15 @@ class EmailManager
501
  }
502
  }
503
 
504
- } catch ( \Exception $ex )
505
  {
506
  RaygunManager::get_instance()->exception_handler( $ex );
507
  }
508
 
509
  $src = wc_placeholder_img_src();
510
  if ( $image_id = $product->get_image_id() ) {
511
- list( $src ) = wp_get_attachment_image_src( $image_id, 'full' );
 
512
  }
513
 
514
  $order_data[ 'line_items' ][] = array(
@@ -524,14 +536,14 @@ class EmailManager
524
  'product_id' => $item->get_product_id(),
525
  'product_image' => $src,
526
  'product_data' => $product_data,
527
- 'sku' => is_object( $product ) ? $product->get_sku() : null,
528
  'meta' => array_values( $item_meta ),
529
  'product_url' => get_the_permalink( $item->get_product_id() ),
530
  'variation_id' => $item->get_variation_id()
531
  );
532
  }
533
 
534
- // add shipping
535
  foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) {
536
  $order_data[ 'shipping_lines' ][] = array(
537
  'id' => $shipping_item_id,
@@ -541,7 +553,7 @@ class EmailManager
541
  );
542
  }
543
 
544
- // add taxes
545
  foreach ( $order->get_tax_totals() as $tax_code => $tax ) {
546
  $order_data[ 'tax_lines' ][] = array(
547
  'id' => $tax->id,
@@ -553,7 +565,7 @@ class EmailManager
553
  );
554
  }
555
 
556
- // add fees
557
  foreach ( $order->get_fees() as $fee_item_id => $fee_item ) {
558
  $order_data[ 'fee_lines' ][] = array(
559
  'id' => $fee_item_id,
@@ -564,7 +576,7 @@ class EmailManager
564
  );
565
  }
566
 
567
- // add coupons
568
  foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) {
569
  $order_data[ 'coupon_lines' ][] = array(
570
  'id' => $coupon_item_id,
@@ -575,13 +587,14 @@ class EmailManager
575
  $data->order = $order_data;
576
  $with_data = true;
577
  }
578
- catch ( \Exception $ex ) {
579
  RaygunManager::get_instance()->exception_handler( $ex );
580
  $with_data = false;
581
  }
582
  }
583
 
584
- $requestItem->data = wp_json_encode( $data );
 
585
  $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ).'/v1.0/wc/trigger';
586
  if ( $with_data )
587
  {
@@ -615,7 +628,7 @@ class EmailManager
615
  return;
616
  }
617
 
618
- // disable managed emails
619
  foreach ( $this->managed_email_notifications as $notification )
620
  {
621
  if ( $this->is_email_managed( $notification->name ) ) {
@@ -641,9 +654,7 @@ class EmailManager
641
  */
642
  public function override_managed_email_title( $title, $email )
643
  {
644
-
645
- if ( isset( $email->id ) && $this->is_email_managed( $email->id ) ) {
646
-
647
  $title .= __( ' (Managed by Creative Mail)', 'ce4wp' );
648
  }
649
 
@@ -663,9 +674,7 @@ class EmailManager
663
  */
664
  public function override_managed_email_description( $description, $email )
665
  {
666
-
667
- if ( isset( $email->id ) && $this->is_email_managed( $email->id ) ) {
668
-
669
  $description .= __( ' This email is being managed and sent by Creative Mail.', 'ce4wp' );
670
  }
671
 
@@ -791,10 +800,10 @@ class EmailManager
791
  $order = wc_get_order( $order_id );
792
  }
793
 
794
- if (isset( $order ) && method_exists( $order, 'get_view_order_url' ) ) {
795
  return $order->get_view_order_url();
796
  }
797
- } catch ( \Exception $exception ) {
798
  RaygunManager::get_instance()->exception_handler( $exception );
799
  }
800
 
@@ -805,7 +814,7 @@ class EmailManager
805
  {
806
  try {
807
  return wc_get_page_permalink( 'myaccount' );
808
- } catch ( \Exception $exception ) {
809
  RaygunManager::get_instance()->exception_handler( $exception );
810
  }
811
 
@@ -815,19 +824,25 @@ class EmailManager
815
  private function get_customer_data( $customer_id )
816
  {
817
  try {
818
- $customer = new \WC_Customer( $customer_id );
819
 
820
  $data = $customer->get_data();
821
 
822
  if ($data[ 'date_created' ] != null) {
823
- $data[ 'date_created' ] = $customer->get_date_created()->getTimestamp();
 
 
 
824
  }
825
  if ($data[ 'date_modified' ] != null) {
826
- $data[ 'date_modified' ] = $customer->get_date_modified()->getTimestamp();
 
 
 
827
  }
828
 
829
  return $data;
830
- } catch ( \Exception $exception ) {
831
  RaygunManager::get_instance()->exception_handler( $exception );
832
  }
833
  return null;
4
  namespace CreativeMail\Managers;
5
 
6
  use CreativeMail\CreativeMail;
7
+ use CreativeMail\Helpers\ValidationHelper;
8
  use CreativeMail\Models\CustomerNewAccount;
9
  use CreativeMail\Models\CustomerNote;
10
  use CreativeMail\Models\CustomerResetPassword;
13
  use CreativeMail\Modules\WooCommerce\Emails\AbandonedCartEmail;
14
  use CreativeMail\Helpers\EnvironmentHelper;
15
  use CreativeMail\Helpers\OptionsHelper;
16
+ use Exception;
17
+ use WC_Customer;
18
  use WC_Email;
19
 
20
  /**
53
 
54
  public function add_hooks()
55
  {
56
+ // Check if woocommerce is active.
57
  if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
58
  add_action('init', array($this, 'manage_emails'));
59
 
60
+ // Email settings table customizations.
61
  add_filter('woocommerce_email_setting_columns', array($this, 'customize_email_setting_columns'));
62
  add_action('woocommerce_email_setting_column_wc_ce_status', array($this, 'render_email_status_column'));
63
  add_action('woocommerce_email_settings_before', array($this, 'redirect_managed_email_settings_to_creative_mail'));
64
 
65
+ // Woocommerce hooks.
66
  add_action('woocommerce_new_order', array($this, 'ce_email_notification_new_order'), 10, 2);
67
  add_action('woocommerce_order_status_cancelled', array($this, 'ce_email_notification_cancelled'), 10, 2);
68
  add_action('woocommerce_order_status_failed', array($this, 'ce_email_notification_failed'), 10, 2);
71
  add_action('woocommerce_order_status_completed', array($this, 'ce_email_notification_completed'), 10, 2);
72
  add_action('woocommerce_order_status_refunded', array($this, 'ce_email_notification_refunded'), 10, 2);
73
  add_action('woocommerce_after_resend_order_email', array($this, 'ce_email_notification_invoice'), 10, 2);
74
+
75
+ // Payment complete.
76
  add_action('woocommerce_payment_complete', array( $this, 'ce_email_notification_payment_complete'), 10, 1);
77
+ // New customer Note.
78
  add_action('woocommerce_new_customer_note', array( $this, 'ce_email_notification_new_customer_note'), 10, 2);
79
+ // Password reset.
80
  add_action('woocommerce_reset_password_notification', array( $this, 'ce_email_notification_customer_reset_password' ), 10, 2);
81
  add_action('woocommerce_created_customer', array( $this, 'ce_email_notification_customer_new_account' ), 10, 3);
82
+ // Replace WC Email settings.
83
  add_filter('woocommerce_email_settings', array($this, 'replace_wc_email_settings'));
84
  add_action('woocommerce_admin_field_ce_manage_button', array($this, 'print_ce_manage_button'));
85
+ // Add checkbox to check out if enabled.
86
+ if (OptionsHelper::get_checkout_checkbox_enabled() == '1') {
87
  add_filter('woocommerce_after_order_notes', array($this, 'add_checkout_field'));
88
  add_action('woocommerce_checkout_update_order_meta', array($this, 'ce_checkout_order_meta'));
89
  }
93
  }
94
 
95
  public function add_emails( $email_classes ) {
96
+ // Add fake email.
97
+ $email_classes['AbandonedCartEmail'] = new AbandonedCartEmail();
 
98
  return $email_classes;
99
  }
100
 
133
  'woocommerce_email_text_color' => 'text_color'
134
  );
135
 
136
+ // Define options that need to be replaced.
137
  $replace = array_merge(array_keys($default_setting_replacement), array('email_template_options'));
138
 
139
+ // Remove settings.
140
  foreach ($settings as $setting_key => $setting) {
141
  if (isset($setting['id']) && in_array($setting['id'], $replace, true)) {
142
  unset($settings[$setting_key]);
181
 
182
  public function set_managed_email_notifications($body)
183
  {
184
+ if (empty($body)) {
185
  return null;
186
  }
187
 
188
+ if ( property_exists($body, 'name') && in_array( $body->name, $this->valid_email_notification_names ) ) {
189
+ OptionsHelper::set_managed_email_notification($body->name, $body->active == true ? 'true' : 'false');
190
+ return $body;
 
 
191
  }
192
 
193
  return null;
262
 
263
  if ( $password_generated && key_exists( "user_pass", $new_customer_data ) ) {
264
  try {
 
 
 
265
  $salted = '';
266
  $dx = '';
267
+ $salt = null;
268
+
269
+ $generated_password = $new_customer_data[ 'user_pass' ];
270
+ $key = sha1( OptionsHelper::get_instance_api_key() . OptionsHelper::get_instance_uuid() );
271
+ $openssl_cipher_iv_length = openssl_cipher_iv_length( 'aes-256-cbc' );
272
+
273
+ if (! is_bool( $openssl_cipher_iv_length )) {
274
+ $salt = openssl_random_pseudo_bytes( $openssl_cipher_iv_length );
275
+ }
276
+ if (! empty($salt) && is_string( $salt )) {
277
+ while ( strlen( $salted ) < 48 ) {
278
+ $dx = md5( $dx . $key . $salt, true );
279
+ $salted .= $dx;
280
+ }
281
  }
282
  $key = substr( $salted, 0, 32 );
283
  $iv = substr( $salted, 32, 16 );
284
  $gp = openssl_encrypt( $generated_password, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv );
285
+ $data->salt = bin2hex( is_string($salt) ? $salt : '' );
286
+ $data->generated_password = base64_encode( is_string($gp) ? $gp : '' );
287
+ } catch ( Exception $ex ) {
288
  RaygunManager::get_instance()->exception_handler( $ex );
289
  }
290
  }
297
  if ( $user_login && $reset_key ) {
298
  $data = new CustomerResetPassword();
299
  $user = get_user_by( 'login', $user_login );
300
+ if (!empty($user)) {
301
+ $data->customer_id = $user->ID;
302
+ $data->customer = $this->get_customer_data($user->ID);
303
+ }
304
  $data->account_url = $this->get_my_account_url();
305
  $data->reset_url = add_query_arg(
306
  array(
512
  }
513
  }
514
 
515
+ } catch ( Exception $ex )
516
  {
517
  RaygunManager::get_instance()->exception_handler( $ex );
518
  }
519
 
520
  $src = wc_placeholder_img_src();
521
  if ( $image_id = $product->get_image_id() ) {
522
+ $image_src = wp_get_attachment_image_src( $image_id, 'full' );
523
+ list( $src ) = is_array( $image_src ) ? $image_src : array('');
524
  }
525
 
526
  $order_data[ 'line_items' ][] = array(
536
  'product_id' => $item->get_product_id(),
537
  'product_image' => $src,
538
  'product_data' => $product_data,
539
+ 'sku' => is_a($product, 'WC_Product') ? $product->get_sku() : null,
540
  'meta' => array_values( $item_meta ),
541
  'product_url' => get_the_permalink( $item->get_product_id() ),
542
  'variation_id' => $item->get_variation_id()
543
  );
544
  }
545
 
546
+ // Add shipping.
547
  foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) {
548
  $order_data[ 'shipping_lines' ][] = array(
549
  'id' => $shipping_item_id,
553
  );
554
  }
555
 
556
+ // Add taxes.
557
  foreach ( $order->get_tax_totals() as $tax_code => $tax ) {
558
  $order_data[ 'tax_lines' ][] = array(
559
  'id' => $tax->id,
565
  );
566
  }
567
 
568
+ // Add fees.
569
  foreach ( $order->get_fees() as $fee_item_id => $fee_item ) {
570
  $order_data[ 'fee_lines' ][] = array(
571
  'id' => $fee_item_id,
576
  );
577
  }
578
 
579
+ // Add coupons.
580
  foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) {
581
  $order_data[ 'coupon_lines' ][] = array(
582
  'id' => $coupon_item_id,
587
  $data->order = $order_data;
588
  $with_data = true;
589
  }
590
+ catch ( Exception $ex ) {
591
  RaygunManager::get_instance()->exception_handler( $ex );
592
  $with_data = false;
593
  }
594
  }
595
 
596
+ $parsed_data = wp_json_encode( $data );
597
+ $requestItem->data = is_string( $parsed_data ) ? $parsed_data : '';
598
  $endpoint = EnvironmentHelper::get_app_gateway_url( 'wordpress' ).'/v1.0/wc/trigger';
599
  if ( $with_data )
600
  {
628
  return;
629
  }
630
 
631
+ // Disable managed emails.
632
  foreach ( $this->managed_email_notifications as $notification )
633
  {
634
  if ( $this->is_email_managed( $notification->name ) ) {
654
  */
655
  public function override_managed_email_title( $title, $email )
656
  {
657
+ if ( !empty( $email->id ) && $this->is_email_managed( $email->id ) ) {
 
 
658
  $title .= __( ' (Managed by Creative Mail)', 'ce4wp' );
659
  }
660
 
674
  */
675
  public function override_managed_email_description( $description, $email )
676
  {
677
+ if ( !empty( $email->id ) && $this->is_email_managed( $email->id ) ) {
 
 
678
  $description .= __( ' This email is being managed and sent by Creative Mail.', 'ce4wp' );
679
  }
680
 
800
  $order = wc_get_order( $order_id );
801
  }
802
 
803
+ if (isset( $order ) && is_object($order) && method_exists( $order, 'get_view_order_url' ) ) {
804
  return $order->get_view_order_url();
805
  }
806
+ } catch ( Exception $exception ) {
807
  RaygunManager::get_instance()->exception_handler( $exception );
808
  }
809
 
814
  {
815
  try {
816
  return wc_get_page_permalink( 'myaccount' );
817
+ } catch ( Exception $exception ) {
818
  RaygunManager::get_instance()->exception_handler( $exception );
819
  }
820
 
824
  private function get_customer_data( $customer_id )
825
  {
826
  try {
827
+ $customer = new WC_Customer( $customer_id );
828
 
829
  $data = $customer->get_data();
830
 
831
  if ($data[ 'date_created' ] != null) {
832
+ $data[ 'date_created' ] = $customer->get_date_created();
833
+ if (!empty($data[ 'date_created' ]) && is_a($data[ 'date_created' ], 'WC_DateTime')) {
834
+ $data[ 'date_created' ] = $data[ 'date_created' ]->getTimestamp();
835
+ }
836
  }
837
  if ($data[ 'date_modified' ] != null) {
838
+ $data[ 'date_modified' ] = $customer->get_date_modified();
839
+ if (!empty($data[ 'date_modified' ]) && is_a($data[ 'date_modified' ], 'WC_DateTime')) {
840
+ $data[ 'date_modified' ] = $data[ 'date_modified' ]->getTimestamp();
841
+ }
842
  }
843
 
844
  return $data;
845
+ } catch ( Exception $exception ) {
846
  RaygunManager::get_instance()->exception_handler( $exception );
847
  }
848
  return null;
src/Managers/FormManager.php CHANGED
@@ -6,6 +6,7 @@ namespace CreativeMail\Managers;
6
  use CreativeMail\CreativeMail;
7
  use CreativeMail\Clients\CreativeMailClient;
8
  use CreativeMail\Helpers\OptionsHelper;
 
9
 
10
  /**
11
  * Class CheckoutManager
@@ -64,16 +65,16 @@ class FormManager
64
  self::LISTID => FILTER_SANITIZE_STRING
65
  ]);
66
 
67
- if (empty($data[self::NONCE]) || !wp_verify_nonce($data[self::NONCE], 'ce4wp_form_submission')) {
68
  wp_send_json_error(esc_html__('Invalid nonce.', self::DOMAIN));
69
  }
70
 
71
  do_action('ce4wp_contact_submission', $data);
72
 
73
  try {
74
- //Insert submission into database
75
  CreativeMail::get_instance()->get_database_manager()->insert_contact($data);
76
- } catch (\Exception $exception) {
77
  RaygunManager::get_instance()->exception_handler($exception);
78
  }
79
 
@@ -85,8 +86,7 @@ class FormManager
85
  $data = filter_input_array(INPUT_POST, [
86
  self::NONCE => FILTER_SANITIZE_STRING
87
  ]);
88
-
89
- if (empty($data[self::NONCE]) || !wp_verify_nonce($data[self::NONCE], 'ce4wp_get_lists')) {
90
  wp_send_json_error(esc_html__('Invalid nonce.', self::DOMAIN));
91
  }
92
  $list = $this->creative_mail_client->get_all_custom_lists();
@@ -104,7 +104,7 @@ class FormManager
104
  self::NONCE => FILTER_SANITIZE_STRING
105
  ]);
106
 
107
- if (empty($data[self::NONCE]) || !wp_verify_nonce($data[self::NONCE], 'ce4wp_get_creative_email_activated')) {
108
  wp_send_json_error(esc_html__('Invalid nonce.', self::DOMAIN));
109
  }
110
  wp_send_json_success(OptionsHelper::get_instance_id() != null);
6
  use CreativeMail\CreativeMail;
7
  use CreativeMail\Clients\CreativeMailClient;
8
  use CreativeMail\Helpers\OptionsHelper;
9
+ use Exception;
10
 
11
  /**
12
  * Class CheckoutManager
65
  self::LISTID => FILTER_SANITIZE_STRING
66
  ]);
67
 
68
+ if (is_array($data) && (empty($data[self::NONCE]) || !wp_verify_nonce($data[self::NONCE], 'ce4wp_form_submission'))) {
69
  wp_send_json_error(esc_html__('Invalid nonce.', self::DOMAIN));
70
  }
71
 
72
  do_action('ce4wp_contact_submission', $data);
73
 
74
  try {
75
+ // Insert submission into database.
76
  CreativeMail::get_instance()->get_database_manager()->insert_contact($data);
77
+ } catch (Exception $exception) {
78
  RaygunManager::get_instance()->exception_handler($exception);
79
  }
80
 
86
  $data = filter_input_array(INPUT_POST, [
87
  self::NONCE => FILTER_SANITIZE_STRING
88
  ]);
89
+ if (is_array($data) && (empty($data[self::NONCE]) || !wp_verify_nonce($data[self::NONCE], 'ce4wp_get_lists'))) {
 
90
  wp_send_json_error(esc_html__('Invalid nonce.', self::DOMAIN));
91
  }
92
  $list = $this->creative_mail_client->get_all_custom_lists();
104
  self::NONCE => FILTER_SANITIZE_STRING
105
  ]);
106
 
107
+ if (is_array($data) && (empty($data[self::NONCE]) || !wp_verify_nonce($data[self::NONCE], 'ce4wp_get_creative_email_activated'))) {
108
  wp_send_json_error(esc_html__('Invalid nonce.', self::DOMAIN));
109
  }
110
  wp_send_json_success(OptionsHelper::get_instance_id() != null);
src/Managers/IntegrationManager.php CHANGED
@@ -18,6 +18,7 @@ use CreativeMail\Modules\Contacts\Handlers\JetpackPluginHandler;
18
  use CreativeMail\Modules\Contacts\Handlers\NinjaFormsPluginHandler;
19
  use CreativeMail\Modules\Contacts\Handlers\CalderaPluginHandler;
20
  use CreativeMail\Modules\Contacts\Handlers\CreativeMailPluginHandler;
 
21
  use ReflectionClass;
22
 
23
  /**
@@ -35,10 +36,8 @@ class IntegrationManager
35
  public function __construct()
36
  {
37
  $this->active_integrations = array();
38
-
39
  $environment = strtolower(EnvironmentHelper::get_environment());
40
-
41
- // Setup the default integrations
42
  $this->supported_integrations = array(
43
  new Integration('jetpack', 'Jetpack Forms', 'jetpack/jetpack.php', JetpackPluginHandler::class, false),
44
  new Integration('jetpack-beta', 'Jetpack Forms (Beta)', 'jetpack-beta-master/jetpack-beta.php', JetpackPluginHandler::class, true),
@@ -65,19 +64,18 @@ class IntegrationManager
65
  $active_plugins = array_filter(
66
  $this->get_active_plugins(), function ($item) {
67
  return array_search($item->get_slug(), $this->get_activated_plugins(), true) !== false;
68
- }
69
- );
70
 
71
  foreach ($active_plugins as $active_plugin) {
72
  try {
73
  if (array_key_exists($active_plugin->get_slug(), $this->active_integrations) === false) {
74
- // use reflection to create instance of class
75
  $class = new ReflectionClass($active_plugin->get_integration_handler());
76
  $this->active_integrations[$active_plugin->get_slug()] = $class->newInstance();
77
  }
78
- // register hooks for integration class
79
  $this->active_integrations[$active_plugin->get_slug()]->registerHooks();
80
- } catch (\Exception $e) {
81
  RaygunManager::get_instance()->exception_handler($e);
82
  }
83
  }
@@ -100,15 +98,13 @@ class IntegrationManager
100
  */
101
  public function get_active_plugins()
102
  {
103
-
104
  $activated_plugins = array();
105
 
106
  foreach ($this->supported_integrations as $integration) {
107
  $activePlugins = $integration->use_basename()
108
  ? array_map('basename', apply_filters('active_plugins', get_option('active_plugins')))
109
  : apply_filters('active_plugins', get_option('active_plugins'));
110
-
111
- // Check if the plugin is activated
112
  if (in_array($integration->get_class(), $activePlugins)) {
113
  array_push($activated_plugins, $integration);
114
  }
@@ -135,11 +131,10 @@ class IntegrationManager
135
  */
136
  public function set_activated_plugins($plugins)
137
  {
138
-
139
- // Store the activated plugins
140
  OptionsHelper::set_activated_plugins(implode(';', $plugins));
141
 
142
- // Remove the hooks and add them again
143
  $this->remove_hooks();
144
  $this->add_hooks();
145
 
@@ -154,7 +149,7 @@ class IntegrationManager
154
  public function get_activated_plugins()
155
  {
156
  $activated_plugins = OptionsHelper::get_activated_plugins();
157
- if (is_null($activated_plugins)) {
158
  $activated_plugins = '';
159
  }
160
  if (is_array($activated_plugins)) {
18
  use CreativeMail\Modules\Contacts\Handlers\NinjaFormsPluginHandler;
19
  use CreativeMail\Modules\Contacts\Handlers\CalderaPluginHandler;
20
  use CreativeMail\Modules\Contacts\Handlers\CreativeMailPluginHandler;
21
+ use Exception;
22
  use ReflectionClass;
23
 
24
  /**
36
  public function __construct()
37
  {
38
  $this->active_integrations = array();
 
39
  $environment = strtolower(EnvironmentHelper::get_environment());
40
+ // Set up the default integrations.
 
41
  $this->supported_integrations = array(
42
  new Integration('jetpack', 'Jetpack Forms', 'jetpack/jetpack.php', JetpackPluginHandler::class, false),
43
  new Integration('jetpack-beta', 'Jetpack Forms (Beta)', 'jetpack-beta-master/jetpack-beta.php', JetpackPluginHandler::class, true),
64
  $active_plugins = array_filter(
65
  $this->get_active_plugins(), function ($item) {
66
  return array_search($item->get_slug(), $this->get_activated_plugins(), true) !== false;
67
+ });
 
68
 
69
  foreach ($active_plugins as $active_plugin) {
70
  try {
71
  if (array_key_exists($active_plugin->get_slug(), $this->active_integrations) === false) {
72
+ // Use reflection to create instance of class.
73
  $class = new ReflectionClass($active_plugin->get_integration_handler());
74
  $this->active_integrations[$active_plugin->get_slug()] = $class->newInstance();
75
  }
76
+ // Register hooks for integration class.
77
  $this->active_integrations[$active_plugin->get_slug()]->registerHooks();
78
+ } catch (Exception $e) {
79
  RaygunManager::get_instance()->exception_handler($e);
80
  }
81
  }
98
  */
99
  public function get_active_plugins()
100
  {
 
101
  $activated_plugins = array();
102
 
103
  foreach ($this->supported_integrations as $integration) {
104
  $activePlugins = $integration->use_basename()
105
  ? array_map('basename', apply_filters('active_plugins', get_option('active_plugins')))
106
  : apply_filters('active_plugins', get_option('active_plugins'));
107
+ // Check if the plugin is activated.
 
108
  if (in_array($integration->get_class(), $activePlugins)) {
109
  array_push($activated_plugins, $integration);
110
  }
131
  */
132
  public function set_activated_plugins($plugins)
133
  {
134
+ // Store the activated plugins.
 
135
  OptionsHelper::set_activated_plugins(implode(';', $plugins));
136
 
137
+ // Remove the hooks and add them again.
138
  $this->remove_hooks();
139
  $this->add_hooks();
140
 
149
  public function get_activated_plugins()
150
  {
151
  $activated_plugins = OptionsHelper::get_activated_plugins();
152
+ if ( empty( $activated_plugins) ) {
153
  $activated_plugins = '';
154
  }
155
  if (is_array($activated_plugins)) {
src/Managers/RaygunManager.php CHANGED
@@ -13,7 +13,7 @@ use Raygun4php\RaygunClient;
13
  */
14
  final class RaygunManager
15
  {
16
- // Lets make this a singleton
17
  private static $instance;
18
  private $raygun_client;
19
 
@@ -41,46 +41,51 @@ final class RaygunManager
41
  /**
42
  * Transmits an exception to the Raygun.io API
43
  *
44
- * @param \Exception $exception An exception object to transmit
45
  */
46
  function exception_handler($exception)
47
  {
48
  $this->raygun_client->SendException($exception, self::build_tags(), self::build_custom_user_data());
49
  }
50
 
 
 
 
 
 
51
  function build_tags()
52
  {
53
  $tags = [];
54
-
55
- try {
56
- // Get as many meta data as possible
57
- $tags['CE4WP_PLUGIN_VERSION'] = CE4WP_PLUGIN_VERSION;
58
- $tags['CE4WP_ENVIRONMENT'] = CE4WP_ENVIRONMENT;
59
- $tags['CE4WP_BUILD'] = CE4WP_BUILD_NUMBER;
60
- } catch (Exception $e) {
61
- // do nothing, otherwise we might have an endless loop
62
- }
63
-
64
  return $tags;
65
  }
66
 
 
 
 
 
 
67
  function build_custom_user_data()
68
  {
69
  $userData = [];
70
 
71
  try {
72
- // Get as many meta data as possible
73
  $userData['CE4WP_APP_URL'] = CE4WP_APP_URL;
74
  $userData['CE4WP_APP_GATEWAY_URL'] = CE4WP_APP_GATEWAY_URL;
75
 
76
- // user data that helps us identify the error
77
  $userData['CE4WP_CONNECTED_ACCOUNT_ID'] = get_option(CE4WP_CONNECTED_ACCOUNT_ID);
78
  $userData['CE4WP_INSTANCE_UUID_KEY'] = get_option(CE4WP_INSTANCE_UUID_KEY);
79
  $userData['CE4WP_MANAGED_EMAIL_NOTIFICATIONS'] = get_option(CE4WP_MANAGED_EMAIL_NOTIFICATIONS);
80
  $userData['CE4WP_ACTIVATED_PLUGINS'] = get_option(CE4WP_ACTIVATED_PLUGINS);
81
 
82
  } catch (Exception $e) {
83
- // do nothing, otherwise we might have an endless loop
 
 
84
  }
85
 
86
  return $userData;
13
  */
14
  final class RaygunManager
15
  {
16
+ // Let's make this a singleton.
17
  private static $instance;
18
  private $raygun_client;
19
 
41
  /**
42
  * Transmits an exception to the Raygun.io API
43
  *
44
+ * @param Exception $exception An exception object to transmit
45
  */
46
  function exception_handler($exception)
47
  {
48
  $this->raygun_client->SendException($exception, self::build_tags(), self::build_custom_user_data());
49
  }
50
 
51
+ /**
52
+ * Builds the tags to be sent to Raygun.io
53
+ *
54
+ * @throws Exception
55
+ */
56
  function build_tags()
57
  {
58
  $tags = [];
59
+ $tags['CE4WP_PLUGIN_VERSION'] = CE4WP_PLUGIN_VERSION;
60
+ $tags['CE4WP_ENVIRONMENT'] = CE4WP_ENVIRONMENT;
61
+ $tags['CE4WP_BUILD'] = CE4WP_BUILD_NUMBER;
 
 
 
 
 
 
 
62
  return $tags;
63
  }
64
 
65
+ /**
66
+ * Builds the custom user data to be sent to Raygun.io
67
+ *
68
+ * @throws Exception
69
+ */
70
  function build_custom_user_data()
71
  {
72
  $userData = [];
73
 
74
  try {
75
+ // Get as much metadata as possible.
76
  $userData['CE4WP_APP_URL'] = CE4WP_APP_URL;
77
  $userData['CE4WP_APP_GATEWAY_URL'] = CE4WP_APP_GATEWAY_URL;
78
 
79
+ // User data that helps us identify the error.
80
  $userData['CE4WP_CONNECTED_ACCOUNT_ID'] = get_option(CE4WP_CONNECTED_ACCOUNT_ID);
81
  $userData['CE4WP_INSTANCE_UUID_KEY'] = get_option(CE4WP_INSTANCE_UUID_KEY);
82
  $userData['CE4WP_MANAGED_EMAIL_NOTIFICATIONS'] = get_option(CE4WP_MANAGED_EMAIL_NOTIFICATIONS);
83
  $userData['CE4WP_ACTIVATED_PLUGINS'] = get_option(CE4WP_ACTIVATED_PLUGINS);
84
 
85
  } catch (Exception $e) {
86
+ // We don't want to throw an exception here, as this is just a helper function.
87
+ // We'll just log the error and move on.
88
+ error_log($e->getMessage());
89
  }
90
 
91
  return $userData;
src/Models/CheckoutSave.php CHANGED
@@ -7,13 +7,13 @@ class CheckoutSave
7
  /**
8
  * Billing email address
9
  *
10
- * @var string
11
  */
12
  public $billing_email;
13
  /**
14
  * Checkout data
15
  *
16
- * @var string
17
  */
18
  public $data;
19
  /**
7
  /**
8
  * Billing email address
9
  *
10
+ * @var string|false
11
  */
12
  public $billing_email;
13
  /**
14
  * Checkout data
15
  *
16
+ * @var string|false
17
  */
18
  public $data;
19
  /**
src/Modules/Blog/Models/BlogAttachment.php CHANGED
@@ -10,6 +10,7 @@ class BlogAttachment
10
  public $modified;
11
  public $url;
12
  public $thumbnail;
 
13
 
14
  function __construct($wp_attachment)
15
  {
10
  public $modified;
11
  public $url;
12
  public $thumbnail;
13
+ public $meta_data;
14
 
15
  function __construct($wp_attachment)
16
  {
src/Modules/Blog/Models/BlogInformation.php CHANGED
@@ -6,6 +6,7 @@ use CreativeMail\Modules\WooCommerce\Models\WCStoreInformation;
6
 
7
  class BlogInformation
8
  {
 
9
  public $title;
10
  public $description;
11
  public $url;
6
 
7
  class BlogInformation
8
  {
9
+ public $plugin_version;
10
  public $title;
11
  public $description;
12
  public $url;
src/Modules/Contacts/Handlers/BaseContactFormPluginHandler.php CHANGED
@@ -20,6 +20,10 @@ abstract class BaseContactFormPluginHandler
20
  protected $firstnameFields = array('firstname', 'first_name', 'name', 'your-name', 'first name', 'first-name', 'first', 'UserFirstName');
21
  protected $lastnameFields = array('lastname', 'last_name', 'last name', 'last-name', 'last', 'UserLastName');
22
  protected $consentFields = array('accept-this', 'acceptance', 'consent');
 
 
 
 
23
 
24
  public function upsertContact($model)
25
  {
20
  protected $firstnameFields = array('firstname', 'first_name', 'name', 'your-name', 'first name', 'first-name', 'first', 'UserFirstName');
21
  protected $lastnameFields = array('lastname', 'last_name', 'last name', 'last-name', 'last', 'UserLastName');
22
  protected $consentFields = array('accept-this', 'acceptance', 'consent');
23
+ protected $cityFields = array('your-city', 'city', 'UserCity');
24
+ protected $stateFields = array('your-state', 'state', 'StateDropDown');
25
+ protected $countryFields = array('your-country','country', 'CountryDropDown');
26
+ protected $zipFields = array('your-zip','zip', 'zipcode', 'UserZip');
27
 
28
  public function upsertContact($model)
29
  {
src/Modules/Contacts/Handlers/BlueHostBuilderPluginHandler.php CHANGED
@@ -7,6 +7,7 @@ define('CE4WP_WB4WP_EVENTTYPE', 'WordPress - BlueHost Builder');
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
 
10
 
11
  class BlueHostBuilderPluginHandler extends BaseContactFormPluginHandler
12
  {
@@ -20,15 +21,15 @@ class BlueHostBuilderPluginHandler extends BaseContactFormPluginHandler
20
  }
21
  $contactModel->setEmail($email);
22
  $contactModel->setEventType(CE4WP_WB4WP_EVENTTYPE);
23
-
24
  if (!empty($contact->opt_in) && (!$contact->opt_out || $contact->opt_out < $contact->opt_in)) {
25
  $contactModel->setOptIn(true);
26
  $contactModel->setOptActionBy(OptActionBy::Owner);
27
  }
28
-
29
  if (!empty($contact->opt_out) && (!$contact->opt_in || $contact->opt_out > $contact->opt_in)) {
30
  $contactModel->setOptOut($contact->opt_out);
31
- $contactModel->setOptActionBy(OptActionBy::User);
32
  }
33
 
34
  if (!empty($contact->first_name)) {
@@ -57,7 +58,7 @@ class BlueHostBuilderPluginHandler extends BaseContactFormPluginHandler
57
  return;
58
  }
59
  $this->upsertContact($this->convertToContactModel($contact));
60
- } catch (\Exception $exception) {
61
  RaygunManager::get_instance()->exception_handler($exception);
62
  }
63
  }
@@ -91,7 +92,7 @@ class BlueHostBuilderPluginHandler extends BaseContactFormPluginHandler
91
  $contactModel = null;
92
  try {
93
  $contactModel = $this->convertToContactModel($contact);
94
- } catch (\Exception $exception) {
95
  RaygunManager::get_instance()->exception_handler($exception);
96
  continue;
97
  }
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
10
+ use Exception;
11
 
12
  class BlueHostBuilderPluginHandler extends BaseContactFormPluginHandler
13
  {
21
  }
22
  $contactModel->setEmail($email);
23
  $contactModel->setEventType(CE4WP_WB4WP_EVENTTYPE);
24
+ // @phpstan-ignore-next-line
25
  if (!empty($contact->opt_in) && (!$contact->opt_out || $contact->opt_out < $contact->opt_in)) {
26
  $contactModel->setOptIn(true);
27
  $contactModel->setOptActionBy(OptActionBy::Owner);
28
  }
29
+ // @phpstan-ignore-next-line
30
  if (!empty($contact->opt_out) && (!$contact->opt_in || $contact->opt_out > $contact->opt_in)) {
31
  $contactModel->setOptOut($contact->opt_out);
32
+ $contactModel->setOptActionBy(OptActionBy::Visitor);
33
  }
34
 
35
  if (!empty($contact->first_name)) {
58
  return;
59
  }
60
  $this->upsertContact($this->convertToContactModel($contact));
61
+ } catch (Exception $exception) {
62
  RaygunManager::get_instance()->exception_handler($exception);
63
  }
64
  }
92
  $contactModel = null;
93
  try {
94
  $contactModel = $this->convertToContactModel($contact);
95
+ } catch (Exception $exception) {
96
  RaygunManager::get_instance()->exception_handler($exception);
97
  continue;
98
  }
src/Modules/Contacts/Handlers/ContactFormSevenPluginHandler.php CHANGED
@@ -7,6 +7,7 @@ define('CE4WP_CF7_EVENTTYPE', 'WordPress - Contact Form 7');
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactFormSevenSubmission;
9
  use CreativeMail\Modules\Contacts\Models\ContactModel;
 
10
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
11
 
12
  class ContactFormSevenPluginHandler extends BaseContactFormPluginHandler
@@ -76,11 +77,46 @@ class ContactFormSevenPluginHandler extends BaseContactFormPluginHandler
76
  $contactModel->setOptOut(false);
77
  $contactModel->setOptActionBy(OptActionBy::Visitor);
78
  }
 
 
 
 
 
 
 
79
  $contactModel->setEventType(CE4WP_CF7_EVENTTYPE);
80
 
81
  return $contactModel;
82
  }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  public function registerHooks()
85
  {
86
  add_action('wpcf7_mail_sent', array($this, 'ceHandleContactFormSevenSubmit'));
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactFormSevenSubmission;
9
  use CreativeMail\Modules\Contacts\Models\ContactModel;
10
+ use CreativeMail\Modules\Contacts\Models\ContactAddressModel;
11
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
12
 
13
  class ContactFormSevenPluginHandler extends BaseContactFormPluginHandler
77
  $contactModel->setOptOut(false);
78
  $contactModel->setOptActionBy(OptActionBy::Visitor);
79
  }
80
+
81
+ $contactAddress = $this->getContactAddressFromForm($contactForm);
82
+
83
+ if (!empty($contactAddress)) {
84
+ $contactModel->setContactAddress($contactAddress);
85
+ }
86
+
87
  $contactModel->setEventType(CE4WP_CF7_EVENTTYPE);
88
 
89
  return $contactModel;
90
  }
91
 
92
+ function getContactAddressFromForm($contactForm)
93
+ {
94
+ $contactAddress = new ContactAddressModel();
95
+
96
+ if (isset($contactForm)) {
97
+ $city = $this->findValue($contactForm, $this->cityFields);
98
+ if (!empty($city)) {
99
+ $contactAddress->setCity($city);
100
+ }
101
+
102
+ $zip = $this->findValue($contactForm, $this->zipFields);
103
+ if (!empty($zip)) {
104
+ $contactAddress->setPostalCode($zip);
105
+ }
106
+
107
+ $state = $this->findValue($contactForm, $this->stateFields);
108
+ if (!empty($state) AND !empty($state[0])) {
109
+ $contactAddress->setStateCode($state[0]);
110
+ }
111
+
112
+ $country = $this->findValue($contactForm, $this->countryFields);
113
+ if (!empty($country) AND !empty($country[0])) {
114
+ $contactAddress->setCountryCode($country[0]);
115
+ }
116
+ }
117
+ return $contactAddress;
118
+ }
119
+
120
  public function registerHooks()
121
  {
122
  add_action('wpcf7_mail_sent', array($this, 'ceHandleContactFormSevenSubmit'));
src/Modules/Contacts/Handlers/CreativeMailPluginHandler.php CHANGED
@@ -7,6 +7,7 @@ define('CE4WP_CE_EVENTTYPE', 'WordPress - Creative Mail Form');
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
 
10
 
11
  class CreativeMailPluginHandler extends BaseContactFormPluginHandler
12
  {
@@ -46,7 +47,7 @@ class CreativeMailPluginHandler extends BaseContactFormPluginHandler
46
  {
47
  try {
48
  $this->upsertContact($this->convertToContactModel($data));
49
- } catch (\Exception $exception) {
50
  RaygunManager::get_instance()->exception_handler($exception);
51
  }
52
  }
@@ -70,19 +71,21 @@ class CreativeMailPluginHandler extends BaseContactFormPluginHandler
70
  global $wpdb;
71
  $contactsArray = array();
72
 
73
- //get contacts
74
  $contactsQuery = 'SELECT * FROM wp_ce4wp_contacts';
75
  $contactsResult = $wpdb->get_results($wpdb->prepare($contactsQuery));
76
 
77
  foreach ($contactsResult as $contact) {
78
- $contactModel = null;
79
  try {
80
- $contact = $this->convertToContactModel(json_decode(json_encode($contact), true));
 
 
 
81
  if (!empty($contact->getEmail())) {
82
  array_push($contactsArray, $contact);
83
  }
84
 
85
- } catch (\Exception $exception) {
86
  RaygunManager::get_instance()->exception_handler($exception);
87
  continue;
88
  }
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
10
+ use Exception;
11
 
12
  class CreativeMailPluginHandler extends BaseContactFormPluginHandler
13
  {
47
  {
48
  try {
49
  $this->upsertContact($this->convertToContactModel($data));
50
+ } catch (Exception $exception) {
51
  RaygunManager::get_instance()->exception_handler($exception);
52
  }
53
  }
71
  global $wpdb;
72
  $contactsArray = array();
73
 
74
+ // Get contacts.
75
  $contactsQuery = 'SELECT * FROM wp_ce4wp_contacts';
76
  $contactsResult = $wpdb->get_results($wpdb->prepare($contactsQuery));
77
 
78
  foreach ($contactsResult as $contact) {
 
79
  try {
80
+ $contact = $this->convertToContactModel(json_decode(
81
+ (string) json_encode($contact),
82
+ true)
83
+ );
84
  if (!empty($contact->getEmail())) {
85
  array_push($contactsArray, $contact);
86
  }
87
 
88
+ } catch (Exception $exception) {
89
  RaygunManager::get_instance()->exception_handler($exception);
90
  continue;
91
  }
src/Modules/Contacts/Handlers/FormidablePluginHandler.php CHANGED
@@ -7,6 +7,10 @@ define('CE4WP_FRM_EVENTTYPE', 'WordPress - Formidable');
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
 
 
 
 
10
 
11
  class FormidablePluginHandler extends BaseContactFormPluginHandler
12
  {
@@ -75,7 +79,7 @@ class FormidablePluginHandler extends BaseContactFormPluginHandler
75
  {
76
  try {
77
  //map entry values to the field meta
78
- $entry = \FrmField::get_all_for_form($form_id);
79
  $entryFieldData = $_POST["item_meta"];
80
  foreach ($entry as $field) {
81
  if (!empty($entryFieldData[$field->id])) {
@@ -84,7 +88,7 @@ class FormidablePluginHandler extends BaseContactFormPluginHandler
84
  $field->fieldName = $field->name;
85
  }
86
  }
87
- $formidableContact = new \stdClass();
88
 
89
  //Convert to contactModel
90
  $this->FindEntryValues($entry, $formidableContact);
@@ -93,7 +97,7 @@ class FormidablePluginHandler extends BaseContactFormPluginHandler
93
  return;
94
  }
95
  $this->upsertContact($this->convertToContactModel($formidableContact));
96
- } catch (\Exception $exception) {
97
  RaygunManager::get_instance()->exception_handler($exception);
98
  }
99
  }
@@ -118,42 +122,44 @@ class FormidablePluginHandler extends BaseContactFormPluginHandler
118
  global $wpdb;
119
  $contactsArray = array();
120
 
121
- $forms = \FrmForm::getAll();
122
- foreach ($forms as $form) {
123
- $entriesQuery = "SELECT e.item_id AS entryId, e.meta_value AS entryValue, f.name AS fieldName, f.description AS fieldDescription, f.type AS fieldType
124
- FROM wp_frm_item_metas e
125
- INNER JOIN wp_frm_fields f ON f.id = e.field_id WHERE f.form_id = {$form->id} ORDER BY e.item_id";
 
126
 
127
- $entryResults = $wpdb->get_results($wpdb->prepare($entriesQuery));
128
- if (empty($entryResults)) {
129
- continue;
130
- }
131
-
132
- $mappedEntries = $this->CombineEntryData($entryResults);
133
-
134
- //Get the contact data for each entry
135
- foreach ($mappedEntries as $entry) {
136
- $formidableContact = new \stdClass();
137
-
138
- //Convert to contactModel
139
- $this->FindEntryValues($entry, $formidableContact);
140
-
141
- if (empty($formidableContact->email)) {
142
  continue;
143
  }
144
- $formidableContact->isSync = true;
145
- try {
146
- $contactModel = null;
147
- $contactModel = $this->convertToContactModel($formidableContact);
148
- } catch (\Exception $exception) {
149
- RaygunManager::get_instance()->exception_handler($exception);
150
- continue;
151
- }
152
- if (!empty($contactModel->email)) {
153
- array_push($contactsArray, $contactModel);
154
- }
155
- if (isset($limit) && count($contactsArray) >= $limit) {
156
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
158
  }
159
  }
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
10
+ use Exception;
11
+ use FrmField; // Formidable Field Class
12
+ use FrmForm; // Formidable Forms Class
13
+ use stdClass;
14
 
15
  class FormidablePluginHandler extends BaseContactFormPluginHandler
16
  {
79
  {
80
  try {
81
  //map entry values to the field meta
82
+ $entry = FrmField::get_all_for_form($form_id);
83
  $entryFieldData = $_POST["item_meta"];
84
  foreach ($entry as $field) {
85
  if (!empty($entryFieldData[$field->id])) {
88
  $field->fieldName = $field->name;
89
  }
90
  }
91
+ $formidableContact = new stdClass();
92
 
93
  //Convert to contactModel
94
  $this->FindEntryValues($entry, $formidableContact);
97
  return;
98
  }
99
  $this->upsertContact($this->convertToContactModel($formidableContact));
100
+ } catch (Exception $exception) {
101
  RaygunManager::get_instance()->exception_handler($exception);
102
  }
103
  }
122
  global $wpdb;
123
  $contactsArray = array();
124
 
125
+ $forms = FrmForm::getAll();
126
+ if (is_array($forms)) {
127
+ foreach ($forms as $form) {
128
+ $entriesQuery = "SELECT e.item_id AS entryId, e.meta_value AS entryValue, f.name AS fieldName, f.description AS fieldDescription, f.type AS fieldType
129
+ FROM wp_frm_item_metas e
130
+ INNER JOIN wp_frm_fields f ON f.id = e.field_id WHERE f.form_id = {$form->id} ORDER BY e.item_id";
131
 
132
+ $entryResults = $wpdb->get_results($wpdb->prepare($entriesQuery));
133
+ if (empty($entryResults)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  continue;
135
  }
136
+
137
+ $mappedEntries = $this->CombineEntryData($entryResults);
138
+
139
+ // Get the contact data for each entry.
140
+ foreach ($mappedEntries as $entry) {
141
+ $formidableContact = new stdClass();
142
+
143
+ // Convert to contactModel.
144
+ $this->FindEntryValues($entry, $formidableContact);
145
+
146
+ if (empty($formidableContact->email)) {
147
+ continue;
148
+ }
149
+ $formidableContact->isSync = true;
150
+ try {
151
+ $contactModel = null;
152
+ $contactModel = $this->convertToContactModel($formidableContact);
153
+ } catch (Exception $exception) {
154
+ RaygunManager::get_instance()->exception_handler($exception);
155
+ continue;
156
+ }
157
+ if (!empty($contactModel->email)) {
158
+ array_push($contactsArray, $contactModel);
159
+ }
160
+ if (isset($limit) && count($contactsArray) >= $limit) {
161
+ break;
162
+ }
163
  }
164
  }
165
  }
src/Modules/Contacts/Handlers/GravityFormsPluginHandler.php CHANGED
@@ -7,6 +7,7 @@ define('CE4WP_GF_EVENTTYPE', 'WordPress - GravityForms');
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
 
10
 
11
  class GravityFormsPluginHandler extends BaseContactFormPluginHandler
12
  {
@@ -18,12 +19,13 @@ class GravityFormsPluginHandler extends BaseContactFormPluginHandler
18
 
19
  $contactModel->setEventType(CE4WP_GF_EVENTTYPE);
20
 
21
- if ($user->isSync) { //If its a DB sync we set optin on true, action by owner
 
22
  $contactModel->setOptIn(true);
23
  $contactModel->setOptOut(false);
24
  $contactModel->setOptActionBy(OptActionBy::Owner);
25
  } else {
26
- //Get contact data from submission
27
  $contactModel->setOptIn(boolval($user->consent));
28
  $contactModel->setOptActionBy(OptActionBy::Visitor);
29
  }
@@ -58,25 +60,25 @@ class GravityFormsPluginHandler extends BaseContactFormPluginHandler
58
  }
59
 
60
  /**
61
- * Gets the first name, optional insertion and last name from the contactform
62
  *
63
  * @param $entry (The form submission)
64
  * @param $form (The form used)
65
  *
66
- * @return string (concatenated firstname, insertion and lastname) Returns the concatenated name
67
  */
68
  private function GetNameValuesFromForm($entry, $form)
69
  {
70
- $nameValues = array();
71
  foreach ($form['fields'] as $field) {
72
  if ($field["type"] == "name") {
73
  $values = $field["inputs"];
74
- $nameValues["firstName"] = rgar($entry, $values[1]["id"]); //first name
75
- $nameValues["insertion"] = rgar($entry, $values[2]["id"]); //insertion
76
- $nameValues["lastName"] = rgar($entry, $values[3]["id"]); //last name
77
  }
78
  }
79
- return $nameValues;
80
  }
81
 
82
  /**
@@ -92,7 +94,7 @@ class GravityFormsPluginHandler extends BaseContactFormPluginHandler
92
  private function GetEmailFromForm($entry, $form)
93
  {
94
  $email = null;
95
- //Check for email type in form
96
  foreach ($form['fields'] as $field) {
97
  if ($field["type"] == "email") {
98
  $email = rgar($entry, $field["id"]);
@@ -102,7 +104,7 @@ class GravityFormsPluginHandler extends BaseContactFormPluginHandler
102
  }
103
  }
104
  }
105
- //Else check if we can find an email value in text fields
106
  foreach ($form['fields'] as $field) {
107
  if (in_array(strtolower($field["type"]), $this->textFormFields) && in_array(strtolower($field["label"]), $this->emailFields)) {
108
  $possibleEmail = rgar($entry, $field["id"]);
@@ -140,7 +142,7 @@ class GravityFormsPluginHandler extends BaseContactFormPluginHandler
140
 
141
  $contact->isSync = false;
142
  $this->upsertContact($this->convertToContactModel($contact));
143
- } catch (\Exception $exception) {
144
  RaygunManager::get_instance()->exception_handler($exception);
145
  }
146
  }
@@ -202,11 +204,11 @@ class GravityFormsPluginHandler extends BaseContactFormPluginHandler
202
  $this->FindFormData($contact, $entry, $formArray);
203
  $contact->isSync = true;
204
 
205
- //Convert to contactModel
206
  $contactModel = null;
207
  try {
208
  $contactModel = $this->convertToContactModel($contact);
209
- } catch (\Exception $exception) {
210
  RaygunManager::get_instance()->exception_handler($exception);
211
  continue;
212
  }
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
10
+ use Exception;
11
 
12
  class GravityFormsPluginHandler extends BaseContactFormPluginHandler
13
  {
19
 
20
  $contactModel->setEventType(CE4WP_GF_EVENTTYPE);
21
 
22
+ // If it's a DB sync we set optin on true, action by owner.
23
+ if ($user->isSync) {
24
  $contactModel->setOptIn(true);
25
  $contactModel->setOptOut(false);
26
  $contactModel->setOptActionBy(OptActionBy::Owner);
27
  } else {
28
+ // Get contact data from submission.
29
  $contactModel->setOptIn(boolval($user->consent));
30
  $contactModel->setOptActionBy(OptActionBy::Visitor);
31
  }
60
  }
61
 
62
  /**
63
+ * Gets the first name, optional insertion and last name from the Contact Form
64
  *
65
  * @param $entry (The form submission)
66
  * @param $form (The form used)
67
  *
68
+ * @return array (concatenated firstname, insertion and lastname) Returns the concatenated name
69
  */
70
  private function GetNameValuesFromForm($entry, $form)
71
  {
72
+ $name_values = array();
73
  foreach ($form['fields'] as $field) {
74
  if ($field["type"] == "name") {
75
  $values = $field["inputs"];
76
+ $name_values["firstName"] = rgar($entry, $values[1]["id"]);
77
+ $name_values["insertion"] = rgar($entry, $values[2]["id"]);
78
+ $name_values["lastName"] = rgar($entry, $values[3]["id"]);
79
  }
80
  }
81
+ return $name_values;
82
  }
83
 
84
  /**
94
  private function GetEmailFromForm($entry, $form)
95
  {
96
  $email = null;
97
+ // Check for email type in form.
98
  foreach ($form['fields'] as $field) {
99
  if ($field["type"] == "email") {
100
  $email = rgar($entry, $field["id"]);
104
  }
105
  }
106
  }
107
+ // Else check if we can find an email value in text fields.
108
  foreach ($form['fields'] as $field) {
109
  if (in_array(strtolower($field["type"]), $this->textFormFields) && in_array(strtolower($field["label"]), $this->emailFields)) {
110
  $possibleEmail = rgar($entry, $field["id"]);
142
 
143
  $contact->isSync = false;
144
  $this->upsertContact($this->convertToContactModel($contact));
145
+ } catch (Exception $exception) {
146
  RaygunManager::get_instance()->exception_handler($exception);
147
  }
148
  }
204
  $this->FindFormData($contact, $entry, $formArray);
205
  $contact->isSync = true;
206
 
207
+ //Convert to contactModel.
208
  $contactModel = null;
209
  try {
210
  $contactModel = $this->convertToContactModel($contact);
211
+ } catch (Exception $exception) {
212
  RaygunManager::get_instance()->exception_handler($exception);
213
  continue;
214
  }
src/Modules/Contacts/Handlers/NinjaFormsPluginHandler.php CHANGED
@@ -7,6 +7,8 @@ define('CE4WP_NF_EVENTTYPE', 'WordPress - NinjaForms');
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
 
 
10
 
11
  class NinjaFormsPluginHandler extends BaseContactFormPluginHandler
12
  {
@@ -117,7 +119,7 @@ class NinjaFormsPluginHandler extends BaseContactFormPluginHandler
117
  public function ceHandleNinjaFormSubmission($form_data)
118
  {
119
  try {
120
- $ninjaContact = new \stdClass();
121
  $this->FindFormValues($ninjaContact, $form_data["fields_by_key"]);
122
  if (empty($ninjaContact->email)) {
123
  return;
@@ -125,7 +127,7 @@ class NinjaFormsPluginHandler extends BaseContactFormPluginHandler
125
  $ninjaContact->name = $this->getNameFromForm($form_data["fields_by_key"]);
126
  $ninjaContact->opt_in = false;
127
  $this->upsertContact($this->convertToContactModel($ninjaContact));
128
- } catch (\Exception $exception) {
129
  RaygunManager::get_instance()->exception_handler($exception);
130
  }
131
  }
@@ -142,103 +144,112 @@ class NinjaFormsPluginHandler extends BaseContactFormPluginHandler
142
 
143
  public function get_contacts($limit = null)
144
  {
 
 
 
145
  if (!is_int($limit) || $limit <= 0) {
146
  $limit = null;
147
  }
148
  try {
149
- // Relies on plugin => NinjaForms
150
  if (in_array('ninja-forms/ninja-forms.php', apply_filters('active_plugins', get_option('active_plugins')))) {
151
-
152
  $contactsArray = array();
153
-
154
- // Get an array of Form Models for All Forms
155
  $forms = Ninja_Forms()->form()->get_forms();
156
- foreach ($forms as $form) {
157
- $formId = $form->get_id();
158
- // Get all form fields and submissions for the form
159
- $fields = Ninja_Forms()->form($formId)->get_fields();
160
- $submissions = Ninja_Forms()->form($formId)->get_subs();
161
- foreach ($submissions as $submission) {
162
- $contact = new \stdClass();
163
- // Get all values for a submission
164
- $field_values = $submission->get_field_values();
165
- foreach ($fields as $field) {
166
- // Get field settings so we can map the values with it's field type
167
- $field_settings = $field->get_settings();
168
- $field_key = $field_settings["key"];
169
- $field_type = $field_settings["type"];
170
- $field_value = isset($field_values[$field_key]) ? $field_values[$field_key] : null; //this prevents undefined index on altered forms
171
-
172
- switch ($field_type) {
173
- case 'email';
174
- $email = $field_value;
175
- if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
176
- $contact->email = $email;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  }
178
- break;
179
- case 'phone';
180
- $contact->phone = $field_value;
181
- break;
182
- case 'date';
183
- if (in_array(strtolower($field_settings['label']), $this->birthdayFields)) {
184
- $contact->birthday = $field_value;
 
 
 
 
 
 
 
 
 
 
185
  }
186
- break;
187
- case 'name';
188
- case 'full_name';
189
- $contact->name = $field_value;
190
- break;
191
- case 'firstname';
192
- case 'first_name';
193
- $contact->firstName = $field_value;
194
- break;
195
- case 'lastname';
196
- case 'last_name';
197
- $contact->lastName = $field_value;
198
- break;
199
- case 'textbox';
200
- case 'text';
201
- if (empty($contact->name) && (empty($contact->firstName) || empty($contact->lastName))) {
202
- $this->attemptAdditionalNameExtraction($contact, $field_key, $field_values);
203
  }
204
- break;
205
- default;
206
- break;
207
- }
208
- }
209
-
210
- if (!empty($contact->email) && $contact->email != null) {
211
- //set optin by owner on db sync
212
- $contact->optinByOwner = true;
213
- $contact->opt_in = true;
214
-
215
- //Convert to contactModel and push to the array
216
- $contactModel = null;
217
- try {
218
- $contactModel = $this->convertToContactModel($contact);
219
- if (!empty($contactModel->getEmail())) {
220
- array_push($contactsArray, $contactModel);
221
  }
222
- } catch (\Exception $exception) {
223
- RaygunManager::get_instance()->exception_handler($exception);
224
- continue;
225
- }
226
- if (isset($limit) && count($contactsArray) >= $limit) {
227
- break;
228
  }
229
  }
230
- }
231
- if (isset($limit) && count($contactsArray) >= $limit) {
232
- break;
233
  }
234
  }
235
 
236
- //upsert the contacts
237
  if (!empty($contactsArray)) {
238
  return $contactsArray;
239
  }
240
  }
241
- } catch (\Exception $exception) {
242
  RaygunManager::get_instance()->exception_handler($exception);
243
  }
244
 
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Models\ContactModel;
9
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
10
+ use Exception;
11
+ use stdClass;
12
 
13
  class NinjaFormsPluginHandler extends BaseContactFormPluginHandler
14
  {
119
  public function ceHandleNinjaFormSubmission($form_data)
120
  {
121
  try {
122
+ $ninjaContact = new stdClass();
123
  $this->FindFormValues($ninjaContact, $form_data["fields_by_key"]);
124
  if (empty($ninjaContact->email)) {
125
  return;
127
  $ninjaContact->name = $this->getNameFromForm($form_data["fields_by_key"]);
128
  $ninjaContact->opt_in = false;
129
  $this->upsertContact($this->convertToContactModel($ninjaContact));
130
+ } catch (Exception $exception) {
131
  RaygunManager::get_instance()->exception_handler($exception);
132
  }
133
  }
144
 
145
  public function get_contacts($limit = null)
146
  {
147
+ $fields = null;
148
+ $submissions = null;
149
+
150
  if (!is_int($limit) || $limit <= 0) {
151
  $limit = null;
152
  }
153
  try {
154
+ // Relies on plugin => NinjaForms.
155
  if (in_array('ninja-forms/ninja-forms.php', apply_filters('active_plugins', get_option('active_plugins')))) {
 
156
  $contactsArray = array();
157
+ // Get an array of Form Models for All Forms.
 
158
  $forms = Ninja_Forms()->form()->get_forms();
159
+ if ( is_array($forms) ) {
160
+ foreach ($forms as $form) {
161
+ $formId = $form->get_id();
162
+ // Get all form fields and submissions for the form.
163
+ if (!empty($formId)) {
164
+ $fields = Ninja_Forms()->form($formId)->get_fields();
165
+ $submissions = Ninja_Forms()->form($formId)->get_subs();
166
+ }
167
+ if (!empty($submissions)) {
168
+ foreach ($submissions as $submission) {
169
+ $contact = new stdClass();
170
+ // Get all values for a submission.
171
+ $field_values = $submission->get_field_values();
172
+
173
+ if (!empty($fields)) {
174
+ foreach ($fields as $field) {
175
+ // Get field settings, so we can map the values with its field type.
176
+ $field_settings = $field->get_settings();
177
+ $field_key = $field_settings["key"];
178
+ $field_type = $field_settings["type"];
179
+ $field_value = $field_values[$field_key] ?? null; // This prevents undefined index on altered forms.
180
+ switch ($field_type) {
181
+ case 'email';
182
+ $email = $field_value;
183
+ if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
184
+ $contact->email = $email;
185
+ }
186
+ break;
187
+ case 'phone';
188
+ $contact->phone = $field_value;
189
+ break;
190
+ case 'date';
191
+ if (in_array(strtolower($field_settings['label']), $this->birthdayFields)) {
192
+ $contact->birthday = $field_value;
193
+ }
194
+ break;
195
+ case 'name';
196
+ case 'full_name';
197
+ $contact->name = $field_value;
198
+ break;
199
+ case 'firstname';
200
+ case 'first_name';
201
+ $contact->firstName = $field_value;
202
+ break;
203
+ case 'lastname';
204
+ case 'last_name';
205
+ $contact->lastName = $field_value;
206
+ break;
207
+ case 'textbox';
208
+ case 'text';
209
+ if (empty($contact->name) && (empty($contact->firstName) || empty($contact->lastName))) {
210
+ $this->attemptAdditionalNameExtraction($contact, $field_key, $field_values);
211
+ }
212
+ break;
213
+ default;
214
+ break;
215
+ }
216
  }
217
+ }
218
+
219
+ if (!empty($contact->email) && $contact->email != null) {
220
+ // Set optin by owner on db sync.
221
+ $contact->optinByOwner = true;
222
+ $contact->opt_in = true;
223
+
224
+ // Convert to contactModel and push to the array.
225
+ $contactModel = null;
226
+ try {
227
+ $contactModel = $this->convertToContactModel($contact);
228
+ if (!empty($contactModel->getEmail())) {
229
+ array_push($contactsArray, $contactModel);
230
+ }
231
+ } catch (Exception $exception) {
232
+ RaygunManager::get_instance()->exception_handler($exception);
233
+ continue;
234
  }
235
+ if (isset($limit) && count($contactsArray) >= $limit) {
236
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  }
 
 
 
 
 
 
239
  }
240
  }
241
+ if (isset($limit) && count($contactsArray) >= $limit) {
242
+ break;
243
+ }
244
  }
245
  }
246
 
247
+ // Upsert the contacts.
248
  if (!empty($contactsArray)) {
249
  return $contactsArray;
250
  }
251
  }
252
+ } catch (Exception $exception) {
253
  RaygunManager::get_instance()->exception_handler($exception);
254
  }
255
 
src/Modules/Contacts/Handlers/WooCommercePluginHandler.php CHANGED
@@ -13,6 +13,7 @@ define('CE4WP_WC_EVENTTYPE', 'WordPress - WooCommerce');
13
  use CreativeMail\Managers\RaygunManager;
14
  use CreativeMail\Modules\Contacts\Models\ContactAddressModel;
15
  use CreativeMail\Modules\Contacts\Models\ContactModel;
 
16
 
17
  class WooCommercePluginHandler extends BaseContactFormPluginHandler
18
  {
@@ -23,10 +24,16 @@ class WooCommercePluginHandler extends BaseContactFormPluginHandler
23
 
24
  public function convertToContactModel($orderId)
25
  {
 
26
  $contactModel = new ContactModel();
27
  $products_detail = get_post_meta($orderId);
28
  $order = wc_get_order($orderId);
29
- $number_of_orders = count(wc_get_orders(array('email' => $order->get_billing_email())));
 
 
 
 
 
30
 
31
  if (isset($products_detail)) {
32
  if (!empty($products_detail["_billing_email"]) && isset($products_detail["_billing_email"][0]) && !empty($products_detail["_billing_email"][0])) {
@@ -124,8 +131,10 @@ class WooCommercePluginHandler extends BaseContactFormPluginHandler
124
  {
125
  try {
126
  $order = wc_get_order($order_id);
127
- $this->upsertContact($this->convertToContactModel($order->ID));
128
- } catch (\Exception $exception) {
 
 
129
  RaygunManager::get_instance()->exception_handler($exception);
130
  }
131
  }
@@ -166,7 +175,7 @@ class WooCommercePluginHandler extends BaseContactFormPluginHandler
166
  try {
167
  $this->isSync = true;
168
  $contactModel = $this->convertToContactModel($products_order->ID);
169
- } catch (\Exception $exception) {
170
  // silent exception
171
  continue;
172
  }
13
  use CreativeMail\Managers\RaygunManager;
14
  use CreativeMail\Modules\Contacts\Models\ContactAddressModel;
15
  use CreativeMail\Modules\Contacts\Models\ContactModel;
16
+ use Exception;
17
 
18
  class WooCommercePluginHandler extends BaseContactFormPluginHandler
19
  {
24
 
25
  public function convertToContactModel($orderId)
26
  {
27
+ $all_orders = null;
28
  $contactModel = new ContactModel();
29
  $products_detail = get_post_meta($orderId);
30
  $order = wc_get_order($orderId);
31
+
32
+ if (is_object($order) && is_a($order, 'WC_Order')) {
33
+ $all_orders = wc_get_orders(array('email' => $order->get_billing_email()));
34
+ }
35
+
36
+ $number_of_orders = count(is_array($all_orders) ? $all_orders : array());
37
 
38
  if (isset($products_detail)) {
39
  if (!empty($products_detail["_billing_email"]) && isset($products_detail["_billing_email"][0]) && !empty($products_detail["_billing_email"][0])) {
131
  {
132
  try {
133
  $order = wc_get_order($order_id);
134
+ if (is_object($order) && is_a($order, 'WC_Order')) {
135
+ $this->upsertContact($this->convertToContactModel($order->get_id()));
136
+ }
137
+ } catch (Exception $exception) {
138
  RaygunManager::get_instance()->exception_handler($exception);
139
  }
140
  }
175
  try {
176
  $this->isSync = true;
177
  $contactModel = $this->convertToContactModel($products_order->ID);
178
+ } catch (Exception $exception) {
179
  // silent exception
180
  continue;
181
  }
src/Modules/Contacts/Handlers/WpFormsPluginHandler.php CHANGED
@@ -8,6 +8,7 @@ define('CE4WP_WPF_EVENTTYPE', 'WordPress - WPForms');
8
  use CreativeMail\Managers\RaygunManager;
9
  use CreativeMail\Modules\Contacts\Models\ContactModel;
10
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
 
11
  use function Sodium\add;
12
 
13
  class WpFormsPluginHandler extends BaseContactFormPluginHandler
@@ -65,11 +66,13 @@ class WpFormsPluginHandler extends BaseContactFormPluginHandler
65
  if(empty($contactModel -> firstName) && empty($contactModel -> lastName) && !empty($nameField) && !empty($nameField['value']))
66
  {
67
  $nameValues = preg_split ('/ /', $nameField['value']);
68
- $arrLength = count($nameValues);
69
- $contactModel->setFirstName($nameValues[0]);
70
- if($arrLength > 1)
71
- {
72
- $contactModel->setLastName($nameValues[$arrLength - 1]);
 
 
73
  }
74
  }
75
 
@@ -88,7 +91,7 @@ class WpFormsPluginHandler extends BaseContactFormPluginHandler
88
  }
89
 
90
  $consentField = $this->get_form_type_field($formData, "gdpr-checkbox");
91
- if (!empty($consentField) && array_key_exists('value', $consentField) && $consentField) {
92
  //If a gdpr checkbox is present it is required before submitting
93
  //The value is a string like "I consent to having this website store my information . . . " instead of a bool
94
  //Will assume people won't alter or change this to be the other way around so having this value == consent
@@ -103,14 +106,14 @@ class WpFormsPluginHandler extends BaseContactFormPluginHandler
103
  {
104
  try {
105
  $this->upsertContact($this->convertToContactModel($fields));
106
- } catch (\Exception $exception) {
107
  RaygunManager::get_instance()->exception_handler($exception);
108
  }
109
  }
110
 
111
  public function registerHooks()
112
  {
113
- // https://wpforms.com/developers/wpforms_process_complete/
114
  add_action('wpforms_process_complete', array($this, 'ceHandleWpFormsProcessComplete'), 10, 4);
115
  }
116
 
@@ -125,20 +128,19 @@ class WpFormsPluginHandler extends BaseContactFormPluginHandler
125
  $limit = null;
126
  }
127
 
128
- // Relies on plugin => wpforms paid or pro
129
  if (in_array('wpforms/wpforms.php', apply_filters('active_plugins', get_option('active_plugins')))
130
  || in_array('wpforms-lite/wpforms.php', apply_filters('active_plugins', get_option('active_plugins')))
131
- ) { //this is a guess, have to test first
132
-
133
- //Get form submissions from the wpforms db
134
  global $wpdb;
135
  $contactsArray = array();
136
 
137
- //get the form entries
138
  $entriesQuery = 'SELECT fields FROM wp_wpforms_entries';
139
  $entryResult = $wpdb->get_results($wpdb->prepare($entriesQuery));
140
 
141
- //Loop through entries and create the contacts
142
  foreach ($entryResult as $entry) {
143
  $contactModel = null;
144
  try {
@@ -147,8 +149,7 @@ class WpFormsPluginHandler extends BaseContactFormPluginHandler
147
  if (!empty($contact->getEmail())) {
148
  array_push($contactsArray, $contact);
149
  }
150
-
151
- } catch (\Exception $exception) {
152
  RaygunManager::get_instance()->exception_handler($exception);
153
  continue;
154
  }
8
  use CreativeMail\Managers\RaygunManager;
9
  use CreativeMail\Modules\Contacts\Models\ContactModel;
10
  use CreativeMail\Modules\Contacts\Models\OptActionBy;
11
+ use Exception;
12
  use function Sodium\add;
13
 
14
  class WpFormsPluginHandler extends BaseContactFormPluginHandler
66
  if(empty($contactModel -> firstName) && empty($contactModel -> lastName) && !empty($nameField) && !empty($nameField['value']))
67
  {
68
  $nameValues = preg_split ('/ /', $nameField['value']);
69
+ if (!empty($nameValues)) {
70
+ $arrLength = count($nameValues);
71
+ $contactModel->setFirstName($nameValues[0]);
72
+
73
+ if($arrLength > 1) {
74
+ $contactModel->setLastName($nameValues[$arrLength - 1]);
75
+ }
76
  }
77
  }
78
 
91
  }
92
 
93
  $consentField = $this->get_form_type_field($formData, "gdpr-checkbox");
94
+ if (!empty($consentField) && array_key_exists('value', $consentField)) {
95
  //If a gdpr checkbox is present it is required before submitting
96
  //The value is a string like "I consent to having this website store my information . . . " instead of a bool
97
  //Will assume people won't alter or change this to be the other way around so having this value == consent
106
  {
107
  try {
108
  $this->upsertContact($this->convertToContactModel($fields));
109
+ } catch (Exception $exception) {
110
  RaygunManager::get_instance()->exception_handler($exception);
111
  }
112
  }
113
 
114
  public function registerHooks()
115
  {
116
+ // https://wpforms.com/developers/wpforms_process_complete/ .
117
  add_action('wpforms_process_complete', array($this, 'ceHandleWpFormsProcessComplete'), 10, 4);
118
  }
119
 
128
  $limit = null;
129
  }
130
 
131
+ // Relies on plugin => WpForms paid or pro.
132
  if (in_array('wpforms/wpforms.php', apply_filters('active_plugins', get_option('active_plugins')))
133
  || in_array('wpforms-lite/wpforms.php', apply_filters('active_plugins', get_option('active_plugins')))
134
+ ) {
135
+ // Get form submissions from the WpForms DB.
 
136
  global $wpdb;
137
  $contactsArray = array();
138
 
139
+ // Get the form entries.
140
  $entriesQuery = 'SELECT fields FROM wp_wpforms_entries';
141
  $entryResult = $wpdb->get_results($wpdb->prepare($entriesQuery));
142
 
143
+ // Loop through entries and create the contacts.
144
  foreach ($entryResult as $entry) {
145
  $contactModel = null;
146
  try {
149
  if (!empty($contact->getEmail())) {
150
  array_push($contactsArray, $contact);
151
  }
152
+ } catch (Exception $exception) {
 
153
  RaygunManager::get_instance()->exception_handler($exception);
154
  continue;
155
  }
src/Modules/Contacts/Managers/ContactsSyncManager.php CHANGED
@@ -11,7 +11,6 @@ class ContactsSyncManager
11
  public function __construct()
12
  {
13
  $this->contacts_sync_background_processor = new ContactsSyncBackgroundProcessor();
14
-
15
  add_action(CE4WP_SYNCHRONIZE_ACTION, array($this, 'publish_contact_sync_request'));
16
  }
17
 
@@ -23,7 +22,6 @@ class ContactsSyncManager
23
  public function publish_contact_sync_request()
24
  {
25
  $this->contacts_sync_background_processor->push_to_queue(null);
26
-
27
  // Start the queue.
28
  $this->contacts_sync_background_processor->save()->dispatch();
29
  }
11
  public function __construct()
12
  {
13
  $this->contacts_sync_background_processor = new ContactsSyncBackgroundProcessor();
 
14
  add_action(CE4WP_SYNCHRONIZE_ACTION, array($this, 'publish_contact_sync_request'));
15
  }
16
 
22
  public function publish_contact_sync_request()
23
  {
24
  $this->contacts_sync_background_processor->push_to_queue(null);
 
25
  // Start the queue.
26
  $this->contacts_sync_background_processor->save()->dispatch();
27
  }
src/Modules/Contacts/Models/ContactModel.php CHANGED
@@ -194,7 +194,7 @@ class ContactModel
194
  );
195
 
196
  $address = $this->getContactAddress();
197
- if(isset($address)) {
198
  $result["addresses"] = array($address->toArray());
199
  }
200
 
194
  );
195
 
196
  $address = $this->getContactAddress();
197
+ if( $address != null ) {
198
  $result["addresses"] = array($address->toArray());
199
  }
200
 
src/Modules/Contacts/Processors/ContactsSyncBackgroundProcessor.php CHANGED
@@ -7,7 +7,9 @@ use CreativeMail\Managers\IntegrationManager;
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Services\ContactsSyncService;
9
  use CreativeMail\Integrations\Integration;
 
10
  use ReflectionClass;
 
11
  use WP_Background_Process;
12
 
13
  class ContactsSyncBackgroundProcessor extends WP_Background_Process
@@ -22,9 +24,9 @@ class ContactsSyncBackgroundProcessor extends WP_Background_Process
22
  * in the next pass through. Or, return false to remove the
23
  * item from the queue.
24
  *
25
- * @param mixed
26
  *
27
- * @return mixed
28
  */
29
  protected function task($item)
30
  {
@@ -33,10 +35,10 @@ class ContactsSyncBackgroundProcessor extends WP_Background_Process
33
  $integrationManager = new IntegrationManager();
34
  $activated_integrations = $integrationManager->get_activated_integrations();
35
 
36
- if (isset($activated_integrations) && !empty($activated_integrations)) {
37
  $this->start_contacts_sync_for_all_integrations($activated_integrations);
38
  }
39
- } catch (\Exception $exception) {
40
  RaygunManager::get_instance()->exception_handler($exception);
41
  }
42
 
@@ -47,33 +49,35 @@ class ContactsSyncBackgroundProcessor extends WP_Background_Process
47
  * Starts the contacts sync for all the activated plugins
48
  *
49
  * @param Integration[] $activated_integrations
 
 
50
  */
51
  private function start_contacts_sync_for_all_integrations($activated_integrations)
52
  {
 
 
53
  if (!ValidationHelper::is_null_or_empty($activated_integrations)) {
54
  // todo throw exception
55
  }
56
 
57
- $total_contacts = array();
58
-
59
- // get all contacts
60
  foreach ($activated_integrations as $activated_integration) {
61
-
62
  $class = new ReflectionClass($activated_integration->get_integration_handler());
63
  $plugin_handler = $class->newInstance();
64
- $plugin_contacts = $plugin_handler->get_contacts(null);
 
 
65
  if (isset($plugin_contacts) && !empty($plugin_contacts)) {
66
  foreach ($plugin_contacts as $plugin_contact) {
67
- array_push($total_contacts, $plugin_contact);
68
  }
69
  }
70
  }
71
 
72
  if (!empty($total_contacts)) {
73
- // start contact sync
74
-
75
  $contactSyncService = new ContactsSyncService();
76
  $contactSyncService->upsertContacts($total_contacts);
77
  }
78
  }
79
- }
7
  use CreativeMail\Managers\RaygunManager;
8
  use CreativeMail\Modules\Contacts\Services\ContactsSyncService;
9
  use CreativeMail\Integrations\Integration;
10
+ use Exception;
11
  use ReflectionClass;
12
+ use ReflectionException;
13
  use WP_Background_Process;
14
 
15
  class ContactsSyncBackgroundProcessor extends WP_Background_Process
24
  * in the next pass through. Or, return false to remove the
25
  * item from the queue.
26
  *
27
+ * @param mixed $item
28
  *
29
+ * @return false
30
  */
31
  protected function task($item)
32
  {
35
  $integrationManager = new IntegrationManager();
36
  $activated_integrations = $integrationManager->get_activated_integrations();
37
 
38
+ if (!empty($activated_integrations)) {
39
  $this->start_contacts_sync_for_all_integrations($activated_integrations);
40
  }
41
+ } catch (Exception $exception) {
42
  RaygunManager::get_instance()->exception_handler($exception);
43
  }
44
 
49
  * Starts the contacts sync for all the activated plugins
50
  *
51
  * @param Integration[] $activated_integrations
52
+ *
53
+ * @throws ReflectionException
54
  */
55
  private function start_contacts_sync_for_all_integrations($activated_integrations)
56
  {
57
+ $total_contacts = array();
58
+
59
  if (!ValidationHelper::is_null_or_empty($activated_integrations)) {
60
  // todo throw exception
61
  }
62
 
63
+ // Get all contacts.
 
 
64
  foreach ($activated_integrations as $activated_integration) {
 
65
  $class = new ReflectionClass($activated_integration->get_integration_handler());
66
  $plugin_handler = $class->newInstance();
67
+ if (method_exists($plugin_handler, 'get_contacts')) {
68
+ $plugin_contacts = $plugin_handler->get_contacts(null);
69
+ }
70
  if (isset($plugin_contacts) && !empty($plugin_contacts)) {
71
  foreach ($plugin_contacts as $plugin_contact) {
72
+ $total_contacts[] = $plugin_contact;
73
  }
74
  }
75
  }
76
 
77
  if (!empty($total_contacts)) {
78
+ // Start contact sync.
 
79
  $contactSyncService = new ContactsSyncService();
80
  $contactSyncService->upsertContacts($total_contacts);
81
  }
82
  }
83
+ }
src/Modules/Contacts/Services/ContactsSyncService.php CHANGED
@@ -50,7 +50,7 @@ class ContactsSyncService
50
 
51
  public function upsertContact(ContactModel $contactModel)
52
  {
53
- if(!isset($contactModel)) {
54
  return false;
55
  }
56
 
@@ -126,19 +126,20 @@ class ContactsSyncService
126
  // todo throw exception
127
  }
128
 
129
- // 1. convert to csv file
130
  $csv_file = $this->create_csv_file($contactModels);
131
- // 2. request sas model (with url and uuid)
132
  $sas_request_model = $this->request_sas_model();
133
- // 3. upload csv file using sas url
134
  $this->upload_csv_file($csv_file, $sas_request_model->url);
135
- // 4. call endpoint to start import (using uuid)
136
  $this->start_import_for_uuid($sas_request_model->uuid);
137
 
138
  }
139
 
140
  private function create_csv_file($contactModels)
141
  {
 
142
  if (ValidationHelper::is_null_or_empty($contactModels)) {
143
  // todo throw exception
144
  }
@@ -151,13 +152,17 @@ class ContactsSyncService
151
  foreach($contactModels as $contactModel) {
152
  $contact_fields_array = $this->convert_contact_to_csv_array($contactModel);
153
  if (!ValidationHelper::is_null_or_empty($contact_fields_array)) {
154
- fputcsv($fd, $contact_fields_array);
 
 
155
  }
156
  }
157
 
158
- rewind($fd);
159
- $csv_content = stream_get_contents($fd);
160
- fclose($fd);
 
 
161
 
162
  return $csv_content;
163
  }
@@ -171,18 +176,16 @@ class ContactsSyncService
171
  'x-account-id' => OptionsHelper::get_connected_account_id()
172
  ]
173
  ];
174
- $response = wp_remote_get($url,
175
- $args);
176
 
177
  if (is_wp_error($response)) {
178
  // todo throw error
179
  }
180
-
181
  if (!$this->is_success_response($response)) {
182
  // todo throw error
183
  }
184
 
185
- $json = json_decode($response['body']);
186
 
187
  $request_sas_model = new stdClass();
188
  $request_sas_model->url = $json->url;
@@ -272,7 +275,6 @@ class ContactsSyncService
272
  private function is_success_response($response)
273
  {
274
  $response_code = wp_remote_retrieve_response_code($response);
275
-
276
  return $response_code >= 200 && $response_code <= 299;
277
  }
278
  }
50
 
51
  public function upsertContact(ContactModel $contactModel)
52
  {
53
+ if( $contactModel == null ) {
54
  return false;
55
  }
56
 
126
  // todo throw exception
127
  }
128
 
129
+ // 1. Convert to csv file.
130
  $csv_file = $this->create_csv_file($contactModels);
131
+ // 2. Request sas model (with url and uuid).
132
  $sas_request_model = $this->request_sas_model();
133
+ // 3. Upload csv file using sas url.
134
  $this->upload_csv_file($csv_file, $sas_request_model->url);
135
+ // 4. Call endpoint to start import (using uuid).
136
  $this->start_import_for_uuid($sas_request_model->uuid);
137
 
138
  }
139
 
140
  private function create_csv_file($contactModels)
141
  {
142
+ $csv_content = '';
143
  if (ValidationHelper::is_null_or_empty($contactModels)) {
144
  // todo throw exception
145
  }
152
  foreach($contactModels as $contactModel) {
153
  $contact_fields_array = $this->convert_contact_to_csv_array($contactModel);
154
  if (!ValidationHelper::is_null_or_empty($contact_fields_array)) {
155
+ if ($fd !== false) {
156
+ fputcsv($fd, $contact_fields_array);
157
+ }
158
  }
159
  }
160
 
161
+ if ($fd !== false) {
162
+ rewind($fd);
163
+ $csv_content = stream_get_contents($fd);
164
+ fclose($fd);
165
+ }
166
 
167
  return $csv_content;
168
  }
176
  'x-account-id' => OptionsHelper::get_connected_account_id()
177
  ]
178
  ];
179
+ $response = wp_remote_get($url, $args);
 
180
 
181
  if (is_wp_error($response)) {
182
  // todo throw error
183
  }
 
184
  if (!$this->is_success_response($response)) {
185
  // todo throw error
186
  }
187
 
188
+ $json = json_decode(is_array($response) ? $response['body'] : '');
189
 
190
  $request_sas_model = new stdClass();
191
  $request_sas_model->url = $json->url;
275
  private function is_success_response($response)
276
  {
277
  $response_code = wp_remote_retrieve_response_code($response);
 
278
  return $response_code >= 200 && $response_code <= 299;
279
  }
280
  }
src/Modules/DashboardWidgetModule.php CHANGED
@@ -8,6 +8,7 @@ use CreativeMail\Exceptions\CreativeMailException;
8
  use CreativeMail\Helpers\OptionsHelper;
9
  use CreativeMail\Helpers\ValidationHelper;
10
  use CreativeMail\Managers\RaygunManager;
 
11
 
12
  class DashboardWidgetModule
13
  {
@@ -27,7 +28,7 @@ class DashboardWidgetModule
27
  */
28
  public function show()
29
  {
30
- wp_enqueue_script( 'ce4wp_dashboard_widget', CE4WP_PLUGIN_URL . 'assets/js/dashboard.js', null, CE4WP_PLUGIN_VERSION );
31
  wp_localize_script( 'ce4wp_dashboard_widget', 'ce4wp_data', array(
32
  'url' => admin_url( 'admin-ajax.php' ),
33
  'nonce' => wp_create_nonce( 'ajax-nonce' )
@@ -105,7 +106,7 @@ class DashboardWidgetModule
105
  include CE4WP_PLUGIN_DIR . 'src/views/admin-dashboard-widget/no-woocommerce.php';
106
  }
107
  }
108
- catch(\Exception $ex) { }
109
  }
110
 
111
  private function show_exception()
8
  use CreativeMail\Helpers\OptionsHelper;
9
  use CreativeMail\Helpers\ValidationHelper;
10
  use CreativeMail\Managers\RaygunManager;
11
+ use Exception;
12
 
13
  class DashboardWidgetModule
14
  {
28
  */
29
  public function show()
30
  {
31
+ wp_enqueue_script( 'ce4wp_dashboard_widget', CE4WP_PLUGIN_URL . 'assets/js/dashboard.js', [], CE4WP_PLUGIN_VERSION );
32
  wp_localize_script( 'ce4wp_dashboard_widget', 'ce4wp_data', array(
33
  'url' => admin_url( 'admin-ajax.php' ),
34
  'nonce' => wp_create_nonce( 'ajax-nonce' )
106
  include CE4WP_PLUGIN_DIR . 'src/views/admin-dashboard-widget/no-woocommerce.php';
107
  }
108
  }
109
+ catch(Exception $ex) { }
110
  }
111
 
112
  private function show_exception()
src/Modules/FeedbackNoticeModule.php CHANGED
@@ -20,9 +20,9 @@ class FeedbackNoticeModule
20
 
21
  public function display()
22
  {
23
- wp_register_style('ce4wp_feedback_notice_css', CE4WP_PLUGIN_URL . 'assets/css/feedback_notice.css', null, CE4WP_PLUGIN_VERSION);
24
  wp_enqueue_style('ce4wp_feedback_notice_css');
25
- wp_enqueue_script('ce4wp_feedback_notice', CE4WP_PLUGIN_URL.'assets/js/feedback_notice.js', null,null,true);
26
 
27
  $admin_url = admin_url('admin-ajax.php');
28
  $nonce = wp_create_nonce('ajax-nonce');
@@ -32,7 +32,7 @@ class FeedbackNoticeModule
32
  'nonce' => $nonce,
33
  'hide_banner_url' => get_rest_url( null, 'creativemail/v1/hide_banner?banner=' ),
34
  ));
35
- wp_enqueue_script('ce4wp_dashboard', CE4WP_PLUGIN_URL.'assets/js/dashboard.js', null,CE4WP_PLUGIN_VERSION);
36
  wp_localize_script('ce4wp_dashboard', 'ce4wp_data', array(
37
  'url' => $admin_url,
38
  'nonce' => $nonce,
20
 
21
  public function display()
22
  {
23
+ wp_register_style('ce4wp_feedback_notice_css', CE4WP_PLUGIN_URL . 'assets/css/feedback_notice.css', [], CE4WP_PLUGIN_VERSION);
24
  wp_enqueue_style('ce4wp_feedback_notice_css');
25
+ wp_enqueue_script('ce4wp_feedback_notice', CE4WP_PLUGIN_URL.'assets/js/feedback_notice.js', [],CE4WP_PLUGIN_VERSION,true);
26
 
27
  $admin_url = admin_url('admin-ajax.php');
28
  $nonce = wp_create_nonce('ajax-nonce');
32
  'nonce' => $nonce,
33
  'hide_banner_url' => get_rest_url( null, 'creativemail/v1/hide_banner?banner=' ),
34
  ));
35
+ wp_enqueue_script('ce4wp_dashboard', CE4WP_PLUGIN_URL.'assets/js/dashboard.js', [],CE4WP_PLUGIN_VERSION);
36
  wp_localize_script('ce4wp_dashboard', 'ce4wp_data', array(
37
  'url' => $admin_url,
38
  'nonce' => $nonce,
src/Modules/WooCommerce/Emails/AbandonedCartEmail.php CHANGED
@@ -7,15 +7,13 @@ use WC_Order;
7
  class AbandonedCartEmail extends WC_Email {
8
  /**
9
  * Constructor.
10
- *
11
- * @param WC_Email[] $email_classes All existing instances of WooCommerce emails.
12
  */
13
- public function __construct( $email_classes = array() ) {
14
  $this->id = 'cart_abandoned_ce4wp';
15
  $this->title = __( 'Abandoned cart', 'ce4wp' );
16
  $this->description = __( 'Send customers a reminder after they abandoned their shopping cart', 'ce4wp' );
17
  $this->customer_email = true;
18
- $this->enabled = false;
19
 
20
  // We want all the parent's methods, with none of its properties, so call its parent's constructor, rather than my parent constructor.
21
  parent::__construct();
7
  class AbandonedCartEmail extends WC_Email {
8
  /**
9
  * Constructor.
 
 
10
  */
11
+ public function __construct( ) {
12
  $this->id = 'cart_abandoned_ce4wp';
13
  $this->title = __( 'Abandoned cart', 'ce4wp' );
14
  $this->description = __( 'Send customers a reminder after they abandoned their shopping cart', 'ce4wp' );
15
  $this->customer_email = true;
16
+ $this->enabled = 'no';
17
 
18
  // We want all the parent's methods, with none of its properties, so call its parent's constructor, rather than my parent constructor.
19
  parent::__construct();
src/Modules/WooCommerce/Models/WCInformationModel.php CHANGED
@@ -8,6 +8,7 @@ class WCInformationModel
8
  public $wc_installed;
9
  public $wc_version;
10
  public $plugin_version;
 
11
 
12
  function __construct()
13
  {
8
  public $wc_installed;
9
  public $wc_version;
10
  public $plugin_version;
11
+ public $perma_links;
12
 
13
  function __construct()
14
  {
src/Modules/WooCommerce/Models/WCStoreInformation.php CHANGED
@@ -28,7 +28,7 @@ class WCStoreInformation
28
  $this->city = WC()->countries->get_base_city();
29
  $this->postcode = WC()->countries->get_base_postcode();
30
  $this->state = WC()->countries->get_base_state();
31
- $this->country = WC()->countries->countries[WC()->countries->get_base_country()];
32
  $this->country_code = WC()->countries->get_base_country();
33
  $this->currency_symbol = get_woocommerce_currency_symbol();
34
  $this->currency = get_woocommerce_currency();
28
  $this->city = WC()->countries->get_base_city();
29
  $this->postcode = WC()->countries->get_base_postcode();
30
  $this->state = WC()->countries->get_base_state();
31
+ $this->country = WC()->countries->get_countries()[WC()->countries->get_base_country()];
32
  $this->country_code = WC()->countries->get_base_country();
33
  $this->currency_symbol = get_woocommerce_currency_symbol();
34
  $this->currency = get_woocommerce_currency();
src/views/activated-integrations.php CHANGED
@@ -70,6 +70,7 @@ $activated_templates = CreativeMail::get_instance()->get_email_manager()->get_ma
70
  <br />
71
  <form id="activated_plugins_form" name="plugins" action="" method="post">
72
  <input type="hidden" name="action" value="change_activated_plugins" />
 
73
  <div style="color: rgba(0, 0, 0, 0.6);" class="ce4wp-grid">
74
  <?php
75
  foreach ($available_integrations as $available_integration) {
70
  <br />
71
  <form id="activated_plugins_form" name="plugins" action="" method="post">
72
  <input type="hidden" name="action" value="change_activated_plugins" />
73
+ <input name="activated_plugins_nonce" type="hidden" value="<?= wp_create_nonce('activated_plugins') ?>" />
74
  <div style="color: rgba(0, 0, 0, 0.6);" class="ce4wp-grid">
75
  <?php
76
  foreach ($available_integrations as $available_integration) {
src/views/admin-dashboard-widget/most-recent-campaigns.php CHANGED
@@ -60,7 +60,9 @@ p.ce4wp-campaigns__item__subtitle {
60
 
61
  <h3><?= __( 'Your recent campaigns', 'ce4wp' ); ?></h3>
62
  <section class="ce4wp-campaigns">
63
- <?php foreach ( $ce_most_recent_campaigns as $campaign ) { ?>
 
 
64
  <div class="ce4wp-campaigns__item">
65
  <section class="ce4wp-campaigns__item__section">
66
  <?php if ( $campaign->is_draft ) { ?>
60
 
61
  <h3><?= __( 'Your recent campaigns', 'ce4wp' ); ?></h3>
62
  <section class="ce4wp-campaigns">
63
+ <?php
64
+ // @phpstan-ignore-next-line
65
+ foreach ( $ce_most_recent_campaigns as $campaign ) { ?>
66
  <div class="ce4wp-campaigns__item">
67
  <section class="ce4wp-campaigns__item__section">
68
  <?php if ( $campaign->is_draft ) { ?>
src/views/admin-dashboard-widget/woocommerce.php CHANGED
@@ -21,13 +21,19 @@
21
  <div class="ce4wp-woocommerce__item">
22
  <p><?= __( 'Active', 'ce4wp' ); ?>:</p>
23
  <p>
24
- <strong><?= $number_of_active_notifications; ?></strong>
 
 
 
25
  </p>
26
  </div>
27
  <div class="ce4wp-woocommerce__item">
28
- <p><?= __( 'Inactive', 'ce4wp' ); ?>:</p>
29
  <p>
30
- <strong><?= $number_of_possible_notifications - $number_of_active_notifications; ?></strong>
 
 
 
31
  </p>
32
  </div>
33
  </section>
21
  <div class="ce4wp-woocommerce__item">
22
  <p><?= __( 'Active', 'ce4wp' ); ?>:</p>
23
  <p>
24
+ <strong>
25
+ <?php // @phpstan-ignore-next-line
26
+ echo $number_of_active_notifications; ?>
27
+ </strong>
28
  </p>
29
  </div>
30
  <div class="ce4wp-woocommerce__item">
31
+ <p><?php echo __( 'Inactive', 'ce4wp' ); ?>:</p>
32
  <p>
33
+ <strong>
34
+ <?php // @phpstan-ignore-next-line
35
+ echo $number_of_possible_notifications - $number_of_active_notifications; ?>
36
+ </strong>
37
  </p>
38
  </div>
39
  </section>
src/views/admin-feedback-notice/many-contacts.php CHANGED
@@ -1,13 +1,17 @@
1
  <div id="ce4wp-admin-feedback-notice" class="notice notice-warning" hidden>
2
- <img class="icon" src="<?= CE4WP_PLUGIN_URL . 'assets/images/airplane-purple.svg'; ?>" />
3
  <section class="content">
4
  <p>
5
- <strong><?= __( 'Awesome... your audience is growing!', 'ce4wp' ); ?></strong>
6
  </p>
7
  <p>
8
- <?= __( 'Your', 'ce4wp' ); ?>
9
- <strong><?= $ce_number_of_contacts; ?></strong>
10
- <?= __( 'contacts are ready for a Creative Mail email campaign. Send one now!', 'ce4wp' ); ?>
 
 
 
 
11
  </p>
12
  </section>
13
  <button class="button button-primary" onclick="ce4wpNavigateToDashboard(this, 'd25f690a-217a-4d68-9c58-8693965d4673', { source: 'feedback_notice' }, ce4wpWidgetStartCallback, ce4wpWidgetFinishCallback)"><?= __( 'Get started', 'ce4wp' ); ?></button>
1
  <div id="ce4wp-admin-feedback-notice" class="notice notice-warning" hidden>
2
+ <img class="icon" src="<?php echo CE4WP_PLUGIN_URL . 'assets/images/airplane-purple.svg'; ?>" />
3
  <section class="content">
4
  <p>
5
+ <strong><?php echo __( 'Awesome... your audience is growing!', 'ce4wp' ); ?></strong>
6
  </p>
7
  <p>
8
+ <?php echo __( 'Your', 'ce4wp' ); ?>
9
+ <strong>
10
+ <?php // @phpstan-ignore-next-line
11
+ echo $ce_number_of_contacts;
12
+ ?>
13
+ </strong>
14
+ <?php echo __( 'contacts are ready for a Creative Mail email campaign. Send one now!', 'ce4wp' ); ?>
15
  </p>
16
  </section>
17
  <button class="button button-primary" onclick="ce4wpNavigateToDashboard(this, 'd25f690a-217a-4d68-9c58-8693965d4673', { source: 'feedback_notice' }, ce4wpWidgetStartCallback, ce4wpWidgetFinishCallback)"><?= __( 'Get started', 'ce4wp' ); ?></button>
src/views/admin-get-started-banner.php CHANGED
@@ -1,7 +1,9 @@
1
  <script>
2
  function hideAdminGetStartedBanner () {
3
  document.querySelector('.notice-ce4wp-getting-started').hidden = true;
4
- fetch('<?= $ce_hide_banner_url; ?>', { method: 'POST' })
 
 
5
  }
6
  </script>
7
 
1
  <script>
2
  function hideAdminGetStartedBanner () {
3
  document.querySelector('.notice-ce4wp-getting-started').hidden = true;
4
+ fetch('<?php // @phpstan-ignore-next-line
5
+ echo $ce_hide_banner_url;
6
+ ?>', { method: 'POST' })
7
  }
8
  </script>
9
 
src/views/pending-setup.php CHANGED
@@ -17,6 +17,7 @@
17
  </p>
18
  <div class="ce4wp-kvp">
19
  <form name="disconnect" action="" method="post">
 
20
  <input type="hidden" name="action" value="disconnect" />
21
  <input name="disconnect_button" type="submit" class="ce4wp-button-text-primary destructive ce4wp-right" id="disconnect-instance" value="Reset" />
22
  </form>
17
  </p>
18
  <div class="ce4wp-kvp">
19
  <form name="disconnect" action="" method="post">
20
+ <input name="disconnect_nonce" type="hidden" value="<?=wp_create_nonce('disconnect')?>" />
21
  <input type="hidden" name="action" value="disconnect" />
22
  <input name="disconnect_button" type="submit" class="ce4wp-button-text-primary destructive ce4wp-right" id="disconnect-instance" value="Reset" />
23
  </form>
src/views/settings-internal.php CHANGED
@@ -4,35 +4,43 @@ use CreativeMail\Helpers\EnvironmentHelper;
4
 
5
  <div class="ce4wp-card">
6
  <div class="ce4wp-px-4 ce4wp-py-4">
7
- <h2 class="ce4wp-typography-root ce4wp-typography-h2 ce4wp-mb-2"><?= __( 'Technical details', 'ce4wp' ); ?></h2>
8
 
9
  <div class="ce4wp-kvp">
10
- <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?= __( 'Instance UUID', 'ce4wp' ); ?></h4>
11
- <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_html($this->instance_uuid) ?></p>
 
 
 
 
12
  </div>
13
 
14
  <div class="ce4wp-kvp">
15
- <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?= __( 'Instance Id', 'ce4wp' ); ?></h4>
16
- <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_html($this->instance_id) ?></p>
 
 
 
 
17
  </div>
18
 
19
  <div class="ce4wp-kvp">
20
- <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?= __( 'Environment', 'ce4wp' ); ?></h4>
21
  <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_html(EnvironmentHelper::get_environment()) ?></p>
22
  </div>
23
 
24
  <div class="ce4wp-kvp">
25
- <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?= __( 'Plugin version', 'ce4wp' ); ?></h4>
26
  <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_html(CE4WP_PLUGIN_VERSION) . '.' . esc_html(CE4WP_BUILD_NUMBER) ?></p>
27
  </div>
28
 
29
  <div class="ce4wp-kvp">
30
- <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?= __( 'App', 'ce4wp' ); ?></h4>
31
  <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_js(EnvironmentHelper::get_app_url()) ?></p>
32
  </div>
33
 
34
  <div class="ce4wp-kvp">
35
- <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?= __( 'App Gateway', 'ce4wp' ); ?></h4>
36
  <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_js(EnvironmentHelper::get_app_gateway_url()) ?></p>
37
  </div>
38
  </div>
4
 
5
  <div class="ce4wp-card">
6
  <div class="ce4wp-px-4 ce4wp-py-4">
7
+ <h2 class="ce4wp-typography-root ce4wp-typography-h2 ce4wp-mb-2"><?php echo __( 'Technical details', 'ce4wp' ); ?></h2>
8
 
9
  <div class="ce4wp-kvp">
10
+ <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?php echo __( 'Instance UUID', 'ce4wp' ); ?></h4>
11
+ <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);">
12
+ <?php // @phpstan-ignore-next-line
13
+ echo esc_html($this->instance_uuid)
14
+ ?>
15
+ </p>
16
  </div>
17
 
18
  <div class="ce4wp-kvp">
19
+ <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?php echo __( 'Instance Id', 'ce4wp' ); ?></h4>
20
+ <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);">
21
+ <?php // @phpstan-ignore-next-line
22
+ echo esc_html($this->instance_id)
23
+ ?>
24
+ </p>
25
  </div>
26
 
27
  <div class="ce4wp-kvp">
28
+ <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?php echo __( 'Environment', 'ce4wp' ); ?></h4>
29
  <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_html(EnvironmentHelper::get_environment()) ?></p>
30
  </div>
31
 
32
  <div class="ce4wp-kvp">
33
+ <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?php echo __( 'Plugin version', 'ce4wp' ); ?></h4>
34
  <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_html(CE4WP_PLUGIN_VERSION) . '.' . esc_html(CE4WP_BUILD_NUMBER) ?></p>
35
  </div>
36
 
37
  <div class="ce4wp-kvp">
38
+ <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?php echo __( 'App', 'ce4wp' ); ?></h4>
39
  <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_js(EnvironmentHelper::get_app_url()) ?></p>
40
  </div>
41
 
42
  <div class="ce4wp-kvp">
43
+ <h4 class="ce4wp-typography-root ce4wp-typography-h4 ce4wp-mb-2"><?php echo __( 'App Gateway', 'ce4wp' ); ?></h4>
44
  <p class="ce4wp-typography-root ce4wp-body2" style="color: rgba(0, 0, 0, 0.6);"><?php echo esc_js(EnvironmentHelper::get_app_gateway_url()) ?></p>
45
  </div>
46
  </div>
src/views/settings.php CHANGED
@@ -5,13 +5,13 @@ use CreativeMail\Helpers\EnvironmentHelper;
5
  use CreativeMail\Helpers\OptionsHelper;
6
 
7
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
8
-
9
- if($_POST['action'] === 'disconnect') {
10
  OptionsHelper::clear_options(true);
 
11
  $this->instance_id = null;
12
  }
13
 
14
- if($_POST['action'] === 'change_activated_plugins') {
15
  $activated_plugins = array();
16
  if (isset($_POST['activated_plugins'])) {
17
  $keys = $_POST["activated_plugins"];
@@ -19,12 +19,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
19
  array_push($activated_plugins, sanitize_key($key));
20
  }
21
  }
22
-
23
  CreativeMail::get_instance()->get_integration_manager()->set_activated_plugins($activated_plugins);
24
  }
25
 
26
- if ($_POST['action'] === 'change_marketing_information') {
27
- if(array_key_exists('ce4wp_show_marketing_checkbox', $_POST) && sanitize_key($_POST['ce4wp_show_marketing_checkbox']) === 'on') {
28
  OptionsHelper::set_checkout_checkbox_enabled('1');
29
  } else {
30
  OptionsHelper::set_checkout_checkbox_enabled('0');
@@ -79,13 +78,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
79
  <h2 class="ce4wp-typography-root ce4wp-typography-h2 ce4wp-mb-2"><?= __( 'Customer Email Marketing', 'ce4wp' ); ?></h2>
80
 
81
  <form name="plugins" action="" method="post">
 
82
  <input type="hidden" name="action" value="change_marketing_information" />
83
  <table class="form-table">
84
  <tbody>
85
  <tr>
86
  <td class="forminp forminp-text ce4wp-px-0">
87
  <label class="ce4wp-checkbox">
88
- <input type="checkbox" name="ce4wp_show_marketing_checkbox" <?php echo (esc_attr(OptionsHelper::get_checkout_checkbox_enabled()) === '1') ? 'checked' : '';?> />
89
  <span class="ce4wp-typography-root ce4wp-body2">
90
  <?php echo __('Yes I want to ask my customers in the WooCommerce Checkout for consent to send marketing emails.', 'ce4wp'); ?>
91
  </span>
5
  use CreativeMail\Helpers\OptionsHelper;
6
 
7
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
8
+ if( $_POST['action'] === 'disconnect' && wp_verify_nonce( $_POST['disconnect_nonce'], 'disconnect' ) ) {
 
9
  OptionsHelper::clear_options(true);
10
+ // @phpstan-ignore-next-line
11
  $this->instance_id = null;
12
  }
13
 
14
+ if( $_POST['action'] === 'change_activated_plugins' && wp_verify_nonce( $_POST['activated_plugins_nonce'], 'activated_plugins' ) ) {
15
  $activated_plugins = array();
16
  if (isset($_POST['activated_plugins'])) {
17
  $keys = $_POST["activated_plugins"];
19
  array_push($activated_plugins, sanitize_key($key));
20
  }
21
  }
 
22
  CreativeMail::get_instance()->get_integration_manager()->set_activated_plugins($activated_plugins);
23
  }
24
 
25
+ if ( $_POST['action'] === 'change_marketing_information' && wp_verify_nonce( $_POST['marketing_consent_nonce'], 'marketing_consent' ) ) {
26
+ if( array_key_exists( 'ce4wp_show_marketing_checkbox', $_POST ) && sanitize_key( $_POST[ 'ce4wp_show_marketing_checkbox' ] ) === 'on') {
27
  OptionsHelper::set_checkout_checkbox_enabled('1');
28
  } else {
29
  OptionsHelper::set_checkout_checkbox_enabled('0');
78
  <h2 class="ce4wp-typography-root ce4wp-typography-h2 ce4wp-mb-2"><?= __( 'Customer Email Marketing', 'ce4wp' ); ?></h2>
79
 
80
  <form name="plugins" action="" method="post">
81
+ <input name="marketing_consent_nonce" type="hidden" value="<?=wp_create_nonce('marketing_consent')?>" />
82
  <input type="hidden" name="action" value="change_marketing_information" />
83
  <table class="form-table">
84
  <tbody>
85
  <tr>
86
  <td class="forminp forminp-text ce4wp-px-0">
87
  <label class="ce4wp-checkbox">
88
+ <input type="checkbox" name="ce4wp_show_marketing_checkbox" <?php echo ( esc_attr ( OptionsHelper::get_checkout_checkbox_enabled() == '1' ? 'checked' : '' ) );?> />
89
  <span class="ce4wp-typography-root ce4wp-body2">
90
  <?php echo __('Yes I want to ask my customers in the WooCommerce Checkout for consent to send marketing emails.', 'ce4wp'); ?>
91
  </span>
src/views/unlink.php CHANGED
@@ -8,7 +8,8 @@
8
 
9
  <div class="ce4wp-kvp">
10
  <form name="disconnect" action="" method="post">
11
- <input type="hidden" name="action" value="disconnect" />
 
12
  <input name="disconnect_button" type="submit" class="ce4wp-button-text-primary destructive ce4wp-right" id="disconnect-instance" value="Unlink" onclick="return confirm('Are you sure you want to unlink your CreativeMail account from your WordPress site? This action is permanent and cannot be undone.')" />
13
  </form>
14
  </div>
8
 
9
  <div class="ce4wp-kvp">
10
  <form name="disconnect" action="" method="post">
11
+ <input name="disconnect_nonce" type="hidden" value="<?=wp_create_nonce('disconnect')?>" />
12
+ <input name="action" type="hidden" value="disconnect" />
13
  <input name="disconnect_button" type="submit" class="ce4wp-button-text-primary destructive ce4wp-right" id="disconnect-instance" value="Unlink" onclick="return confirm('Are you sure you want to unlink your CreativeMail account from your WordPress site? This action is permanent and cannot be undone.')" />
14
  </form>
15
  </div>
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit23a51e0a2bd5984936353858b1422529::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit280162df9749c3147507d248f2c68d82::getLoader();
vendor/bin/phpstan.phar ADDED
Binary file
vendor/composer/autoload_classmap.php CHANGED
@@ -97,6 +97,9 @@ return array(
97
  'Firebase\\JWT\\JWT' => $vendorDir . '/firebase/php-jwt/src/JWT.php',
98
  'Firebase\\JWT\\Key' => $vendorDir . '/firebase/php-jwt/src/Key.php',
99
  'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
 
 
 
100
  'Raygun4php\\Raygun4PhpException' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/Raygun4PhpException.php',
101
  'Raygun4php\\RaygunClient' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunClient.php',
102
  'Raygun4php\\RaygunClientMessage' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunClientMessage.php',
@@ -107,6 +110,34 @@ return array(
107
  'Raygun4php\\RaygunMessage' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunMessage.php',
108
  'Raygun4php\\RaygunMessageDetails' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunMessageDetails.php',
109
  'Raygun4php\\RaygunRequestMessage' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunRequestMessage.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  'WP_Async_Request' => $vendorDir . '/a5hleyrich/wp-background-processing/classes/wp-async-request.php',
111
  'WP_Background_Process' => $vendorDir . '/a5hleyrich/wp-background-processing/classes/wp-background-process.php',
112
  );
97
  'Firebase\\JWT\\JWT' => $vendorDir . '/firebase/php-jwt/src/JWT.php',
98
  'Firebase\\JWT\\Key' => $vendorDir . '/firebase/php-jwt/src/Key.php',
99
  'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
100
+ 'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
101
+ 'PHPStan\\ExtensionInstaller\\GeneratedConfig' => $vendorDir . '/phpstan/extension-installer/src/GeneratedConfig.php',
102
+ 'PHPStan\\ExtensionInstaller\\Plugin' => $vendorDir . '/phpstan/extension-installer/src/Plugin.php',
103
  'Raygun4php\\Raygun4PhpException' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/Raygun4PhpException.php',
104
  'Raygun4php\\RaygunClient' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunClient.php',
105
  'Raygun4php\\RaygunClientMessage' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunClientMessage.php',
110
  'Raygun4php\\RaygunMessage' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunMessage.php',
111
  'Raygun4php\\RaygunMessageDetails' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunMessageDetails.php',
112
  'Raygun4php\\RaygunRequestMessage' => $vendorDir . '/mindscape/raygun4php/src/Raygun4php/RaygunRequestMessage.php',
113
+ 'Symfony\\Polyfill\\Php73\\Php73' => $vendorDir . '/symfony/polyfill-php73/Php73.php',
114
+ 'SzepeViktor\\PHPStan\\WordPress\\ApplyFiltersDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/ApplyFiltersDynamicFunctionReturnTypeExtension.php',
115
+ 'SzepeViktor\\PHPStan\\WordPress\\CurrentTimeDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/CurrentTimeDynamicFunctionReturnTypeExtension.php',
116
+ 'SzepeViktor\\PHPStan\\WordPress\\EchoParameterDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/EchoParameterDynamicFunctionReturnTypeExtension.php',
117
+ 'SzepeViktor\\PHPStan\\WordPress\\GetCommentDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/GetCommentDynamicFunctionReturnTypeExtension.php',
118
+ 'SzepeViktor\\PHPStan\\WordPress\\GetListTableDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/GetListTableDynamicFunctionReturnTypeExtension.php',
119
+ 'SzepeViktor\\PHPStan\\WordPress\\GetObjectTaxonomiesDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/GetObjectTaxonomiesDynamicFunctionReturnTypeExtension.php',
120
+ 'SzepeViktor\\PHPStan\\WordPress\\GetPostDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/GetPostDynamicFunctionReturnTypeExtension.php',
121
+ 'SzepeViktor\\PHPStan\\WordPress\\GetPostsDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/GetPostsDynamicFunctionReturnTypeExtension.php',
122
+ 'SzepeViktor\\PHPStan\\WordPress\\GetSitesDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/GetSitesDynamicFunctionReturnTypeExtension.php',
123
+ 'SzepeViktor\\PHPStan\\WordPress\\GetTaxonomiesDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/GetTaxonomiesDynamicFunctionReturnTypeExtension.php',
124
+ 'SzepeViktor\\PHPStan\\WordPress\\GetTermsDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/GetTermsDynamicFunctionReturnTypeExtension.php',
125
+ 'SzepeViktor\\PHPStan\\WordPress\\HasFilterDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/HasFilterDynamicFunctionReturnTypeExtension.php',
126
+ 'SzepeViktor\\PHPStan\\WordPress\\HookDocBlock' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/HookDocBlock.php',
127
+ 'SzepeViktor\\PHPStan\\WordPress\\HookDocsParamException' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/HookDocsParamException.php',
128
+ 'SzepeViktor\\PHPStan\\WordPress\\HookDocsRule' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/HookDocsRule.php',
129
+ 'SzepeViktor\\PHPStan\\WordPress\\HookDocsVisitor' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/HookDocsVisitor.php',
130
+ 'SzepeViktor\\PHPStan\\WordPress\\IsWpErrorFunctionTypeSpecifyingExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/IsWpErrorFunctionTypeSpecifyingExtension.php',
131
+ 'SzepeViktor\\PHPStan\\WordPress\\IsWpErrorRule' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/IsWpErrorRule.php',
132
+ 'SzepeViktor\\PHPStan\\WordPress\\MySQL2DateDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/MySQL2DateDynamicFunctionReturnTypeExtension.php',
133
+ 'SzepeViktor\\PHPStan\\WordPress\\RedirectCanonicalDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/RedirectCanonicalDynamicFunctionReturnTypeExtension.php',
134
+ 'SzepeViktor\\PHPStan\\WordPress\\ShortcodeAttsDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/ShortcodeAttsDynamicFunctionReturnTypeExtension.php',
135
+ 'SzepeViktor\\PHPStan\\WordPress\\StringOrArrayDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/StringOrArrayDynamicFunctionReturnTypeExtension.php',
136
+ 'SzepeViktor\\PHPStan\\WordPress\\TermExistsDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/TermExistsDynamicFunctionReturnTypeExtension.php',
137
+ 'SzepeViktor\\PHPStan\\WordPress\\WPErrorParameterDynamicFunctionReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/WPErrorParameterDynamicFunctionReturnTypeExtension.php',
138
+ 'SzepeViktor\\PHPStan\\WordPress\\WpParseUrlFunctionDynamicReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/WpParseUrlFunctionDynamicReturnTypeExtension.php',
139
+ 'SzepeViktor\\PHPStan\\WordPress\\WpThemeGetDynamicMethodReturnTypeExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/WpThemeGetDynamicMethodReturnTypeExtension.php',
140
+ 'SzepeViktor\\PHPStan\\WordPress\\WpThemeMagicPropertiesClassReflectionExtension' => $vendorDir . '/szepeviktor/phpstan-wordpress/src/WpThemeMagicPropertiesClassReflectionExtension.php',
141
  'WP_Async_Request' => $vendorDir . '/a5hleyrich/wp-background-processing/classes/wp-async-request.php',
142
  'WP_Background_Process' => $vendorDir . '/a5hleyrich/wp-background-processing/classes/wp-background-process.php',
143
  );
vendor/composer/autoload_files.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_files.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ '9b38cf48e83f5d8f60375221cd213eee' => $vendorDir . '/phpstan/phpstan/bootstrap.php',
10
+ '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
11
+ );
vendor/composer/autoload_psr4.php CHANGED
@@ -6,6 +6,9 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
 
9
  'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
10
  'Defuse\\Crypto\\' => array($vendorDir . '/defuse/php-encryption/src'),
11
  'CreativeMail\\Modules\\' => array($baseDir . '/src/modules'),
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'SzepeViktor\\PHPStan\\WordPress\\' => array($vendorDir . '/szepeviktor/phpstan-wordpress/src'),
10
+ 'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'),
11
+ 'PHPStan\\ExtensionInstaller\\' => array($vendorDir . '/phpstan/extension-installer/src'),
12
  'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
13
  'Defuse\\Crypto\\' => array($vendorDir . '/defuse/php-encryption/src'),
14
  'CreativeMail\\Modules\\' => array($baseDir . '/src/modules'),
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit23a51e0a2bd5984936353858b1422529
6
  {
7
  private static $loader;
8
 
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit23a51e0a2bd5984936353858b1422529
22
  return self::$loader;
23
  }
24
 
25
- spl_autoload_register(array('ComposerAutoloaderInit23a51e0a2bd5984936353858b1422529', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
- spl_autoload_unregister(array('ComposerAutoloaderInit23a51e0a2bd5984936353858b1422529', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require_once __DIR__ . '/autoload_static.php';
32
 
33
- call_user_func(\Composer\Autoload\ComposerStaticInit23a51e0a2bd5984936353858b1422529::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
@@ -50,6 +50,24 @@ class ComposerAutoloaderInit23a51e0a2bd5984936353858b1422529
50
 
51
  $loader->register(true);
52
 
 
 
 
 
 
 
 
 
 
53
  return $loader;
54
  }
55
  }
 
 
 
 
 
 
 
 
 
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit280162df9749c3147507d248f2c68d82
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit280162df9749c3147507d248f2c68d82', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit280162df9749c3147507d248f2c68d82', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require_once __DIR__ . '/autoload_static.php';
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit280162df9749c3147507d248f2c68d82::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
50
 
51
  $loader->register(true);
52
 
53
+ if ($useStaticLoader) {
54
+ $includeFiles = Composer\Autoload\ComposerStaticInit280162df9749c3147507d248f2c68d82::$files;
55
+ } else {
56
+ $includeFiles = require __DIR__ . '/autoload_files.php';
57
+ }
58
+ foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequire280162df9749c3147507d248f2c68d82($fileIdentifier, $file);
60
+ }
61
+
62
  return $loader;
63
  }
64
  }
65
+
66
+ function composerRequire280162df9749c3147507d248f2c68d82($fileIdentifier, $file)
67
+ {
68
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
+ require $file;
70
+
71
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
72
+ }
73
+ }
vendor/composer/autoload_static.php CHANGED
@@ -4,9 +4,23 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit23a51e0a2bd5984936353858b1422529
8
  {
 
 
 
 
 
9
  public static $prefixLengthsPsr4 = array (
 
 
 
 
 
 
 
 
 
10
  'F' =>
11
  array (
12
  'Firebase\\JWT\\' => 13,
@@ -29,6 +43,18 @@ class ComposerStaticInit23a51e0a2bd5984936353858b1422529
29
  );
30
 
31
  public static $prefixDirsPsr4 = array (
 
 
 
 
 
 
 
 
 
 
 
 
32
  'Firebase\\JWT\\' =>
33
  array (
34
  0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
@@ -173,6 +199,9 @@ class ComposerStaticInit23a51e0a2bd5984936353858b1422529
173
  'Firebase\\JWT\\JWT' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWT.php',
174
  'Firebase\\JWT\\Key' => __DIR__ . '/..' . '/firebase/php-jwt/src/Key.php',
175
  'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
 
 
 
176
  'Raygun4php\\Raygun4PhpException' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/Raygun4PhpException.php',
177
  'Raygun4php\\RaygunClient' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunClient.php',
178
  'Raygun4php\\RaygunClientMessage' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunClientMessage.php',
@@ -183,6 +212,34 @@ class ComposerStaticInit23a51e0a2bd5984936353858b1422529
183
  'Raygun4php\\RaygunMessage' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunMessage.php',
184
  'Raygun4php\\RaygunMessageDetails' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunMessageDetails.php',
185
  'Raygun4php\\RaygunRequestMessage' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunRequestMessage.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  'WP_Async_Request' => __DIR__ . '/..' . '/a5hleyrich/wp-background-processing/classes/wp-async-request.php',
187
  'WP_Background_Process' => __DIR__ . '/..' . '/a5hleyrich/wp-background-processing/classes/wp-background-process.php',
188
  );
@@ -190,10 +247,10 @@ class ComposerStaticInit23a51e0a2bd5984936353858b1422529
190
  public static function getInitializer(ClassLoader $loader)
191
  {
192
  return \Closure::bind(function () use ($loader) {
193
- $loader->prefixLengthsPsr4 = ComposerStaticInit23a51e0a2bd5984936353858b1422529::$prefixLengthsPsr4;
194
- $loader->prefixDirsPsr4 = ComposerStaticInit23a51e0a2bd5984936353858b1422529::$prefixDirsPsr4;
195
- $loader->prefixesPsr0 = ComposerStaticInit23a51e0a2bd5984936353858b1422529::$prefixesPsr0;
196
- $loader->classMap = ComposerStaticInit23a51e0a2bd5984936353858b1422529::$classMap;
197
 
198
  }, null, ClassLoader::class);
199
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit280162df9749c3147507d248f2c68d82
8
  {
9
+ public static $files = array (
10
+ '9b38cf48e83f5d8f60375221cd213eee' => __DIR__ . '/..' . '/phpstan/phpstan/bootstrap.php',
11
+ '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
12
+ );
13
+
14
  public static $prefixLengthsPsr4 = array (
15
+ 'S' =>
16
+ array (
17
+ 'SzepeViktor\\PHPStan\\WordPress\\' => 30,
18
+ 'Symfony\\Polyfill\\Php73\\' => 23,
19
+ ),
20
+ 'P' =>
21
+ array (
22
+ 'PHPStan\\ExtensionInstaller\\' => 27,
23
+ ),
24
  'F' =>
25
  array (
26
  'Firebase\\JWT\\' => 13,
43
  );
44
 
45
  public static $prefixDirsPsr4 = array (
46
+ 'SzepeViktor\\PHPStan\\WordPress\\' =>
47
+ array (
48
+ 0 => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src',
49
+ ),
50
+ 'Symfony\\Polyfill\\Php73\\' =>
51
+ array (
52
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-php73',
53
+ ),
54
+ 'PHPStan\\ExtensionInstaller\\' =>
55
+ array (
56
+ 0 => __DIR__ . '/..' . '/phpstan/extension-installer/src',
57
+ ),
58
  'Firebase\\JWT\\' =>
59
  array (
60
  0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
199
  'Firebase\\JWT\\JWT' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWT.php',
200
  'Firebase\\JWT\\Key' => __DIR__ . '/..' . '/firebase/php-jwt/src/Key.php',
201
  'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
202
+ 'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
203
+ 'PHPStan\\ExtensionInstaller\\GeneratedConfig' => __DIR__ . '/..' . '/phpstan/extension-installer/src/GeneratedConfig.php',
204
+ 'PHPStan\\ExtensionInstaller\\Plugin' => __DIR__ . '/..' . '/phpstan/extension-installer/src/Plugin.php',
205
  'Raygun4php\\Raygun4PhpException' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/Raygun4PhpException.php',
206
  'Raygun4php\\RaygunClient' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunClient.php',
207
  'Raygun4php\\RaygunClientMessage' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunClientMessage.php',
212
  'Raygun4php\\RaygunMessage' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunMessage.php',
213
  'Raygun4php\\RaygunMessageDetails' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunMessageDetails.php',
214
  'Raygun4php\\RaygunRequestMessage' => __DIR__ . '/..' . '/mindscape/raygun4php/src/Raygun4php/RaygunRequestMessage.php',
215
+ 'Symfony\\Polyfill\\Php73\\Php73' => __DIR__ . '/..' . '/symfony/polyfill-php73/Php73.php',
216
+ 'SzepeViktor\\PHPStan\\WordPress\\ApplyFiltersDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/ApplyFiltersDynamicFunctionReturnTypeExtension.php',
217
+ 'SzepeViktor\\PHPStan\\WordPress\\CurrentTimeDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/CurrentTimeDynamicFunctionReturnTypeExtension.php',
218
+ 'SzepeViktor\\PHPStan\\WordPress\\EchoParameterDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/EchoParameterDynamicFunctionReturnTypeExtension.php',
219
+ 'SzepeViktor\\PHPStan\\WordPress\\GetCommentDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/GetCommentDynamicFunctionReturnTypeExtension.php',
220
+ 'SzepeViktor\\PHPStan\\WordPress\\GetListTableDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/GetListTableDynamicFunctionReturnTypeExtension.php',
221
+ 'SzepeViktor\\PHPStan\\WordPress\\GetObjectTaxonomiesDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/GetObjectTaxonomiesDynamicFunctionReturnTypeExtension.php',
222
+ 'SzepeViktor\\PHPStan\\WordPress\\GetPostDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/GetPostDynamicFunctionReturnTypeExtension.php',
223
+ 'SzepeViktor\\PHPStan\\WordPress\\GetPostsDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/GetPostsDynamicFunctionReturnTypeExtension.php',
224
+ 'SzepeViktor\\PHPStan\\WordPress\\GetSitesDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/GetSitesDynamicFunctionReturnTypeExtension.php',
225
+ 'SzepeViktor\\PHPStan\\WordPress\\GetTaxonomiesDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/GetTaxonomiesDynamicFunctionReturnTypeExtension.php',
226
+ 'SzepeViktor\\PHPStan\\WordPress\\GetTermsDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/GetTermsDynamicFunctionReturnTypeExtension.php',
227
+ 'SzepeViktor\\PHPStan\\WordPress\\HasFilterDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/HasFilterDynamicFunctionReturnTypeExtension.php',
228
+ 'SzepeViktor\\PHPStan\\WordPress\\HookDocBlock' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/HookDocBlock.php',
229
+ 'SzepeViktor\\PHPStan\\WordPress\\HookDocsParamException' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/HookDocsParamException.php',
230
+ 'SzepeViktor\\PHPStan\\WordPress\\HookDocsRule' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/HookDocsRule.php',
231
+ 'SzepeViktor\\PHPStan\\WordPress\\HookDocsVisitor' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/HookDocsVisitor.php',
232
+ 'SzepeViktor\\PHPStan\\WordPress\\IsWpErrorFunctionTypeSpecifyingExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/IsWpErrorFunctionTypeSpecifyingExtension.php',
233
+ 'SzepeViktor\\PHPStan\\WordPress\\IsWpErrorRule' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/IsWpErrorRule.php',
234
+ 'SzepeViktor\\PHPStan\\WordPress\\MySQL2DateDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/MySQL2DateDynamicFunctionReturnTypeExtension.php',
235
+ 'SzepeViktor\\PHPStan\\WordPress\\RedirectCanonicalDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/RedirectCanonicalDynamicFunctionReturnTypeExtension.php',
236
+ 'SzepeViktor\\PHPStan\\WordPress\\ShortcodeAttsDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/ShortcodeAttsDynamicFunctionReturnTypeExtension.php',
237
+ 'SzepeViktor\\PHPStan\\WordPress\\StringOrArrayDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/StringOrArrayDynamicFunctionReturnTypeExtension.php',
238
+ 'SzepeViktor\\PHPStan\\WordPress\\TermExistsDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/TermExistsDynamicFunctionReturnTypeExtension.php',
239
+ 'SzepeViktor\\PHPStan\\WordPress\\WPErrorParameterDynamicFunctionReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/WPErrorParameterDynamicFunctionReturnTypeExtension.php',
240
+ 'SzepeViktor\\PHPStan\\WordPress\\WpParseUrlFunctionDynamicReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/WpParseUrlFunctionDynamicReturnTypeExtension.php',
241
+ 'SzepeViktor\\PHPStan\\WordPress\\WpThemeGetDynamicMethodReturnTypeExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/WpThemeGetDynamicMethodReturnTypeExtension.php',
242
+ 'SzepeViktor\\PHPStan\\WordPress\\WpThemeMagicPropertiesClassReflectionExtension' => __DIR__ . '/..' . '/szepeviktor/phpstan-wordpress/src/WpThemeMagicPropertiesClassReflectionExtension.php',
243
  'WP_Async_Request' => __DIR__ . '/..' . '/a5hleyrich/wp-background-processing/classes/wp-async-request.php',
244
  'WP_Background_Process' => __DIR__ . '/..' . '/a5hleyrich/wp-background-processing/classes/wp-background-process.php',
245
  );
247
  public static function getInitializer(ClassLoader $loader)
248
  {
249
  return \Closure::bind(function () use ($loader) {
250
+ $loader->prefixLengthsPsr4 = ComposerStaticInit280162df9749c3147507d248f2c68d82::$prefixLengthsPsr4;
251
+ $loader->prefixDirsPsr4 = ComposerStaticInit280162df9749c3147507d248f2c68d82::$prefixDirsPsr4;
252
+ $loader->prefixesPsr0 = ComposerStaticInit280162df9749c3147507d248f2c68d82::$prefixesPsr0;
253
+ $loader->classMap = ComposerStaticInit280162df9749c3147507d248f2c68d82::$classMap;
254
 
255
  }, null, ClassLoader::class);
256
  }
vendor/composer/installed.json CHANGED
@@ -279,6 +279,101 @@
279
  "source": "https://github.com/paragonie/random_compat"
280
  }
281
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  {
283
  "name": "phpcompatibility/php-compatibility",
284
  "version": "9.3.5",
@@ -343,6 +438,114 @@
343
  "source": "https://github.com/PHPCompatibility/PHPCompatibility"
344
  }
345
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  {
347
  "name": "squizlabs/php_codesniffer",
348
  "version": "3.6.2",
@@ -400,5 +603,157 @@
400
  "source": "https://github.com/squizlabs/PHP_CodeSniffer",
401
  "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
402
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  }
404
  ]
279
  "source": "https://github.com/paragonie/random_compat"
280
  }
281
  },
282
+ {
283
+ "name": "php-stubs/woocommerce-stubs",
284
+ "version": "v6.9.3",
285
+ "version_normalized": "6.9.3.0",
286
+ "source": {
287
+ "type": "git",
288
+ "url": "https://github.com/php-stubs/woocommerce-stubs.git",
289
+ "reference": "870c0c0abcd5ae9a8be58fc797123a4d882e604e"
290
+ },
291
+ "dist": {
292
+ "type": "zip",
293
+ "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/870c0c0abcd5ae9a8be58fc797123a4d882e604e",
294
+ "reference": "870c0c0abcd5ae9a8be58fc797123a4d882e604e",
295
+ "shasum": ""
296
+ },
297
+ "require": {
298
+ "php-stubs/wordpress-stubs": "^5.3 || ^6.0"
299
+ },
300
+ "require-dev": {
301
+ "php": "~7.1 || ~8.0",
302
+ "php-stubs/generator": "^0.8.0"
303
+ },
304
+ "suggest": {
305
+ "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
306
+ "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
307
+ },
308
+ "time": "2022-09-20T23:28:43+00:00",
309
+ "type": "library",
310
+ "installation-source": "dist",
311
+ "notification-url": "https://packagist.org/downloads/",
312
+ "license": [
313
+ "MIT"
314
+ ],
315
+ "description": "WooCommerce function and class declaration stubs for static analysis.",
316
+ "homepage": "https://github.com/php-stubs/woocommerce-stubs",
317
+ "keywords": [
318
+ "PHPStan",
319
+ "static analysis",
320
+ "woocommerce",
321
+ "wordpress"
322
+ ],
323
+ "support": {
324
+ "issues": "https://github.com/php-stubs/woocommerce-stubs/issues",
325
+ "source": "https://github.com/php-stubs/woocommerce-stubs/tree/v6.9.3"
326
+ }
327
+ },
328
+ {
329
+ "name": "php-stubs/wordpress-stubs",
330
+ "version": "v6.0.1",
331
+ "version_normalized": "6.0.1.0",
332
+ "source": {
333
+ "type": "git",
334
+ "url": "https://github.com/php-stubs/wordpress-stubs.git",
335
+ "reference": "e04781a84e364615a7b5f70fdc345c8253ca5b8f"
336
+ },
337
+ "dist": {
338
+ "type": "zip",
339
+ "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/e04781a84e364615a7b5f70fdc345c8253ca5b8f",
340
+ "reference": "e04781a84e364615a7b5f70fdc345c8253ca5b8f",
341
+ "shasum": ""
342
+ },
343
+ "replace": {
344
+ "giacocorsiglia/wordpress-stubs": "*"
345
+ },
346
+ "require-dev": {
347
+ "nikic/php-parser": "< 4.12.0",
348
+ "php": "~7.3 || ~8.0",
349
+ "php-stubs/generator": "^0.8.1",
350
+ "phpdocumentor/reflection-docblock": "^5.3",
351
+ "phpstan/phpstan": "^1.2"
352
+ },
353
+ "suggest": {
354
+ "paragonie/sodium_compat": "Pure PHP implementation of libsodium",
355
+ "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
356
+ "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
357
+ },
358
+ "time": "2022-07-15T11:10:45+00:00",
359
+ "type": "library",
360
+ "installation-source": "dist",
361
+ "notification-url": "https://packagist.org/downloads/",
362
+ "license": [
363
+ "MIT"
364
+ ],
365
+ "description": "WordPress function and class declaration stubs for static analysis.",
366
+ "homepage": "https://github.com/php-stubs/wordpress-stubs",
367
+ "keywords": [
368
+ "PHPStan",
369
+ "static analysis",
370
+ "wordpress"
371
+ ],
372
+ "support": {
373
+ "issues": "https://github.com/php-stubs/wordpress-stubs/issues",
374
+ "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.0.1"
375
+ }
376
+ },
377
  {
378
  "name": "phpcompatibility/php-compatibility",
379
  "version": "9.3.5",
438
  "source": "https://github.com/PHPCompatibility/PHPCompatibility"
439
  }
440
  },
441
+ {
442
+ "name": "phpstan/extension-installer",
443
+ "version": "1.1.0",
444
+ "version_normalized": "1.1.0.0",
445
+ "source": {
446
+ "type": "git",
447
+ "url": "https://github.com/phpstan/extension-installer.git",
448
+ "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051"
449
+ },
450
+ "dist": {
451
+ "type": "zip",
452
+ "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
453
+ "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
454
+ "shasum": ""
455
+ },
456
+ "require": {
457
+ "composer-plugin-api": "^1.1 || ^2.0",
458
+ "php": "^7.1 || ^8.0",
459
+ "phpstan/phpstan": ">=0.11.6"
460
+ },
461
+ "require-dev": {
462
+ "composer/composer": "^1.8",
463
+ "phing/phing": "^2.16.3",
464
+ "php-parallel-lint/php-parallel-lint": "^1.2.0",
465
+ "phpstan/phpstan-strict-rules": "^0.11 || ^0.12"
466
+ },
467
+ "time": "2020-12-13T13:06:13+00:00",
468
+ "type": "composer-plugin",
469
+ "extra": {
470
+ "class": "PHPStan\\ExtensionInstaller\\Plugin"
471
+ },
472
+ "installation-source": "dist",
473
+ "autoload": {
474
+ "psr-4": {
475
+ "PHPStan\\ExtensionInstaller\\": "src/"
476
+ }
477
+ },
478
+ "notification-url": "https://packagist.org/downloads/",
479
+ "license": [
480
+ "MIT"
481
+ ],
482
+ "description": "Composer plugin for automatic installation of PHPStan extensions",
483
+ "support": {
484
+ "issues": "https://github.com/phpstan/extension-installer/issues",
485
+ "source": "https://github.com/phpstan/extension-installer/tree/1.1.0"
486
+ }
487
+ },
488
+ {
489
+ "name": "phpstan/phpstan",
490
+ "version": "1.8.2",
491
+ "version_normalized": "1.8.2.0",
492
+ "source": {
493
+ "type": "git",
494
+ "url": "https://github.com/phpstan/phpstan.git",
495
+ "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c"
496
+ },
497
+ "dist": {
498
+ "type": "zip",
499
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c53312ecc575caf07b0e90dee43883fdf90ca67c",
500
+ "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c",
501
+ "shasum": ""
502
+ },
503
+ "require": {
504
+ "php": "^7.2|^8.0"
505
+ },
506
+ "conflict": {
507
+ "phpstan/phpstan-shim": "*"
508
+ },
509
+ "time": "2022-07-20T09:57:31+00:00",
510
+ "bin": [
511
+ "phpstan",
512
+ "phpstan.phar"
513
+ ],
514
+ "type": "library",
515
+ "installation-source": "dist",
516
+ "autoload": {
517
+ "files": [
518
+ "bootstrap.php"
519
+ ]
520
+ },
521
+ "notification-url": "https://packagist.org/downloads/",
522
+ "license": [
523
+ "MIT"
524
+ ],
525
+ "description": "PHPStan - PHP Static Analysis Tool",
526
+ "support": {
527
+ "issues": "https://github.com/phpstan/phpstan/issues",
528
+ "source": "https://github.com/phpstan/phpstan/tree/1.8.2"
529
+ },
530
+ "funding": [
531
+ {
532
+ "url": "https://github.com/ondrejmirtes",
533
+ "type": "github"
534
+ },
535
+ {
536
+ "url": "https://github.com/phpstan",
537
+ "type": "github"
538
+ },
539
+ {
540
+ "url": "https://www.patreon.com/phpstan",
541
+ "type": "patreon"
542
+ },
543
+ {
544
+ "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
545
+ "type": "tidelift"
546
+ }
547
+ ]
548
+ },
549
  {
550
  "name": "squizlabs/php_codesniffer",
551
  "version": "3.6.2",
603
  "source": "https://github.com/squizlabs/PHP_CodeSniffer",
604
  "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
605
  }
606
+ },
607
+ {
608
+ "name": "symfony/polyfill-php73",
609
+ "version": "v1.26.0",
610
+ "version_normalized": "1.26.0.0",
611
+ "source": {
612
+ "type": "git",
613
+ "url": "https://github.com/symfony/polyfill-php73.git",
614
+ "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85"
615
+ },
616
+ "dist": {
617
+ "type": "zip",
618
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85",
619
+ "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85",
620
+ "shasum": ""
621
+ },
622
+ "require": {
623
+ "php": ">=7.1"
624
+ },
625
+ "time": "2022-05-24T11:49:31+00:00",
626
+ "type": "library",
627
+ "extra": {
628
+ "branch-alias": {
629
+ "dev-main": "1.26-dev"
630
+ },
631
+ "thanks": {
632
+ "name": "symfony/polyfill",
633
+ "url": "https://github.com/symfony/polyfill"
634
+ }
635
+ },
636
+ "installation-source": "dist",
637
+ "autoload": {
638
+ "files": [
639
+ "bootstrap.php"
640
+ ],
641
+ "psr-4": {
642
+ "Symfony\\Polyfill\\Php73\\": ""
643
+ },
644
+ "classmap": [
645
+ "Resources/stubs"
646
+ ]
647
+ },
648
+ "notification-url": "https://packagist.org/downloads/",
649
+ "license": [
650
+ "MIT"
651
+ ],
652
+ "authors": [
653
+ {
654
+ "name": "Nicolas Grekas",
655
+ "email": "p@tchwork.com"
656
+ },
657
+ {
658
+ "name": "Symfony Community",
659
+ "homepage": "https://symfony.com/contributors"
660
+ }
661
+ ],
662
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
663
+ "homepage": "https://symfony.com",
664
+ "keywords": [
665
+ "compatibility",
666
+ "polyfill",
667
+ "portable",
668
+ "shim"
669
+ ],
670
+ "support": {
671
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0"
672
+ },
673
+ "funding": [
674
+ {
675
+ "url": "https://symfony.com/sponsor",
676
+ "type": "custom"
677
+ },
678
+ {
679
+ "url": "https://github.com/fabpot",
680
+ "type": "github"
681
+ },
682
+ {
683
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
684
+ "type": "tidelift"
685
+ }
686
+ ]
687
+ },
688
+ {
689
+ "name": "szepeviktor/phpstan-wordpress",
690
+ "version": "v1.1.3",
691
+ "version_normalized": "1.1.3.0",
692
+ "source": {
693
+ "type": "git",
694
+ "url": "https://github.com/szepeviktor/phpstan-wordpress.git",
695
+ "reference": "e644df734e1bbe95810e0f617d17df091048a94e"
696
+ },
697
+ "dist": {
698
+ "type": "zip",
699
+ "url": "https://api.github.com/repos/szepeviktor/phpstan-wordpress/zipball/e644df734e1bbe95810e0f617d17df091048a94e",
700
+ "reference": "e644df734e1bbe95810e0f617d17df091048a94e",
701
+ "shasum": ""
702
+ },
703
+ "require": {
704
+ "php": "^7.2 || ^8.0",
705
+ "php-stubs/wordpress-stubs": "^4.7 || ^5.0 || ^6.0",
706
+ "phpstan/phpstan": "^1.6",
707
+ "symfony/polyfill-php73": "^1.12.0"
708
+ },
709
+ "require-dev": {
710
+ "composer/composer": "^2.1.14",
711
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7",
712
+ "php-parallel-lint/php-parallel-lint": "^1.1",
713
+ "phpstan/phpstan-strict-rules": "^1.2",
714
+ "phpunit/phpunit": "^8 || ^9",
715
+ "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^0.6"
716
+ },
717
+ "time": "2022-09-22T13:14:50+00:00",
718
+ "type": "phpstan-extension",
719
+ "extra": {
720
+ "phpstan": {
721
+ "includes": [
722
+ "extension.neon"
723
+ ]
724
+ }
725
+ },
726
+ "installation-source": "dist",
727
+ "autoload": {
728
+ "psr-4": {
729
+ "SzepeViktor\\PHPStan\\WordPress\\": "src/"
730
+ }
731
+ },
732
+ "notification-url": "https://packagist.org/downloads/",
733
+ "license": [
734
+ "MIT"
735
+ ],
736
+ "description": "WordPress extensions for PHPStan",
737
+ "keywords": [
738
+ "PHPStan",
739
+ "code analyse",
740
+ "code analysis",
741
+ "static analysis",
742
+ "wordpress"
743
+ ],
744
+ "support": {
745
+ "issues": "https://github.com/szepeviktor/phpstan-wordpress/issues",
746
+ "source": "https://github.com/szepeviktor/phpstan-wordpress/tree/v1.1.3"
747
+ },
748
+ "funding": [
749
+ {
750
+ "url": "https://www.paypal.me/szepeviktor",
751
+ "type": "custom"
752
+ },
753
+ {
754
+ "url": "https://github.com/szepeviktor",
755
+ "type": "github"
756
+ }
757
+ ]
758
  }
759
  ]
vendor/phpstan/extension-installer/.github/workflows/build.yml ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # https://help.github.com/en/categories/automating-your-workflow-with-github-actions
2
+
3
+ name: "Build"
4
+
5
+ on:
6
+ pull_request:
7
+ push:
8
+ branches:
9
+ - "master"
10
+
11
+ jobs:
12
+ lint:
13
+ name: "Lint"
14
+ runs-on: "ubuntu-latest"
15
+
16
+ strategy:
17
+ matrix:
18
+ php-version:
19
+ - "7.1"
20
+ - "7.2"
21
+ - "7.3"
22
+ - "7.4"
23
+ - "8.0"
24
+
25
+ steps:
26
+ - name: "Checkout"
27
+ uses: "actions/checkout@v2"
28
+
29
+ - name: "Install PHP"
30
+ uses: "shivammathur/setup-php@v2"
31
+ with:
32
+ coverage: "none"
33
+ php-version: "${{ matrix.php-version }}"
34
+
35
+ - name: "Validate Composer"
36
+ run: "composer validate"
37
+
38
+ - name: "Install dependencies"
39
+ run: "composer install --no-interaction --no-progress --no-suggest"
40
+
41
+ - name: "Lint"
42
+ run: "vendor/bin/phing lint"
43
+
44
+ coding-standards:
45
+ name: "Coding Standard"
46
+
47
+ runs-on: "ubuntu-latest"
48
+
49
+ steps:
50
+ - name: "Checkout"
51
+ uses: "actions/checkout@v2"
52
+
53
+ - name: "Install PHP"
54
+ uses: "shivammathur/setup-php@v2"
55
+ with:
56
+ coverage: "none"
57
+ php-version: "7.4"
58
+
59
+ - name: "Validate Composer"
60
+ run: "composer validate"
61
+
62
+ - name: "Install dependencies"
63
+ run: "composer install --no-interaction --no-progress --no-suggest"
64
+
65
+ - name: "Lint"
66
+ run: "vendor/bin/phing lint"
67
+
68
+ - name: "Coding Standard"
69
+ run: "vendor/bin/phing cs"
70
+
71
+ static-analysis:
72
+ name: "PHPStan"
73
+ runs-on: "ubuntu-latest"
74
+
75
+ strategy:
76
+ fail-fast: false
77
+ matrix:
78
+ php-version:
79
+ - "7.1"
80
+ - "7.2"
81
+ - "7.3"
82
+ - "7.4"
83
+ - "8.0"
84
+ dependencies:
85
+ - "lowest"
86
+ - "highest"
87
+
88
+ steps:
89
+ - name: "Checkout"
90
+ uses: "actions/checkout@v2"
91
+
92
+ - name: "Install PHP"
93
+ uses: "shivammathur/setup-php@v2"
94
+ with:
95
+ coverage: "none"
96
+ php-version: "${{ matrix.php-version }}"
97
+ extensions: mbstring
98
+ tools: composer:v2
99
+
100
+ - name: "Install lowest dependencies"
101
+ if: ${{ matrix.dependencies == 'lowest' }}
102
+ run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest"
103
+
104
+ - name: "Install highest dependencies"
105
+ if: ${{ matrix.dependencies == 'highest' }}
106
+ run: "composer update --no-interaction --no-progress --no-suggest"
107
+
108
+ - name: "Update PHPStan"
109
+ if: matrix.php-version == '8.0'
110
+ run: "composer require --dev phpstan/phpstan:'^0.12.60' --update-with-dependencies"
111
+
112
+ - name: "PHPStan"
113
+ run: "vendor/bin/phing phpstan"
vendor/phpstan/extension-installer/.github/workflows/release.yml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # https://help.github.com/en/categories/automating-your-workflow-with-github-actions
2
+
3
+ name: "Create release"
4
+
5
+ on:
6
+ push:
7
+ tags:
8
+ - '*'
9
+
10
+ jobs:
11
+ deploy:
12
+ name: "Deploy"
13
+ runs-on: "ubuntu-latest"
14
+
15
+ steps:
16
+ - name: "Checkout"
17
+ uses: "actions/checkout@v2"
18
+
19
+ - name: Generate changelog
20
+ id: changelog
21
+ uses: metcalfc/changelog-generator@v0.4.4
22
+ with:
23
+ myToken: ${{ secrets.GITHUB_TOKEN }}
24
+
25
+ - name: "Create release"
26
+ id: create-release
27
+ uses: actions/create-release@v1
28
+ env:
29
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30
+ with:
31
+ tag_name: ${{ github.ref }}
32
+ release_name: ${{ github.ref }}
33
+ body: ${{ steps.changelog.outputs.changelog }}
vendor/phpstan/extension-installer/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /src/GeneratedConfig.php
2
+ /vendor
3
+ composer.lock
vendor/phpstan/extension-installer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Ondřej Mirtes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
vendor/phpstan/extension-installer/README.md ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PHPStan Extension Installer
2
+
3
+ [![Build](https://github.com/phpstan/extension-installer/workflows/Build/badge.svg)](https://github.com/phpstan/extension-installer/actions)
4
+ [![Latest Stable Version](https://poser.pugx.org/phpstan/extension-installer/v/stable)](https://packagist.org/packages/phpstan/extension-installer)
5
+ [![License](https://poser.pugx.org/phpstan/extension-installer/license)](https://packagist.org/packages/phpstan/extension-installer)
6
+
7
+ Composer plugin for automatic installation of [PHPStan](https://phpstan.org/) extensions.
8
+
9
+ # Motivation
10
+
11
+ ```diff
12
+ diff --git a/phpstan.neon b/phpstan.neon
13
+ index db4e3df32e..2ca30fa20a 100644
14
+ --- a/phpstan.neon
15
+ +++ b/phpstan.neon
16
+ @@ -1,12 +1,3 @@
17
+ -includes:
18
+ - - vendor/phpstan/phpstan-doctrine/extension.neon
19
+ - - vendor/phpstan/phpstan-doctrine/rules.neon
20
+ - - vendor/phpstan/phpstan-nette/extension.neon
21
+ - - vendor/phpstan/phpstan-nette/rules.neon
22
+ - - vendor/phpstan/phpstan-phpunit/extension.neon
23
+ - - vendor/phpstan/phpstan-phpunit/rules.neon
24
+ - - vendor/phpstan/phpstan-strict-rules/rules.neon
25
+ -
26
+ parameters:
27
+ autoload_directories:
28
+ - %rootDir%/../../../build/SlevomatSniffs
29
+ diff --git a/composer.json b/composer.json
30
+ index 1b578dd624..f6ebf6e477 100644
31
+ --- a/composer.json
32
+ +++ b/composer.json
33
+ @@ -142,6 +142,7 @@
34
+ "jakub-onderka/php-parallel-lint": "1.0.0",
35
+ "justinrainbow/json-schema": "5.2.8",
36
+ "ondrejmirtes/mocktainer": "0.8",
37
+ + "phpstan/extension-installer": "^1.0",
38
+ "phpstan/phpstan": "^0.11.7",
39
+ "phpstan/phpstan-doctrine": "^0.11.3",
40
+ "phpstan/phpstan-nette": "^0.11.1",
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ```bash
46
+ composer require --dev phpstan/extension-installer
47
+ ```
48
+
49
+ And that's it.
50
+
51
+ ## Instructions for extension developers
52
+
53
+ It's best (but optional) to set the extension's composer package [type](https://getcomposer.org/doc/04-schema.md#type) to `phpstan-extension` for this plugin to be able to recognize it and to be [discoverable on Packagist](https://packagist.org/explore/?type=phpstan-extension).
54
+
55
+ Only one feature is supported right now: PHPStan is able to automatically include the extension's config files, without you having to mention them in your `phpstan.neon`'s `includes` section.
56
+
57
+ For this, you have to add a `phpstan` key in the extension `composer.json`'s `extra` section like so:
58
+
59
+ ```json
60
+ {
61
+ "extra": {
62
+ "phpstan": {
63
+ "includes": [
64
+ "extension.neon"
65
+ ]
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## Limitations
72
+
73
+ The extension installer depends on Composer script events, therefore you cannot use `--no-scripts` flag.
vendor/phpstan/extension-installer/build-cs/.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /composer.lock
2
+ /vendor
vendor/phpstan/extension-installer/build-cs/composer.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "require-dev": {
3
+ "consistence/coding-standard": "^3.10",
4
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
5
+ "slevomat/coding-standard": "^6.4"
6
+ }
7
+ }
vendor/phpstan/extension-installer/build.xml ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <project name="PHPStan Extension Installer" default="check">
3
+
4
+ <target name="check" depends="
5
+ composer,
6
+ lint,
7
+ cs,
8
+ phpstan
9
+ "/>
10
+
11
+ <target name="composer">
12
+ <exec
13
+ executable="composer"
14
+ logoutput="true"
15
+ passthru="true"
16
+ checkreturn="true"
17
+ >
18
+ <arg value="install"/>
19
+ </exec>
20
+ </target>
21
+
22
+ <target name="lint">
23
+ <exec
24
+ executable="vendor/bin/parallel-lint"
25
+ logoutput="true"
26
+ passthru="true"
27
+ checkreturn="true"
28
+ >
29
+ <arg path="src" />
30
+ </exec>
31
+ </target>
32
+
33
+ <target name="cs">
34
+ <exec
35
+ executable="composer"
36
+ logoutput="true"
37
+ passthru="true"
38
+ checkreturn="true"
39
+ >
40
+ <arg value="install"/>
41
+ <arg value="--working-dir"/>
42
+ <arg path="build-cs"/>
43
+ <arg value="--ansi"/>
44
+ </exec>
45
+ <exec
46
+ executable="build-cs/vendor/bin/phpcs"
47
+ logoutput="true"
48
+ passthru="true"
49
+ checkreturn="true"
50
+ >
51
+ <arg value="--extensions=php"/>
52
+ <arg value="--encoding=utf-8"/>
53
+ <arg value="--tab-width=4"/>
54
+ <arg value="-sp"/>
55
+ <arg path="src"/>
56
+ </exec>
57
+ </target>
58
+
59
+ <target name="cs-fix">
60
+ <exec
61
+ executable="build-cs/vendor/bin/phpcbf"
62
+ logoutput="true"
63
+ passthru="true"
64
+ checkreturn="true"
65
+ >
66
+ <arg value="--extensions=php"/>
67
+ <arg value="--encoding=utf-8"/>
68
+ <arg value="--tab-width=4"/>
69
+ <arg value="-sp"/>
70
+ <arg path="src"/>
71
+ </exec>
72
+ </target>
73
+
74
+ <target name="phpstan">
75
+ <exec
76
+ executable="vendor/bin/phpstan"
77
+ logoutput="true"
78
+ passthru="true"
79
+ checkreturn="true"
80
+ >
81
+ <arg value="analyse"/>
82
+ <arg value="-l"/>
83
+ <arg value="7"/>
84
+ <arg value="-c"/>
85
+ <arg path="phpstan.neon"/>
86
+ <arg path="src"/>
87
+ </exec>
88
+ </target>
89
+
90
+ </project>
vendor/phpstan/extension-installer/composer.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "phpstan/extension-installer",
3
+ "type": "composer-plugin",
4
+ "description": "Composer plugin for automatic installation of PHPStan extensions",
5
+ "license": [
6
+ "MIT"
7
+ ],
8
+ "require": {
9
+ "php": "^7.1 || ^8.0",
10
+ "composer-plugin-api": "^1.1 || ^2.0",
11
+ "phpstan/phpstan": ">=0.11.6"
12
+ },
13
+ "require-dev": {
14
+ "composer/composer": "^1.8",
15
+ "phing/phing": "^2.16.3",
16
+ "php-parallel-lint/php-parallel-lint": "^1.2.0",
17
+ "phpstan/phpstan-strict-rules": "^0.11 || ^0.12"
18
+ },
19
+ "config": {
20
+ "sort-packages": true
21
+ },
22
+ "extra": {
23
+ "class": "PHPStan\\ExtensionInstaller\\Plugin"
24
+ },
25
+ "autoload": {
26
+ "psr-4": {
27
+ "PHPStan\\ExtensionInstaller\\": "src/"
28
+ }
29
+ }
30
+ }
vendor/phpstan/extension-installer/phpcs.xml ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset name="PHPStan extension installer">
3
+ <rule ref="build-cs/vendor/consistence/coding-standard/Consistence/ruleset.xml">
4
+ <exclude name="Squiz.Functions.GlobalFunction.Found"/>
5
+ <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameAfterKeyword"/>
6
+ <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation"/>
7
+ <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions"/>
8
+ <exclude name="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly"/>
9
+ <exclude name="Squiz.PHP.Heredoc.NotAllowed"/>
10
+ </rule>
11
+ <rule ref="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses">
12
+ <properties>
13
+ <property name="caseSensitive" value="false"/>
14
+ </properties>
15
+ </rule>
16
+ <rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
17
+ <properties>
18
+ <property name="newlinesCountBetweenOpenTagAndDeclare" value="0"/>
19
+ </properties>
20
+ </rule>
21
+ <rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint">
22
+ <properties>
23
+ <property name="usefulAnnotations" type="array" value="
24
+ @dataProvider,
25
+ @requires
26
+ "/>
27
+ <property name="enableObjectTypeHint" value="false"/>
28
+ </properties>
29
+ <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableParameterTypeHintSpecification"/>
30
+ <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableReturnTypeHintSpecification"/>
31
+ </rule>
32
+ <rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint">
33
+ <properties>
34
+ <property name="enableNativeTypeHint" value="false"/>
35
+ </properties>
36
+ <exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification"/>
37
+ </rule>
38
+ <rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint">
39
+ <properties>
40
+ <property name="enableObjectTypeHint" value="false"/>
41
+ </properties>
42
+ <exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification"/>
43
+ </rule>
44
+ <rule ref="SlevomatCodingStandard.ControlStructures.AssignmentInCondition"/>
45
+ <rule ref="SlevomatCodingStandard.Operators.DisallowEqualOperators"/>
46
+ <rule ref="SlevomatCodingStandard.ControlStructures.EarlyExit"/>
47
+ <rule ref="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming"/>
48
+ <rule ref="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming"/>
49
+ <!-- <rule ref="SlevomatCodingStandard.ControlStructures.DisallowShortTernaryOperator"/>-->
50
+ <!-- <rule ref="SlevomatCodingStandard.Namespaces.RequireOneNamespaceInFile"/> -->
51
+ <!-- <rule ref="SlevomatCodingStandard.PHP.ShortList"/> -->
52
+ <rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
53
+ <properties>
54
+ <property name="rootNamespaces" type="array" value="src=>PHPStan\ExtensionInstaller"/>
55
+ </properties>
56
+ </rule>
57
+ </ruleset>
vendor/phpstan/extension-installer/phpstan.neon ADDED
@@ -0,0 +1,2 @@
 
 
1
+ includes:
2
+ - vendor/phpstan/phpstan-strict-rules/rules.neon
vendor/phpstan/extension-installer/src/Plugin.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare(strict_types = 1);
2
+
3
+ namespace PHPStan\ExtensionInstaller;
4
+
5
+ use Composer\Composer;
6
+ use Composer\EventDispatcher\EventSubscriberInterface;
7
+ use Composer\IO\IOInterface;
8
+ use Composer\Plugin\PluginInterface;
9
+ use Composer\Script\Event;
10
+ use Composer\Script\ScriptEvents;
11
+ use Composer\Util\Filesystem;
12
+ use function array_keys;
13
+ use function file_exists;
14
+ use function file_put_contents;
15
+ use function in_array;
16
+ use function is_file;
17
+ use function md5;
18
+ use function md5_file;
19
+ use function sprintf;
20
+ use function strpos;
21
+ use function var_export;
22
+
23
+ final class Plugin implements PluginInterface, EventSubscriberInterface
24
+ {
25
+
26
+ /** @var string */
27
+ private static $generatedFileTemplate = <<<'PHP'
28
+ <?php declare(strict_types = 1);
29
+
30
+ namespace PHPStan\ExtensionInstaller;
31
+
32
+ /**
33
+ * This class is generated by phpstan/extension-installer.
34
+ * @internal
35
+ */
36
+ final class GeneratedConfig
37
+ {
38
+
39
+ public const EXTENSIONS = %s;
40
+
41
+ public const NOT_INSTALLED = %s;
42
+
43
+ private function __construct()
44
+ {
45
+ }
46
+
47
+ }
48
+
49
+ PHP;
50
+
51
+ public function activate(Composer $composer, IOInterface $io): void
52
+ {
53
+ // noop
54
+ }
55
+
56
+ public function deactivate(Composer $composer, IOInterface $io): void
57
+ {
58
+ // noop
59
+ }
60
+
61
+ public function uninstall(Composer $composer, IOInterface $io): void
62
+ {
63
+ // noop
64
+ }
65
+
66
+ /**
67
+ * @return array<string, string>
68
+ */
69
+ public static function getSubscribedEvents(): array
70
+ {
71
+ return [
72
+ ScriptEvents::POST_INSTALL_CMD => 'process',
73
+ ScriptEvents::POST_UPDATE_CMD => 'process',
74
+ ];
75
+ }
76
+
77
+ public function process(Event $event): void
78
+ {
79
+ $io = $event->getIO();
80
+
81
+ if (!file_exists(__DIR__)) {
82
+ $io->write('<info>phpstan/extension-installer:</info> Package not found (probably scheduled for removal); extensions installation skipped.');
83
+ return;
84
+ }
85
+
86
+ $composer = $event->getComposer();
87
+ $installationManager = $composer->getInstallationManager();
88
+
89
+ $generatedConfigFilePath = __DIR__ . '/GeneratedConfig.php';
90
+ $oldGeneratedConfigFileHash = null;
91
+ if (is_file($generatedConfigFilePath)) {
92
+ $oldGeneratedConfigFileHash = md5_file($generatedConfigFilePath);
93
+ }
94
+ $notInstalledPackages = [];
95
+ $installedPackages = [];
96
+
97
+ $data = [];
98
+ $fs = new Filesystem();
99
+ foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) {
100
+ if (
101
+ $package->getType() !== 'phpstan-extension'
102
+ && !isset($package->getExtra()['phpstan'])
103
+ ) {
104
+ if (
105
+ strpos($package->getName(), 'phpstan') !== false
106
+ && !in_array($package->getName(), [
107
+ 'phpstan/phpstan',
108
+ 'phpstan/phpstan-shim',
109
+ 'phpstan/phpdoc-parser',
110
+ 'phpstan/extension-installer',
111
+ ], true)
112
+ ) {
113
+ $notInstalledPackages[$package->getName()] = $package->getFullPrettyVersion();
114
+ }
115
+ continue;
116
+ }
117
+ $absoluteInstallPath = $installationManager->getInstallPath($package);
118
+ $data[$package->getName()] = [
119
+ 'install_path' => $absoluteInstallPath,
120
+ 'relative_install_path' => $fs->findShortestPath(dirname($generatedConfigFilePath), $absoluteInstallPath, true),
121
+ 'extra' => $package->getExtra()['phpstan'] ?? null,
122
+ 'version' => $package->getFullPrettyVersion(),
123
+ ];
124
+
125
+ $installedPackages[$package->getName()] = true;
126
+ }
127
+
128
+ ksort($data);
129
+ ksort($installedPackages);
130
+ ksort($notInstalledPackages);
131
+
132
+ $generatedConfigFileContents = sprintf(self::$generatedFileTemplate, var_export($data, true), var_export($notInstalledPackages, true));
133
+ file_put_contents($generatedConfigFilePath, $generatedConfigFileContents);
134
+ $io->write('<info>phpstan/extension-installer:</info> Extensions installed');
135
+
136
+ if ($oldGeneratedConfigFileHash === md5($generatedConfigFileContents)) {
137
+ return;
138
+ }
139
+
140
+ foreach (array_keys($installedPackages) as $name) {
141
+ $io->write(sprintf('> <info>%s:</info> installed', $name));
142
+ }
143
+
144
+ foreach (array_keys($notInstalledPackages) as $name) {
145
+ $io->write(sprintf('> <comment>%s:</comment> not supported', $name));
146
+ }
147
+ }
148
+
149
+ }
vendor/phpstan/phpstan/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Ondřej Mirtes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
vendor/phpstan/phpstan/README.md ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <h1 align="center">PHPStan - PHP Static Analysis Tool</h1>
2
+
3
+ <p align="center">
4
+ <img src="https://i.imgur.com/WaRKPlC.png" alt="PHPStan" width="300" height="300">
5
+ </p>
6
+
7
+ <p align="center">
8
+ <a href="https://github.com/phpstan/phpstan/actions"><img src="https://github.com/phpstan/phpstan/workflows/Tests/badge.svg" alt="Build Status"></a>
9
+ <a href="https://packagist.org/packages/phpstan/phpstan"><img src="https://poser.pugx.org/phpstan/phpstan/v/stable" alt="Latest Stable Version"></a>
10
+ <a href="https://packagist.org/packages/phpstan/phpstan/stats"><img src="https://poser.pugx.org/phpstan/phpstan/downloads" alt="Total Downloads"></a>
11
+ <a href="https://choosealicense.com/licenses/mit/"><img src="https://poser.pugx.org/phpstan/phpstan/license" alt="License"></a>
12
+ <a href="https://phpstan.org/"><img src="https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat" alt="PHPStan Enabled"></a>
13
+ </p>
14
+
15
+ ------
16
+
17
+ PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs
18
+ even before you write tests for the code. It moves PHP closer to compiled languages in the sense that the correctness of each line of the code
19
+ can be checked before you run the actual line.
20
+
21
+ **[Read more about PHPStan in an introductory article »](https://phpstan.org/blog/find-bugs-in-your-code-without-writing-tests)**
22
+
23
+ **[Try out PHPStan on the on-line playground! »](https://phpstan.org/)**
24
+
25
+ ## Sponsors
26
+
27
+ <a href="https://coders.thecodingmachine.com/phpstan"><img src="https://i.imgur.com/kQhNOTP.png" alt="TheCodingMachine" width="247" height="64"></a>
28
+ &nbsp;&nbsp;&nbsp;
29
+ <a href="https://packagist.com/?utm_source=phpstan&utm_medium=readme&utm_campaign=sponsorlogo"><img src="https://i.imgur.com/B2T63Do.png" alt="Private Packagist" width="283" height="64"></a>
30
+ <br>
31
+ <a href="https://careers.tuigroup.com/jobs/"><img src="https://i.imgur.com/uw5rAlR.png" alt="Musement" width="247" height="49"></a>
32
+ &nbsp;&nbsp;&nbsp;
33
+ <a href="https://blackfire.io/docs/introduction?utm_source=phpstan&utm_medium=github_readme&utm_campaign=logo"><img src="https://i.imgur.com/zR8rsqk.png" alt="Blackfire.io" width="254" height="64"></a>
34
+ <br>
35
+ <a href="https://www.iodigital.com/"><img src="https://i.imgur.com/fJlw1n9.png" alt="iO" width="254" height="65"></a>
36
+ &nbsp;&nbsp;&nbsp;
37
+ <a href="https://jobs.ticketswap.com/"><img src="https://i.imgur.com/lhzcutK.png" alt="TicketSwap" width="269" height="64"></a>
38
+ <br>
39
+ <a href="https://www.startupjobs.cz/startup/shipmonk"><img src="https://i.imgur.com/bAC47za.jpg" alt="ShipMonk" width="290" height="64"></a>
40
+ &nbsp;&nbsp;&nbsp;
41
+ <a href="https://togetter.com/"><img src="https://i.imgur.com/x9n5cj3.png" alt="Togetter" width="283" height="64"></a>
42
+ <br>
43
+ <a href="https://join.rightcapital.com/?utm_source=phpstan&utm_medium=github&utm_campaign=sponsorship"><img src="https://i.imgur.com/1AhB5tW.png" alt="RightCapital" width="283" height="64"></a>
44
+ &nbsp;&nbsp;&nbsp;
45
+ <a href="https://www.contentkingapp.com/?ref=php-developer&utm_source=phpstan&utm_medium=referral&utm_campaign=sponsorship"><img src="https://i.imgur.com/HHhbPGN.png" alt="ContentKing" width="283" height="64"></a>
46
+ <br>
47
+ <a href="https://zol.fr?utm_source=phpstan"><img src="https://i.imgur.com/dzDgd4s.png" alt="ZOL" width="283" height="64"></a>
48
+ &nbsp;&nbsp;&nbsp;
49
+ <a href="https://kocourek.uk/"><img src="https://i.imgur.com/EX29z98.png" alt="Stepan Kocourek" width="294" height="64"></a>
50
+ <br>
51
+ <a href="https://www.shopware.com/en/"><img src="https://i.imgur.com/L4X5w9s.png" alt="Shopware" width="284" height="64"></a>
52
+ &nbsp;&nbsp;&nbsp;
53
+ <a href="https://craftcms.com/"><img src="https://i.imgur.com/xJWThke.png" alt="Craft CMS" width="283" height="64"></a>
54
+ <br>
55
+ <a href="https://www.worksome.com/"><img src="https://i.imgur.com/TQKSwOl.png" alt="Worksome" width="283" height="64"></a>
56
+ &nbsp;&nbsp;&nbsp;
57
+ <a href="https://www.campoint.net/"><img src="https://i.imgur.com/fR6eMUm.png" alt="campoint AG" width="283" height="64"></a>
58
+ <br>
59
+ <a href="https://www.crisp.nl/"><img src="https://i.imgur.com/jRJyPve.png" alt="Crisp.nl" width="283" height="64"></a>
60
+ &nbsp;&nbsp;&nbsp;
61
+ <a href="https://inviqa.com/"><img src="https://i.imgur.com/G99rj45.png" alt="Inviqa" width="254" height="65"></a>
62
+ <br>
63
+ <a href="https://www.psyonix.com/"><img src="https://i.imgur.com/p8svxQZ.png" alt="Psyonix" width="254" height="65"></a>
64
+
65
+ [**You can now sponsor my open-source work on PHPStan through GitHub Sponsors.**](https://github.com/sponsors/ondrejmirtes)
66
+
67
+ Does GitHub already have your 💳? Do you use PHPStan to find 🐛 before they reach production? [Send a couple of 💸 a month my way too.](https://github.com/sponsors/ondrejmirtes) Thank you!
68
+
69
+ One-time donations [through PayPal](https://paypal.me/phpstan) are also accepted. To request an invoice, [contact me](mailto:ondrej@mirtes.cz) through e-mail.
70
+
71
+ ## Documentation
72
+
73
+ All the documentation lives on the [phpstan.org website](https://phpstan.org/):
74
+
75
+ * [Getting Started & User Guide](https://phpstan.org/user-guide/getting-started)
76
+ * [Config Reference](https://phpstan.org/config-reference)
77
+ * [PHPDocs Basics](https://phpstan.org/writing-php-code/phpdocs-basics) & [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types)
78
+ * [Extension Library](https://phpstan.org/user-guide/extension-library)
79
+ * [Developing Extensions](https://phpstan.org/developing-extensions/extension-types)
80
+ * [API Reference](https://apiref.phpstan.org/)
81
+
82
+ ## PHPStan Pro
83
+
84
+ PHPStan Pro is a paid add-on on top of open-source PHPStan Static Analysis Tool with these premium features:
85
+
86
+ * Web UI for browsing found errors, you can click and open your editor of choice on the offending line.
87
+ * Continuous analysis (watch mode): scans changed files in the background, refreshes the UI automatically.
88
+ * Interactive fixer: lets you choose the right fix for found errors :blush:
89
+
90
+ Try it on PHPStan 0.12.45 or later by running it with the `--pro` option. You can create an account either by following the on-screen instructions, or by visiting [account.phpstan.com](https://account.phpstan.com/).
91
+
92
+ After 30-day free trial period it costs 7 EUR for individuals monthly, 70 EUR for teams (up to 25 members). By paying for PHPStan Pro, you're supporting the development of open-source PHPStan.
93
+
94
+ You can read more about it on [PHPStan's website](https://phpstan.org/blog/introducing-phpstan-pro).
95
+
96
+ ## Code of Conduct
97
+
98
+ This project adheres to a [Contributor Code of Conduct](https://github.com/phpstan/phpstan/blob/master/CODE_OF_CONDUCT.md). By participating in this project and its community, you are expected to uphold this code.
99
+
100
+ ## Contributing
101
+
102
+ Any contributions are welcome. PHPStan's source code open to pull requests lives at [`phpstan/phpstan-src`](https://github.com/phpstan/phpstan-src).
vendor/phpstan/phpstan/bootstrap.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare(strict_types = 1);
2
+
3
+ namespace PHPStan;
4
+
5
+ use Composer\Autoload\ClassLoader;
6
+
7
+ final class PharAutoloader
8
+ {
9
+ /** @var ClassLoader */
10
+ private static $composerAutoloader;
11
+
12
+ final public static function loadClass(string $class): void {
13
+ if (!extension_loaded('phar') || defined('__PHPSTAN_RUNNING__')) {
14
+ return;
15
+ }
16
+
17
+ if (strpos($class, '_PHPStan_') === 0) {
18
+ if (!in_array('phar', stream_get_wrappers(), true)) {
19
+ throw new \Exception('Phar wrapper is not registered. Please review your php.ini settings.');
20
+ }
21
+
22
+ if (self::$composerAutoloader === null) {
23
+ self::$composerAutoloader = require 'phar://' . __DIR__ . '/phpstan.phar/vendor/autoload.php';
24
+ require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/clue/block-react/src/functions_include.php';
25
+ require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/jetbrains/phpstorm-stubs/PhpStormStubsMap.php';
26
+ require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/react/promise-stream/src/functions_include.php';
27
+ require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/react/promise-timer/src/functions_include.php';
28
+ require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/react/promise/src/functions_include.php';
29
+ require_once 'phar://' . __DIR__ . '/phpstan.phar/vendor/ringcentral/psr7/src/functions_include.php';
30
+ }
31
+ self::$composerAutoloader->loadClass($class);
32
+
33
+ return;
34
+ }
35
+ if (strpos($class, 'PHPStan\\') !== 0 || strpos($class, 'PHPStan\\PhpDocParser\\') === 0) {
36
+ return;
37
+ }
38
+
39
+ if (!in_array('phar', stream_get_wrappers(), true)) {
40
+ throw new \Exception('Phar wrapper is not registered. Please review your php.ini settings.');
41
+ }
42
+
43
+ $filename = str_replace('\\', DIRECTORY_SEPARATOR, $class);
44
+ if (strpos($class, 'PHPStan\\BetterReflection\\') === 0) {
45
+ $filename = substr($filename, strlen('PHPStan\\BetterReflection\\'));
46
+ $filepath = 'phar://' . __DIR__ . '/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/' . $filename . '.php';
47
+ } else {
48
+ $filename = substr($filename, strlen('PHPStan\\'));
49
+ $filepath = 'phar://' . __DIR__ . '/phpstan.phar/src/' . $filename . '.php';
50
+ }
51
+
52
+ if (!file_exists($filepath)) {
53
+ return;
54
+ }
55
+
56
+ require $filepath;
57
+ }
58
+ }
59
+
60
+ spl_autoload_register([PharAutoloader::class, 'loadClass']);
vendor/phpstan/phpstan/composer.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "phpstan/phpstan",
3
+ "description": "PHPStan - PHP Static Analysis Tool",
4
+ "license": ["MIT"],
5
+ "require": {
6
+ "php": "^7.2|^8.0"
7
+ },
8
+ "conflict": {
9
+ "phpstan/phpstan-shim": "*"
10
+ },
11
+ "bin": [
12
+ "phpstan",
13
+ "phpstan.phar"
14
+ ],
15
+ "autoload": {
16
+ "files": ["bootstrap.php"]
17
+ }
18
+ }
vendor/phpstan/phpstan/conf/bleedingEdge.neon ADDED
@@ -0,0 +1,2 @@
 
 
1
+ includes:
2
+ - phar://phpstan.phar/conf/bleedingEdge.neon
vendor/phpstan/phpstan/phpstan ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env php
2
+ <?php
3
+
4
+ declare (strict_types=1);
5
+
6
+ Phar::loadPhar(__DIR__ . '/phpstan.phar', 'phpstan.phar');
7
+
8
+ require 'phar://phpstan.phar/bin/phpstan';
vendor/phpstan/phpstan/phpstan.phar ADDED
Binary file
vendor/phpstan/phpstan/phpstan.phar.asc ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN PGP SIGNATURE-----
2
+
3
+ iQIzBAABCgAdFiEE0yaA1ZV9xxFr4pwUzxoQjQ565yAFAmLX0XwACgkQzxoQjQ56
4
+ 5yAmDw/+KPoaY+vsYXrYjbNcYmXyH+9ca8Yl1WkgqMOAAiojQBAdN+PIeXqdM4P1
5
+ ODJq7SGPqhR5j9dK3k4wxvTkmAVlFHWCbOQS0eCueoV2s0w0Sg9xkut7zTMwwBTp
6
+ I+0TbU9W7DdnDk6k6xoNCNhT8OYpMElmwhS9nChoY2+cwdWJNZ0Lr5JeXwvb5R7W
7
+ YnHUqO/zTIAjwJNdKwb27J9szwL3GQ4nB9gSoKXCFQTIONszfMYNwboy3VlD8m/F
8
+ irh9ZZeZsMlCpEO9Rsqx4QyOvbLy0D2jEOKNYzXPQea9dx9gQvDiWJrVETsQBwkc
9
+ iWJ/HJVhs3ng7iyUfMr8VAPn7rf+3fSqYeQUs5Z5/ubqABF2ZI9/4DIPGsXtqH7q
10
+ b5OTOvSucvRpsxudnJElKWhkCjZUyjYzBqGdZ6erCh+GTiM4uFNB/en/QObfHmP2
11
+ z4D41Dk9peLxstqlrwoLL0sJCHR4fQZFvPKrQ6sKlTKliu1zBc0HcEqq3BFalKF+
12
+ XO2PT1QVNXx/9IqOruKm+M5siY63VKDwE/DXJZZTUPz7GN/Cr9j5Jz3pjq8jL0CR
13
+ e4D+sEu7xXzlJa7MFqg2odZhLTRYuM/DHZCj3cOyQGlYUQ+tZMGsAiix9JyO7XhB
14
+ 1jzEMugtAglPAsmHr0HR/+oz+YDgwQEmQA4VO4l0swCNmjzLITA=
15
+ =LM6h
16
+ -----END PGP SIGNATURE-----
vendor/symfony/polyfill-php73/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2018-2019 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
vendor/symfony/polyfill-php73/Php73.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Polyfill\Php73;
13
+
14
+ /**
15
+ * @author Gabriel Caruso <carusogabriel34@gmail.com>
16
+ * @author Ion Bazan <ion.bazan@gmail.com>
17
+ *
18
+ * @internal
19
+ */
20
+ final class Php73
21
+ {
22
+ public static $startAt = 1533462603;
23
+
24
+ /**
25
+ * @param bool $asNum
26
+ *
27
+ * @return array|float|int
28
+ */
29
+ public static function hrtime($asNum = false)
30
+ {
31
+ $ns = microtime(false);
32
+ $s = substr($ns, 11) - self::$startAt;
33
+ $ns = 1E9 * (float) $ns;
34
+
35
+ if ($asNum) {
36
+ $ns += $s * 1E9;
37
+
38
+ return \PHP_INT_SIZE === 4 ? $ns : (int) $ns;
39
+ }
40
+
41
+ return [$s, (int) $ns];
42
+ }
43
+ }
vendor/symfony/polyfill-php73/README.md ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Symfony Polyfill / Php73
2
+ ========================
3
+
4
+ This component provides functions added to PHP 7.3 core:
5
+
6
+ - [`array_key_first`](https://php.net/array_key_first)
7
+ - [`array_key_last`](https://php.net/array_key_last)
8
+ - [`hrtime`](https://php.net/function.hrtime)
9
+ - [`is_countable`](https://php.net/is_countable)
10
+ - [`JsonException`](https://php.net/JsonException)
11
+
12
+ More information can be found in the
13
+ [main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
14
+
15
+ License
16
+ =======
17
+
18
+ This library is released under the [MIT license](LICENSE).
vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ if (\PHP_VERSION_ID < 70300) {
13
+ class JsonException extends Exception
14
+ {
15
+ }
16
+ }
vendor/symfony/polyfill-php73/bootstrap.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ use Symfony\Polyfill\Php73 as p;
13
+
14
+ if (\PHP_VERSION_ID >= 70300) {
15
+ return;
16
+ }
17
+
18
+ if (!function_exists('is_countable')) {
19
+ function is_countable($value) { return is_array($value) || $value instanceof Countable || $value instanceof ResourceBundle || $value instanceof SimpleXmlElement; }
20
+ }
21
+ if (!function_exists('hrtime')) {
22
+ require_once __DIR__.'/Php73.php';
23
+ p\Php73::$startAt = (int) microtime(true);
24
+ function hrtime($as_number = false) { return p\Php73::hrtime($as_number); }
25
+ }
26
+ if (!function_exists('array_key_first')) {
27
+ function array_key_first(array $array) { foreach ($array as $key => $value) { return $key; } }
28
+ }
29
+ if (!function_exists('array_key_last')) {
30
+ function array_key_last(array $array) { return key(array_slice($array, -1, 1, true)); }
31
+ }
vendor/symfony/polyfill-php73/composer.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "symfony/polyfill-php73",
3
+ "type": "library",
4
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
5
+ "keywords": ["polyfill", "shim", "compatibility", "portable"],
6
+ "homepage": "https://symfony.com",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Nicolas Grekas",
11
+ "email": "p@tchwork.com"
12
+ },
13
+ {
14
+ "name": "Symfony Community",
15
+ "homepage": "https://symfony.com/contributors"
16
+ }
17
+ ],
18
+ "require": {
19
+ "php": ">=7.1"
20
+ },
21
+ "autoload": {
22
+ "psr-4": { "Symfony\\Polyfill\\Php73\\": "" },
23
+ "files": [ "bootstrap.php" ],
24
+ "classmap": [ "Resources/stubs" ]
25
+ },
26
+ "minimum-stability": "dev",
27
+ "extra": {
28
+ "branch-alias": {
29
+ "dev-main": "1.26-dev"
30
+ },
31
+ "thanks": {
32
+ "name": "symfony/polyfill",
33
+ "url": "https://github.com/symfony/polyfill"
34
+ }
35
+ }
36
+ }