PluginProbe
Repeaterly – ACF Repeater, Flexible Content & Dynamic Tags for Elementor / trunk
Repeaterly – ACF Repeater, Flexible Content & Dynamic Tags for Elementor vtrunk
2.2.1 trunk 1.0.0 1.0.1 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1.0 2.2.0
repeaterly / repeaterly.php

repeaterly.php in Repeaterly – ACF Repeater, Flexible Content & Dynamic Tags for Elementor trunk, at repeaterly.php

211 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Plugin Name: Repeaterly
5 * Plugin URI: https://repeaterly.com
6 * Description: Connect ACF repeater, flexible content & relationship fields to Elementor with dynamic tags.
7 * Version: 2.2.1
8 * Author: Techimium
9 * Author URI: https://techimium.com
10 * License: GPLv2 or later
11 * Text Domain: repeaterly
12 * Domain Path: /languages
13 */
14
15 use Repeaterly\Includes\Migrator;
16 use Repeaterly\Includes\Page_Manager;
17 use Repeaterly\Includes\Tag_Manager;
18 use Repeaterly\Includes\Widget_Manager;
19
20 if (! defined('ABSPATH')) {
21 exit; // Exit if accessed directly.
22 }
23
24 if (!class_exists('Repeaterly')) {
25 class Repeaterly
26 {
27 public static $instance;
28 /**
29 * Plugin version
30 */
31 static function plugin_version()
32 {
33 return '2.2.1';
34 }
35
36 /**
37 * Plugin name
38 */
39 static function plugin_name()
40 {
41 return 'Repeaterly';
42 }
43
44 /**
45 * Plugin file
46 */
47 static function plugin_file()
48 {
49 return __FILE__;
50 }
51
52 /**
53 * Plugin url
54 */
55 static function plugin_url()
56 {
57 return trailingslashit(plugin_dir_url(__FILE__));
58 }
59
60 /**
61 * Plugin dir
62 */
63 static function plugin_dir()
64 {
65 return trailingslashit(plugin_dir_path(__FILE__));
66 }
67
68 /**
69 * Is pro version active?
70 */
71 static function is_pro_activated()
72 {
73 return class_exists('Repeaterly_Pro');
74 }
75
76 /**
77 * Link to the pro version
78 */
79 static function pro_link()
80 {
81 return 'https://repeaterly.com';
82 }
83
84 static function run()
85 {
86 if (!self::$instance) {
87 self::$instance = new static();
88 }
89
90 return self::$instance;
91 }
92
93 /**
94 * Init the plugin
95 */
96 public function init()
97 {
98 require_once self::plugin_dir() . 'autoloader.php';
99
100 // Must stay above the compatibility check, which hooks admin_init
101 // to deactivate this plugin outright when Elementor or ACF is
102 // missing. Below it, such a site would never record the version it
103 // is running and any future upgrade step would be skipped.
104 Migrator::run(self::plugin_version());
105
106 if ($this->is_compatible()) {
107 Widget_Manager::init();
108 Tag_Manager::init();
109 }
110
111 Page_Manager::init();
112 }
113
114 function add_premium_link($links)
115 {
116 if (!self::is_pro_activated()) {
117 $links[] = '<a style="color: #FCB214; font-weight: 500;" href="' . self::pro_link() . '" target="_blank">Go Premium</a>';
118 }
119 return $links;
120 }
121
122 function plugin_deactivate()
123 {
124 deactivate_plugins(plugin_basename(__FILE__));
125 }
126
127 public function is_compatible()
128 {
129 if (! did_action('elementor/loaded')) {
130 add_action('admin_notices', [$this, 'admin_notice_missing_main_plugin']);
131 add_action('admin_init', [$this, 'plugin_deactivate']);
132 return false;
133 }
134
135 if (! function_exists('get_field')) {
136 add_action('admin_notices', [$this, 'admin_notice_missing_acf_plugin']);
137 add_action('admin_init', [$this, 'plugin_deactivate']);
138 return false;
139 }
140
141 return true;
142 }
143
144 public function admin_notice_missing_main_plugin(): void
145 {
146 $message = sprintf(
147 /* translators: %1$s: Plugin name (Repeaterly), %2$s: Required plugin name (Elementor). */
148 __('"%1$s" requires "%2$s" to be installed and activated.', 'repeaterly'),
149 '<strong>' . __('Repeaterly', 'repeaterly') . '</strong>',
150 '<strong>' . __('Elementor', 'repeaterly') . '</strong>'
151 );
152
153 $allowed_html = [
154 'strong' => [],
155 ];
156
157 printf(
158 '<div class="notice notice-error is-dismissible"><p>%1$s</p></div>',
159 wp_kses($message, $allowed_html)
160 );
161 }
162
163 public function admin_notice_missing_acf_plugin(): void
164 {
165 $message = sprintf(
166 /* translators: %1$s: Plugin name (Repeaterly), %2$s: Required plugin name (Advanced Custom Fields). */
167 __('"%1$s" requires "%2$s" to be installed and activated.', 'repeaterly'),
168 '<strong>' . __('Repeaterly', 'repeaterly') . '</strong>',
169 '<strong>' . __('Advanced Custom Fields', 'repeaterly') . '</strong>'
170 );
171
172 $allowed_html = [
173 'strong' => [],
174 ];
175
176 printf(
177 '<div class="notice notice-error is-dismissible"><p>%1$s</p></div>',
178 wp_kses($message, $allowed_html)
179 );
180 }
181
182 /**
183 * Deleting the plugin must leave nothing behind in wp_options.
184 *
185 * The autoloader is required here rather than assumed: uninstall runs
186 * by including this file and calling straight into this method, so
187 * init() — which is where the autoloader is normally registered — never
188 * fires on this path.
189 */
190 public static function uninstall()
191 {
192 require_once self::plugin_dir() . 'autoloader.php';
193
194 delete_option(Migrator::$version_option);
195 }
196
197 /**
198 * Run the plugin
199 */
200 public function __construct()
201 {
202 add_action('plugins_loaded', [$this, 'init'], 100);
203 add_filter('plugin_action_links_' . plugin_basename(__FILE__), [$this, 'add_premium_link']);
204
205 register_uninstall_hook(__FILE__, ['Repeaterly', 'uninstall']);
206 }
207 }
208
209 Repeaterly::run();
210 }
211