Amazon Associates Link Builder - Version 1.3

Version Description

This update includes a few minor fixes. In particular, you will no longer need to back up your custom templates when updating the plugin in future.

Download this release

Release Info

Developer amazonlinkbuilder
Plugin Icon 128x128 Amazon Associates Link Builder
Version 1.3
Comparing to
See all releases

Code changes from version 1.2 to 1.3

aalb_config.php CHANGED
@@ -13,7 +13,7 @@ and limitations under the License.
13
  */
14
 
15
  //version
16
- define('AALB_PLUGIN_CURRENT_VERSION','1.2');
17
 
18
  //paths
19
  define('AALB_PLUGIN_DIR', plugin_dir_path( __FILE__ ));
@@ -142,6 +142,7 @@ define('AALB_AWS_SECRET_KEY', 'aalb_aws_secret_key');
142
  define('AALB_CRED_CONFIG_GROUP', 'aalb_cred_config_group');
143
  define('AALB_STORE_ID_NAMES', 'aalb_store_id_names');
144
  define('AALB_SHOW_HTTP_WARNING_ONCE', 'aalb_show_http_warning_once');
 
145
 
146
  //Masking constant
147
  define('AALB_AWS_SECRET_KEY_MASK', '••••••••••••••••••••••••••••••••••••••••');
13
  */
14
 
15
  //version
16
+ define('AALB_PLUGIN_CURRENT_VERSION','1.3');
17
 
18
  //paths
19
  define('AALB_PLUGIN_DIR', plugin_dir_path( __FILE__ ));
142
  define('AALB_CRED_CONFIG_GROUP', 'aalb_cred_config_group');
143
  define('AALB_STORE_ID_NAMES', 'aalb_store_id_names');
144
  define('AALB_SHOW_HTTP_WARNING_ONCE', 'aalb_show_http_warning_once');
145
+ define('AALB_PLUGIN_VERSION', 'aalb_plugin_version');
146
 
147
  //Masking constant
148
  define('AALB_AWS_SECRET_KEY_MASK', '••••••••••••••••••••••••••••••••••••••••');
admin/aalb_admin.php CHANGED
@@ -27,11 +27,13 @@ class Aalb_Admin {
27
  private $paapi_helper;
28
  private $remote_loader;
29
  private $tracking_api_helper;
 
30
 
31
  public function __construct() {
32
  $this->paapi_helper = new Aalb_Paapi_Helper();
33
  $this->remote_loader = new Aalb_Remote_Loader();
34
  $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
 
35
  add_action('admin_notices', array($this, 'aalb_plugin_activation')) ;
36
  }
37
 
@@ -98,6 +100,30 @@ class Aalb_Admin {
98
  );
99
  }
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  /**
102
  * Prints the aalb-admin sidebar search box.
103
  *
@@ -162,5 +188,23 @@ class Aalb_Admin {
162
  echo $this->tracking_api_helper->get_link_id($shortcode_name, $shortcode_params_json_string);
163
  wp_die();
164
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  }
166
  ?>
27
  private $paapi_helper;
28
  private $remote_loader;
29
  private $tracking_api_helper;
30
+ private $helper;
31
 
32
  public function __construct() {
33
  $this->paapi_helper = new Aalb_Paapi_Helper();
34
  $this->remote_loader = new Aalb_Remote_Loader();
35
  $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
36
+ $this->helper = new Aalb_Helper();
37
  add_action('admin_notices', array($this, 'aalb_plugin_activation')) ;
38
  }
39
 
100
  );
101
  }
102
 
103
+ /**
104
+ * Block which run whenever the plugin has been updated.
105
+ * Refreshes the templates
106
+ *
107
+ * @since 1.3
108
+ */
109
+ public function handle_plugin_update() {
110
+ global $wp_filesystem;
111
+ $this->helper->aalb_initialize_wp_filesystem_api();
112
+ $this->helper->refresh_template_list();
113
+ update_option(AALB_PLUGIN_VERSION, AALB_PLUGIN_CURRENT_VERSION);
114
+ }
115
+
116
+ /**
117
+ * Checks if the plugin has been updated and calls required method
118
+ *
119
+ * @since 1.3
120
+ */
121
+ public function check_update() {
122
+ if(AALB_PLUGIN_CURRENT_VERSION !== get_option(AALB_PLUGIN_VERSION)) {
123
+ $this->handle_plugin_update();
124
+ }
125
+ }
126
+
127
  /**
128
  * Prints the aalb-admin sidebar search box.
129
  *
188
  echo $this->tracking_api_helper->get_link_id($shortcode_name, $shortcode_params_json_string);
189
  wp_die();
190
  }
191
+
192
+ /**
193
+ * Supports the ajax request for getting template contents for custom templates
194
+ *
195
+ * @since 1.3
196
+ */
197
+ public function get_custom_template_content() {
198
+ global $wp_filesystem;
199
+ $this->helper->aalb_initialize_wp_filesystem_api();
200
+ $css_file = $_POST['css'];
201
+ $mustache_file = $_POST['mustache'];
202
+ $css_file_content = $wp_filesystem->get_contents($css_file);
203
+ $mustache_file_content = $wp_filesystem->get_contents($mustache_file);
204
+
205
+ $response = array("css" => $css_file_content, "mustache" => $mustache_file_content);
206
+ echo json_encode($response);
207
+ wp_die();
208
+ }
209
  }
210
  ?>
admin/sidebar/js/aalb_template.js CHANGED
@@ -48,23 +48,31 @@ function aalb_template_select_template_onchange(element) {
48
  set_template_read_only(false);
49
  jQuery('#aalb_template_name').removeAttr("readonly");
50
  jQuery('#aalb_template_name').val('');
 
51
  jQuery('#clone_template').attr('disabled','disabled');
52
  } else {
53
  jQuery('#clone_template').removeAttr('disabled');
54
  jQuery('#aalb_template_name').val(element.value);
55
  jQuery('#aalb_template_name').attr("readonly", "readonly");
56
- base = wp_opt.plugin_url + "template/" + element.value;
57
- jQuery.get(base+".css", function(data) {
58
- codeMirrorCss.setValue(data);
59
- });
60
- jQuery.get(base+".mustache", function(data) {
61
- codeMirrorHtml.setValue(data);
62
- });
63
  //Make the Amazon Default templates as Read-Only
64
  if(wp_opt.aalb_default_templates.split(",").indexOf(element.value)>=0) {
 
65
  set_template_read_only(true);
 
 
 
 
 
 
 
66
  } else {
 
67
  set_template_read_only(false);
 
 
 
 
 
68
  }
69
  }
70
  }
@@ -79,6 +87,7 @@ function clone_existing_template() {
79
  jQuery('#aalb_template_name').removeAttr("readonly");
80
  jQuery('#aalb_template_name').val('CopyOf-' + templateNameToClone);
81
  jQuery('#clone_template').attr('disabled','disabled');
 
82
  //Add CSS Prefix for Amazon Default Templates to prevent style overlapping for clones
83
  if(wp_opt.aalb_default_templates.split(",").indexOf(templateNameToClone)>=0) {
84
  set_template_read_only(false);
48
  set_template_read_only(false);
49
  jQuery('#aalb_template_name').removeAttr("readonly");
50
  jQuery('#aalb_template_name').val('');
51
+ jQuery('#submit_remove').attr('disabled','disabled');
52
  jQuery('#clone_template').attr('disabled','disabled');
53
  } else {
54
  jQuery('#clone_template').removeAttr('disabled');
55
  jQuery('#aalb_template_name').val(element.value);
56
  jQuery('#aalb_template_name').attr("readonly", "readonly");
 
 
 
 
 
 
 
57
  //Make the Amazon Default templates as Read-Only
58
  if(wp_opt.aalb_default_templates.split(",").indexOf(element.value)>=0) {
59
+ jQuery('#submit_remove').attr('disabled','disabled');
60
  set_template_read_only(true);
61
+ base = wp_opt.plugin_url + "template/" + element.value;
62
+ jQuery.get(base+".css", function(data) {
63
+ codeMirrorCss.setValue(data);
64
+ });
65
+ jQuery.get(base+".mustache", function(data) {
66
+ codeMirrorHtml.setValue(data);
67
+ });
68
  } else {
69
+ jQuery('#submit_remove').removeAttr('disabled');
70
  set_template_read_only(false);
71
+ base = wp_opt.upload_url + element.value;
72
+ jQuery.post( wp_opt.ajax_url, { "action" : "get_custom_template_content", "css":base+".css", "mustache":base+".mustache"}, function(json) {
73
+ codeMirrorCss.setValue(json.css);
74
+ codeMirrorHtml.setValue(json.mustache);
75
+ }, "json");
76
  }
77
  }
78
  }
87
  jQuery('#aalb_template_name').removeAttr("readonly");
88
  jQuery('#aalb_template_name').val('CopyOf-' + templateNameToClone);
89
  jQuery('#clone_template').attr('disabled','disabled');
90
+ jQuery('#submit_remove').attr('disabled','disabled');
91
  //Add CSS Prefix for Amazon Default Templates to prevent style overlapping for clones
92
  if(wp_opt.aalb_default_templates.split(",").indexOf(templateNameToClone)>=0) {
93
  set_template_read_only(false);
admin/sidebar/partials/aalb_templates.php CHANGED
@@ -13,6 +13,8 @@ and limitations under the License.
13
  */
14
 
15
  include 'aalb_admin_ui_common.php';
 
 
16
 
17
  /**
18
  * Verifies whether file exists and is writable
@@ -37,7 +39,8 @@ function aalb_verify_file_is_writable($file) {
37
  * @return bool TRUE if write was successful, throws exception otherwise
38
  */
39
  function aalb_write_to_file($file,$content) {
40
- if(file_put_contents($file, $content)===FALSE)
 
41
  throw new Exception("Save Failed. Error writing contents to file: " . $file);
42
 
43
  return true;
@@ -70,15 +73,43 @@ function aalb_save_template($file, $content_html, $content_css) {
70
  }
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  //Flag to check if the save is failed.
74
  $saveFailed = false;
 
 
 
 
 
 
 
75
  $aalb_template_names = get_option(AALB_TEMPLATE_NAMES);
 
76
 
77
  if (!empty($_POST["submit"])) {
78
  $aalb_template_name = stripslashes($_POST["aalb_template_name"]);
79
  $aalb_template_template_html_box = stripslashes($_POST["aalb_template_template_html_box"]);
80
  $aalb_template_template_css_box = stripslashes($_POST["aalb_template_template_css_box"]);
81
  $dir = AALB_TEMPLATE_DIR;
 
82
  if ($_POST["submit"] == "Save") {
83
  if ($_POST["aalb_template_list"] == "new") {
84
  if (empty($aalb_template_name)) {
@@ -87,8 +118,8 @@ if (!empty($_POST["submit"])) {
87
  //The template name can only be alphanumeric characters plus hyphens (-) and underscores (_)
88
  aalb_error_notice("Save Failed. Only alphanumeric characters allowed for template name.");
89
  } else {
90
- if (!is_dir($dir) or !is_writable($dir)) {
91
- aalb_error_notice($dir . " doesn't exist or is not writable. Please set up the directory permissions correctly.");
92
  } else {
93
  //Check if template of that name already exists
94
  if (in_array($aalb_template_name, $aalb_template_names)) {
@@ -97,7 +128,7 @@ if (!empty($_POST["submit"])) {
97
  $saveFailed = true;
98
  } else {
99
  try {
100
- aalb_save_template($dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box);
101
  array_push($aalb_template_names, $aalb_template_name);
102
  update_option('aalb_template_names', $aalb_template_names);
103
  } catch (Exception $e) {
@@ -108,9 +139,13 @@ if (!empty($_POST["submit"])) {
108
  }
109
  } else {
110
  try {
111
- aalb_save_template($dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box);
 
 
 
 
 
112
  //clears the cached rendered templates whenever the template is modified
113
- $helper = new Aalb_Helper();
114
  $helper->clear_cache_for_template($aalb_template_name);
115
  } catch (Exception $e) {
116
  aalb_error_notice($e->getMessage());
@@ -122,16 +157,22 @@ if (!empty($_POST["submit"])) {
122
  } else {
123
  $aalb_template_names = array_diff($aalb_template_names, array($aalb_template_name));
124
  update_option('aalb_template_names', $aalb_template_names);
125
- if (unlink($dir . $aalb_template_name . ".mustache")) {
126
- aalb_success_notice("Successfully removed Template HTML");
127
- } else {
128
- aalb_error_notice("Couldn't remove Template HTML. Please manually remove " . $dir . $aalb_template_name . ".mustache");
129
- }
130
- if (unlink($dir . $aalb_template_name . ".css")) {
131
- aalb_success_notice("Successfully removed Template CSS");
132
  } else {
133
- aalb_error_notice("Couldn't remove Template CSS. Please manually remove " . $dir . $aalb_template_name . ".css");
 
 
 
 
 
 
 
 
 
134
  }
 
135
  $aalb_template_name = "";
136
  $aalb_template_template_html_box = "";
137
  $aalb_template_template_css_box = "";
@@ -146,7 +187,7 @@ wp_enqueue_script('codemirror_mode_css_js', CODEMIRROR_MODE_CSS_JS);
146
  wp_enqueue_style('codemirror_css', CODEMIRROR_CSS);
147
 
148
  wp_enqueue_script('aalb_template_js', AALB_TEMPLATE_JS, array('jquery', 'codemirror_js', 'codemirror_mode_xml_js', 'codemirror_mode_css_js'));
149
- wp_localize_script('aalb_template_js', 'wp_opt', array('plugin_url' => AALB_PLUGIN_URL, 'aalb_default_templates' => AALB_AMAZON_TEMPLATE_NAMES));
150
 
151
  ?>
152
  <div class="wrap">
@@ -172,20 +213,23 @@ wp_localize_script('aalb_template_js', 'wp_opt', array('plugin_url' => AALB_PLUG
172
  </tr>
173
  <tr>
174
  <th scope="row" style="width:15%;">Set a name for your template</th>
175
- <td><input type="text" id="aalb_template_name" name="aalb_template_name" style="width:50%" value="<?=$aalb_template_name?>" /></td>
 
 
 
176
  </tr>
177
  <tr>
178
  <th scope="row" style="width:15%;">Add HTML for your template</th>
179
- <td><textarea id="aalb_template_template_html_box" name="aalb_template_template_html_box"><?=$aalb_template_template_html_box?></textarea></td>
180
  </tr>
181
  <tr>
182
  <th scope="row" style="width:15%;">Add CSS for your template</th>
183
- <td><textarea id="aalb_template_template_css_box" name="aalb_template_template_css_box"><?=$aalb_template_template_css_box?></textarea></td>
184
  </tr>
185
  </table>
186
  <p class="submit">
187
  <input name="submit" id="submit_save" class="button button-primary" value="Save" type="submit">
188
- <input name="submit" id="submit_remove" class="button button-secondary" value="Remove" type="submit">
189
  </p>
190
  </form>
191
  </div>
13
  */
14
 
15
  include 'aalb_admin_ui_common.php';
16
+ $helper = new Aalb_Helper();
17
+ $helper->aalb_initialize_wp_filesystem_api();
18
 
19
  /**
20
  * Verifies whether file exists and is writable
39
  * @return bool TRUE if write was successful, throws exception otherwise
40
  */
41
  function aalb_write_to_file($file,$content) {
42
+ global $wp_filesystem;
43
+ if($wp_filesystem->put_contents($file,$content) === FALSE)
44
  throw new Exception("Save Failed. Error writing contents to file: " . $file);
45
 
46
  return true;
73
  }
74
  }
75
 
76
+ /**
77
+ * Finds any change in the current list of templates.
78
+ * Flags a note if either a template is added or removed.
79
+ *
80
+ * @since 1.3
81
+ * @param array $aalb_current_template_names Current list of templates
82
+ * @param array $aalb_template_names Refreshed list of templates
83
+ */
84
+ function aalb_find_template_change($aalb_current_template_names, $aalb_template_names) {
85
+ $templates_added = array_diff($aalb_template_names, $aalb_current_template_names);
86
+ $templates_deleted = array_diff($aalb_current_template_names, $aalb_template_names);
87
+ if(sizeof($templates_added) > 0) {
88
+ aalb_info_notice(sizeof($templates_added) . " template(s) added: " . implode(', ', $templates_added));
89
+ }
90
+ if(sizeof($templates_deleted) > 0) {
91
+ aalb_info_notice(sizeof($templates_deleted) . " template(s) deleted: " . implode(', ', $templates_deleted));
92
+ }
93
+ }
94
+
95
  //Flag to check if the save is failed.
96
  $saveFailed = false;
97
+ $aalb_default_templates = explode(",", AALB_AMAZON_TEMPLATE_NAMES);
98
+
99
+ $aalb_current_template_names = get_option(AALB_TEMPLATE_NAMES);
100
+
101
+ //Refresh templates
102
+ $helper->refresh_template_list();
103
+
104
  $aalb_template_names = get_option(AALB_TEMPLATE_NAMES);
105
+ aalb_find_template_change($aalb_current_template_names, $aalb_template_names);
106
 
107
  if (!empty($_POST["submit"])) {
108
  $aalb_template_name = stripslashes($_POST["aalb_template_name"]);
109
  $aalb_template_template_html_box = stripslashes($_POST["aalb_template_template_html_box"]);
110
  $aalb_template_template_css_box = stripslashes($_POST["aalb_template_template_css_box"]);
111
  $dir = AALB_TEMPLATE_DIR;
112
+ $aalb_template_upload_dir = $helper->get_template_upload_directory();
113
  if ($_POST["submit"] == "Save") {
114
  if ($_POST["aalb_template_list"] == "new") {
115
  if (empty($aalb_template_name)) {
118
  //The template name can only be alphanumeric characters plus hyphens (-) and underscores (_)
119
  aalb_error_notice("Save Failed. Only alphanumeric characters allowed for template name.");
120
  } else {
121
+ if (!is_dir($aalb_template_upload_dir) or !is_writable($aalb_template_upload_dir)) {
122
+ aalb_error_notice($aalb_template_upload_dir . " doesn't exist or is not writable. Please set up Read-Write permissions for <ApacheHomeFolder>/wordpress/wp-content/uploads/amazon-associates-link-builder/template/");
123
  } else {
124
  //Check if template of that name already exists
125
  if (in_array($aalb_template_name, $aalb_template_names)) {
128
  $saveFailed = true;
129
  } else {
130
  try {
131
+ aalb_save_template($aalb_template_upload_dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box);
132
  array_push($aalb_template_names, $aalb_template_name);
133
  update_option('aalb_template_names', $aalb_template_names);
134
  } catch (Exception $e) {
139
  }
140
  } else {
141
  try {
142
+ if(in_array($aalb_template_name, $aalb_default_templates)) {
143
+ aalb_save_template($dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box);
144
+ } else {
145
+ aalb_save_template($aalb_template_upload_dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box);
146
+ }
147
+
148
  //clears the cached rendered templates whenever the template is modified
 
149
  $helper->clear_cache_for_template($aalb_template_name);
150
  } catch (Exception $e) {
151
  aalb_error_notice($e->getMessage());
157
  } else {
158
  $aalb_template_names = array_diff($aalb_template_names, array($aalb_template_name));
159
  update_option('aalb_template_names', $aalb_template_names);
160
+ if(in_array($aalb_template_name, $aalb_default_templates)) {
161
+ //If Default Amazon Template is Removed
162
+ aalb_error_notice("Couldn't remove Default Template");
 
 
 
 
163
  } else {
164
+ if (unlink($aalb_template_upload_dir . $aalb_template_name . ".mustache")) {
165
+ aalb_success_notice("Successfully removed Template HTML");
166
+ } else {
167
+ aalb_error_notice("Couldn't remove Template HTML. Please manually remove " . $dir . $aalb_template_name . ".mustache");
168
+ }
169
+ if (unlink($aalb_template_upload_dir . $aalb_template_name . ".css")) {
170
+ aalb_success_notice("Successfully removed Template CSS");
171
+ } else {
172
+ aalb_error_notice("Couldn't remove Template CSS. Please manually remove " . $dir . $aalb_template_name . ".css");
173
+ }
174
  }
175
+
176
  $aalb_template_name = "";
177
  $aalb_template_template_html_box = "";
178
  $aalb_template_template_css_box = "";
187
  wp_enqueue_style('codemirror_css', CODEMIRROR_CSS);
188
 
189
  wp_enqueue_script('aalb_template_js', AALB_TEMPLATE_JS, array('jquery', 'codemirror_js', 'codemirror_mode_xml_js', 'codemirror_mode_css_js'));
190
+ wp_localize_script('aalb_template_js', 'wp_opt', array('ajax_url' => admin_url('admin-ajax.php'), 'upload_url' => $helper->get_template_upload_directory(), 'plugin_url' => AALB_PLUGIN_URL, 'aalb_default_templates' => AALB_AMAZON_TEMPLATE_NAMES));
191
 
192
  ?>
193
  <div class="wrap">
213
  </tr>
214
  <tr>
215
  <th scope="row" style="width:15%;">Set a name for your template</th>
216
+ <td>
217
+ <input type="text" id="aalb_template_name" name="aalb_template_name" style="width:50%" value="<?=(isset($aalb_template_name))?$aalb_template_name:''?>" />
218
+ <span style="font-size:0.9em;">[<a href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToCreateCustomTemplates.pdf" target="_blank">Guide for creating custom templates</a>]</span>
219
+ </td>
220
  </tr>
221
  <tr>
222
  <th scope="row" style="width:15%;">Add HTML for your template</th>
223
+ <td><textarea id="aalb_template_template_html_box" name="aalb_template_template_html_box"><?=(isset($aalb_template_template_html_box))?$aalb_template_template_html_box:''?></textarea></td>
224
  </tr>
225
  <tr>
226
  <th scope="row" style="width:15%;">Add CSS for your template</th>
227
+ <td><textarea id="aalb_template_template_css_box" name="aalb_template_template_css_box"><?=(isset($aalb_template_template_css_box))?$aalb_template_template_css_box:''?></textarea></td>
228
  </tr>
229
  </table>
230
  <p class="submit">
231
  <input name="submit" id="submit_save" class="button button-primary" value="Save" type="submit">
232
+ <input name="submit" id="submit_remove" class="button button-secondary" value="Remove" type="submit" disabled>
233
  </p>
234
  </form>
235
  </div>
amazon-associates-link-builder.php CHANGED
@@ -7,7 +7,7 @@
7
  /*
8
  Plugin Name: Amazon Associates Link Builder
9
  Description: Amazon Associates Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to search for products in the Amazon catalog, access real-time price and availability information, and easily create links in your posts to products on Amazon.com. You will be able to generate text links, create custom ad units, or take advantage of out-of-the-box widgets that we’ve designed and included with the plugin.
10
- Version: 1.2
11
  Author: Amazon Associates Program
12
  Author URI: https://affiliate-program.amazon.com/
13
  License: GPLv2
@@ -93,6 +93,7 @@ register_deactivation_hook( __FILE__, 'aalb_deactivate' );
93
  function aalb_uninstall() {
94
  $aalb_deactivator = new Aalb_Deactivator();
95
  $aalb_deactivator->remove_settings();
 
96
  }
97
 
98
  register_uninstall_hook( __FILE__, 'aalb_uninstall' );
7
  /*
8
  Plugin Name: Amazon Associates Link Builder
9
  Description: Amazon Associates Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to search for products in the Amazon catalog, access real-time price and availability information, and easily create links in your posts to products on Amazon.com. You will be able to generate text links, create custom ad units, or take advantage of out-of-the-box widgets that we’ve designed and included with the plugin.
10
+ Version: 1.3
11
  Author: Amazon Associates Program
12
  Author URI: https://affiliate-program.amazon.com/
13
  License: GPLv2
93
  function aalb_uninstall() {
94
  $aalb_deactivator = new Aalb_Deactivator();
95
  $aalb_deactivator->remove_settings();
96
+ $aalb_deactivator->remove_uploads_dir();
97
  }
98
 
99
  register_uninstall_hook( __FILE__, 'aalb_uninstall' );
includes/aalb_activator.php CHANGED
@@ -23,22 +23,19 @@ and limitations under the License.
23
  */
24
  class Aalb_Activator {
25
 
 
 
 
 
 
 
26
  /**
27
  * Add the template names to the database from the filesystem.
28
  *
29
  * @since 1.0.0
30
  */
31
  public function load_templates() {
32
- $aalb_templates = array();
33
- if ($handle = opendir(AALB_TEMPLATE_DIR)) {
34
- while (false !== ($entry = readdir($handle))) {
35
- if ($this->aalb_get_file_extension($entry) == "css") {
36
- $aalb_templates[] = $this->aalb_get_file_name($entry);
37
- }
38
- }
39
- closedir($handle);
40
- }
41
- update_option(AALB_TEMPLATE_NAMES, $aalb_templates);
42
  }
43
 
44
  /**
@@ -66,28 +63,6 @@ class Aalb_Activator {
66
  public function load_store_ids() {
67
  update_option(AALB_STORE_IDS, '');
68
  }
69
-
70
- /**
71
- * Gets the extension of the file
72
- *
73
- * @since 1.0.0
74
- * @param string $file_name Name of the file
75
- * @return string Extension of the file
76
- */
77
- function aalb_get_file_extension($file_name) {
78
- return substr(strrchr($file_name,'.'),1);
79
- }
80
-
81
- /**
82
- * Gets the name of the file without the extension
83
- *
84
- * @since 1.0.0
85
- * @param string $file_name Name of the file
86
- * @return string Name of the file without the extension
87
- */
88
- function aalb_get_file_name($file_name) {
89
- return substr($file_name, 0, strlen($file_name) - strlen(strrchr($file_name,'.')));
90
- }
91
  }
92
 
93
  ?>
23
  */
24
  class Aalb_Activator {
25
 
26
+ protected $helper;
27
+
28
+ public function __construct() {
29
+ $this->helper = new Aalb_Helper();
30
+ }
31
+
32
  /**
33
  * Add the template names to the database from the filesystem.
34
  *
35
  * @since 1.0.0
36
  */
37
  public function load_templates() {
38
+ $this->helper->refresh_template_list();
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
  /**
63
  public function load_store_ids() {
64
  update_option(AALB_STORE_IDS, '');
65
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
67
 
68
  ?>
includes/aalb_deactivator.php CHANGED
@@ -55,6 +55,18 @@ class Aalb_Deactivator {
55
  public function remove_cache() {
56
  $this->helper->clear_cache_for_substring('');
57
  }
 
 
 
 
 
 
 
 
 
 
 
 
58
  }
59
 
60
  ?>
55
  public function remove_cache() {
56
  $this->helper->clear_cache_for_substring('');
57
  }
58
+
59
+ /**
60
+ * Recursively remove the template uploads dir
61
+ *
62
+ * @since 1.3
63
+ */
64
+ public function remove_uploads_dir() {
65
+ global $wp_filesystem;
66
+ $this->helper->aalb_initialize_wp_filesystem_api();
67
+ $upload_dir = $this->helper->get_template_upload_directory();
68
+ $wp_filesystem->rmdir($upload_dir, true);
69
+ }
70
  }
71
 
72
  ?>
includes/aalb_helper.php CHANGED
@@ -66,8 +66,8 @@ class Aalb_Helper{
66
  */
67
  public function clear_cache_for_substring($substring) {
68
  global $wpdb;
69
-
70
- $statement = 'DELETE from wp_options
71
  WHERE option_name like %s or option_name like %s';
72
  $transient_timeout_cache = '_transient_timeout_aalb%' . $substring . '%';
73
  $transient_cache = '_transient_aalb%' . $substring . '%';
@@ -100,12 +100,12 @@ class Aalb_Helper{
100
  */
101
  public function clear_expired_transients() {
102
  global $wpdb;
103
-
104
  $transients_prefix = esc_sql( "_transient_timeout_aalb%" );
105
  $sql = $wpdb -> prepare (
106
  '
107
  SELECT option_name
108
- FROM wp_options
109
  WHERE option_name LIKE %s
110
  ',
111
  $transients_prefix
@@ -142,16 +142,6 @@ class Aalb_Helper{
142
  return explode("\r\n", strlen(get_option(AALB_STORE_ID_NAMES))?get_option(AALB_STORE_ID_NAMES):AALB_DEFAULT_STORE_ID_NAME);
143
  }
144
 
145
- /**
146
- * Fetches the current plugins version number
147
- *
148
- * @since 1.0.0
149
- * @return string Version number of the plugin
150
- */
151
- function get_plugin_version() {
152
- return AALB_PLUGIN_CURRENT_VERSION;
153
- }
154
-
155
  /**
156
  * Fetches the Wordpress version number
157
  *
@@ -162,5 +152,121 @@ class Aalb_Helper{
162
  global $wp_version;
163
  return $wp_version;
164
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  }
166
  ?>
66
  */
67
  public function clear_cache_for_substring($substring) {
68
  global $wpdb;
69
+ $table_prefix = $wpdb->prefix;
70
+ $statement = 'DELETE from ' . $table_prefix . 'options
71
  WHERE option_name like %s or option_name like %s';
72
  $transient_timeout_cache = '_transient_timeout_aalb%' . $substring . '%';
73
  $transient_cache = '_transient_aalb%' . $substring . '%';
100
  */
101
  public function clear_expired_transients() {
102
  global $wpdb;
103
+ $table_prefix = $wpdb->prefix;
104
  $transients_prefix = esc_sql( "_transient_timeout_aalb%" );
105
  $sql = $wpdb -> prepare (
106
  '
107
  SELECT option_name
108
+ FROM ' . $table_prefix . 'options
109
  WHERE option_name LIKE %s
110
  ',
111
  $transients_prefix
142
  return explode("\r\n", strlen(get_option(AALB_STORE_ID_NAMES))?get_option(AALB_STORE_ID_NAMES):AALB_DEFAULT_STORE_ID_NAME);
143
  }
144
 
 
 
 
 
 
 
 
 
 
 
145
  /**
146
  * Fetches the Wordpress version number
147
  *
152
  global $wp_version;
153
  return $wp_version;
154
  }
155
+
156
+ /**
157
+ * Fetches the Uploads Directory where custom templates are stored.
158
+ * If the dir doesn't exists, it is created and returned.
159
+ *
160
+ * @since 1.3
161
+ * @return Full directory path of the template uploads directory
162
+ */
163
+ public function get_template_upload_directory() {
164
+ global $wp_filesystem;
165
+ $this->aalb_initialize_wp_filesystem_api();
166
+ $aalb_template_upload_dir = $this->get_template_upload_directory_name($wp_filesystem);
167
+ if ( ! $wp_filesystem->is_dir($aalb_template_upload_dir) ) {
168
+ if(! $this->create_template_upload_dir($aalb_template_upload_dir)) {
169
+ return false;
170
+ }
171
+ }
172
+ return $aalb_template_upload_dir;
173
+ }
174
+
175
+ /**
176
+ * Creates the Uploads Directory where custom templates are stored
177
+ *
178
+ * @since 1.3
179
+ * @return TRUE on successful creation of the dir; FALSE otherwise
180
+ */
181
+ public function create_template_upload_dir($aalb_template_upload_dir) {
182
+ global $wp_filesystem;
183
+ if(!wp_mkdir_p($aalb_template_upload_dir)) {
184
+ error_log("Error Creating Dir . " . $aalb_template_upload_dir . ". Please set the folder permissions correctly.");
185
+ return false;
186
+ }
187
+ return true;
188
+ }
189
+
190
+ /**
191
+ * Gets the template uploads dir name.
192
+ *
193
+ * @since 1.3
194
+ * @return full path of the template uploads directory
195
+ */
196
+ public function get_template_upload_directory_name() {
197
+ global $wp_filesystem;
198
+ $upload_dir = wp_upload_dir();
199
+ return $wp_filesystem->find_folder( $upload_dir['basedir'] ) . 'amazon-associates-link-builder/template/';
200
+ }
201
+
202
+ /**
203
+ * Loads necessary files and initializes WP Filesystem API
204
+ *
205
+ * @since 1.3
206
+ */
207
+ public function aalb_initialize_wp_filesystem_api() {
208
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
209
+ WP_Filesystem();
210
+ }
211
+
212
+ /**
213
+ * Gets the extension of the file
214
+ *
215
+ * @since 1.0
216
+ * @param string $file_name Name of the file
217
+ * @return string Extension of the file
218
+ */
219
+ public function aalb_get_file_extension($file_name) {
220
+ return substr(strrchr($file_name,'.'),1);
221
+ }
222
+
223
+ /**
224
+ * Gets the name of the file without the extension
225
+ *
226
+ * @since 1.0
227
+ * @param string $file_name Name of the file
228
+ * @return string Name of the file without the extension
229
+ */
230
+ function aalb_get_file_name($file_name) {
231
+ return substr($file_name, 0, strlen($file_name) - strlen(strrchr($file_name,'.')));
232
+ }
233
+
234
+ /**
235
+ * Reads both the templates/ and the uploads/ directory and updates the template list.
236
+ * Helper to replicate the current status of the default and custom templates
237
+ *
238
+ * @since 1.3
239
+ */
240
+ public function refresh_template_list() {
241
+ global $wp_filesystem;
242
+ $this->aalb_initialize_wp_filesystem_api();
243
+
244
+ $aalb_templates = array();
245
+ $upload_dir = $this->get_template_upload_directory();
246
+
247
+ //Read and update templates from the plugin's template/ directory (Default Templates)
248
+ if ($handle = opendir(AALB_TEMPLATE_DIR)) {
249
+ while (false !== ($entry = readdir($handle))) {
250
+ $file_name = $this->aalb_get_file_name($entry);
251
+ $file_extension = $this->aalb_get_file_extension($entry);
252
+ if ($file_extension == "css" and file_exists(AALB_TEMPLATE_DIR . $file_name . '.mustache')) {
253
+ $aalb_templates[] = $file_name;
254
+ }
255
+ }
256
+ closedir($handle);
257
+ }
258
+
259
+ //Read and update templates from the uploads/ directory (Custom Templates)
260
+ if ($handle = opendir($upload_dir)) {
261
+ while (false !== ($entry = readdir($handle))) {
262
+ $file_name = $this->aalb_get_file_name($entry);
263
+ $file_extension = $this->aalb_get_file_extension($entry);
264
+ if ($file_extension == "css" and file_exists($upload_dir . $file_name . '.mustache')) {
265
+ $aalb_templates[] = $file_name;
266
+ }
267
+ }
268
+ }
269
+ update_option(AALB_TEMPLATE_NAMES, $aalb_templates);
270
+ }
271
  }
272
  ?>
includes/aalb_manager.php CHANGED
@@ -47,7 +47,9 @@ class Aalb_Manager {
47
  $this->hook_loader->add_action( 'admin_print_footer_scripts', $aalb_admin, 'add_quicktags');
48
  $this->hook_loader->add_action( 'wp_ajax_get_item_search_result', $aalb_admin, 'get_item_search_result');
49
  $this->hook_loader->add_action( 'wp_ajax_get_link_code', $aalb_admin, 'get_link_code');
 
50
  $this->hook_loader->add_action( 'media_buttons', $aalb_admin, 'admin_display_callback');
 
51
 
52
  $aalb_sidebar = new Aalb_Sidebar();
53
  $this->hook_loader->add_action( 'admin_init', $aalb_sidebar, 'register_cred_config_group');
47
  $this->hook_loader->add_action( 'admin_print_footer_scripts', $aalb_admin, 'add_quicktags');
48
  $this->hook_loader->add_action( 'wp_ajax_get_item_search_result', $aalb_admin, 'get_item_search_result');
49
  $this->hook_loader->add_action( 'wp_ajax_get_link_code', $aalb_admin, 'get_link_code');
50
+ $this->hook_loader->add_action( 'wp_ajax_get_custom_template_content', $aalb_admin, 'get_custom_template_content');
51
  $this->hook_loader->add_action( 'media_buttons', $aalb_admin, 'admin_display_callback');
52
+ $this->hook_loader->add_action( 'plugins_loaded', $aalb_admin, 'check_update');
53
 
54
  $aalb_sidebar = new Aalb_Sidebar();
55
  $this->hook_loader->add_action( 'admin_init', $aalb_sidebar, 'register_cred_config_group');
includes/aalb_template_engine.php CHANGED
@@ -25,11 +25,14 @@ class Aalb_Template_Engine {
25
  protected $cache_template_loader;
26
  protected $mustache;
27
  protected $xml_helper;
 
28
 
29
  public function __construct() {
30
  $this->xml_loader = new Aalb_Cache_Loader(new Aalb_Remote_Loader());
 
31
  $this->cache_template_loader = new Aalb_Cache_Template_Loader();
32
  $this->mustache = new Mustache_Engine(array('loader' => new Mustache_Loader_FilesystemLoader(AALB_TEMPLATE_DIR)));
 
33
  $this->xml_helper = new Aalb_Xml_Helper();
34
  }
35
 
@@ -116,8 +119,13 @@ class Aalb_Template_Engine {
116
  * @return string HTML of the display unit.
117
  */
118
  private function render_xml($items, $template) {
 
119
  try {
120
- $template = $this->mustache->loadTemplate($template);
 
 
 
 
121
  } catch (Mustache_Exception_UnknownTemplateException $e) {
122
  $template = $this->mustache->loadTemplate(get_option(AALB_DEFAULT_TEMPLATE,AALB_DEFAULT_TEMPLATE_NAME));
123
  }
25
  protected $cache_template_loader;
26
  protected $mustache;
27
  protected $xml_helper;
28
+ protected $helper;
29
 
30
  public function __construct() {
31
  $this->xml_loader = new Aalb_Cache_Loader(new Aalb_Remote_Loader());
32
+ $this->helper = new Aalb_Helper();
33
  $this->cache_template_loader = new Aalb_Cache_Template_Loader();
34
  $this->mustache = new Mustache_Engine(array('loader' => new Mustache_Loader_FilesystemLoader(AALB_TEMPLATE_DIR)));
35
+ $this->mustache_custom = new Mustache_Engine(array('loader' => new Mustache_Loader_FilesystemLoader($this->helper->get_template_upload_directory())));
36
  $this->xml_helper = new Aalb_Xml_Helper();
37
  }
38
 
119
  * @return string HTML of the display unit.
120
  */
121
  private function render_xml($items, $template) {
122
+ $aalb_default_templates = explode(",", AALB_AMAZON_TEMPLATE_NAMES);
123
  try {
124
+ if(in_array($template, $aalb_default_templates)) {
125
+ $template = $this->mustache->loadTemplate($template);
126
+ } else {
127
+ $template = $this->mustache_custom->loadTemplate($template);
128
+ }
129
  } catch (Mustache_Exception_UnknownTemplateException $e) {
130
  $template = $this->mustache->loadTemplate(get_option(AALB_DEFAULT_TEMPLATE,AALB_DEFAULT_TEMPLATE_NAME));
131
  }
lib/php/aalb_tracking_api_helper.php CHANGED
@@ -30,7 +30,7 @@ class Aalb_Tracking_Api_Helper {
30
  $this->helper = new Aalb_Helper();
31
 
32
  //Initializes the version information once.
33
- $plugin_version = $this->helper->get_plugin_version();
34
  $wordpress_version = $this->helper->get_wordpress_version();
35
  $this->version_info = array(
36
  'wordpress' => $wordpress_version,
@@ -114,7 +114,7 @@ class Aalb_Tracking_Api_Helper {
114
  public function insert_pixel($impression_params) {
115
  $body = json_decode($impression_params,true);
116
  $pixel_url = $body["pixel-url"];
117
- echo '<img src="' . $pixel_url . '" style="visibility:hidden"></img>';
118
  }
119
  }
120
 
30
  $this->helper = new Aalb_Helper();
31
 
32
  //Initializes the version information once.
33
+ $plugin_version = AALB_PLUGIN_CURRENT_VERSION;
34
  $wordpress_version = $this->helper->get_wordpress_version();
35
  $this->version_info = array(
36
  'wordpress' => $wordpress_version,
114
  public function insert_pixel($impression_params) {
115
  $body = json_decode($impression_params,true);
116
  $pixel_url = $body["pixel-url"];
117
+ echo '<img src="' . $pixel_url . '" style="display:none"></img>';
118
  }
119
  }
120
 
lib/php/aalb_xml_helper.php CHANGED
@@ -83,7 +83,7 @@ class Aalb_Xml_Helper {
83
  }
84
 
85
  //add common aalb nodes
86
- $aalb_common_node = $items->addChild('aalb-common');
87
  $aalb_common_node = $this->add_xml_node($aalb_common_node, $common_marketplace_node_name , 'true');
88
 
89
  return $items;
83
  }
84
 
85
  //add common aalb nodes
86
+ $aalb_common_node = $items->addChild('AalbHeader');
87
  $aalb_common_node = $this->add_xml_node($aalb_common_node, $common_marketplace_node_name , 'true');
88
 
89
  return $items;
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: amazonlinkbuilder
3
  Tags: Amazon, Affiliate, Associates, Amazon Associates, Amazon Associate, Product Advertising API, Amazon API, Amazon Link, Amazon Ad, Amazon Affiliate, eCommerce
4
  Requires at least: 3.0.1
5
  Tested up to: 4.7.0
6
- Stable tag: 1.2
7
  License: GPLv2
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -88,8 +88,16 @@ You can search products using keywords in any supported country, but you have to
88
 
89
  == Changelog ==
90
 
 
 
 
 
 
 
 
 
91
  = 1.2 - December 19, 2016 =
92
- * If you are using custom templates, be sure to take a backup of your templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/Guidance-BackupCustomTemplate.pdf). If you are not using custom templates, you can simply update the plugin using the update now link.
93
  * Fix: Array dereference issue with PHP version 5.3. You will no longer get PHP syntax issues while activating the plugin.
94
  * Administration of the plugin over a secured network (HTTPS) is recommended and not required.
95
  * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
@@ -102,5 +110,8 @@ You can search products using keywords in any supported country, but you have to
102
 
103
  == Upgrade Notice ==
104
 
 
 
 
105
  = 1.2 =
106
  You will no longer get PHP syntax issues while activating the plugin. Take a backup of your custom templates before updating the plugin.
3
  Tags: Amazon, Affiliate, Associates, Amazon Associates, Amazon Associate, Product Advertising API, Amazon API, Amazon Link, Amazon Ad, Amazon Affiliate, eCommerce
4
  Requires at least: 3.0.1
5
  Tested up to: 4.7.0
6
+ Stable tag: 1.3
7
  License: GPLv2
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
88
 
89
  == Changelog ==
90
 
91
+ = 1.3 - December 27, 2016 =
92
+ * If you have created custom templates, be sure to take a backup of your templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToBackupCustomTemplates.pdf). If you have not created any custom template, you can simply update the plugin using the update now link.
93
+ * Fix: Preserve custom templates with plugin updates. You will no longer need to back up your custom templates when updating the plugin in future.
94
+ * Fix: Update tracking pixel to display:none.
95
+ * Fix: Remove ! from PriceLink template.
96
+ * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
97
+
98
+
99
  = 1.2 - December 19, 2016 =
100
+ * If you have created custom templates, be sure to take a backup of your templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToBackupCustomTemplates.pdf). If you have not created any custom template, you can simply update the plugin using the update now link.
101
  * Fix: Array dereference issue with PHP version 5.3. You will no longer get PHP syntax issues while activating the plugin.
102
  * Administration of the plugin over a secured network (HTTPS) is recommended and not required.
103
  * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
110
 
111
  == Upgrade Notice ==
112
 
113
+ = 1.3 =
114
+ This update includes a few minor fixes. In particular, you will no longer need to back up your custom templates when updating the plugin in future.
115
+
116
  = 1.2 =
117
  You will no longer get PHP syntax issues while activating the plugin. Take a backup of your custom templates before updating the plugin.
shortcode/aalb_shortcode.php CHANGED
@@ -55,7 +55,13 @@ class Aalb_Shortcode {
55
  * @since 1.0.0
56
  */
57
  public function enqueue_template_styles($template_name) {
58
- wp_enqueue_style('aalb_template' . $template_name . '_css', AALB_TEMPLATE_URL . $template_name . '.css' );
 
 
 
 
 
 
59
  }
60
 
61
  /**
55
  * @since 1.0.0
56
  */
57
  public function enqueue_template_styles($template_name) {
58
+ $aalb_default_templates = explode(",", AALB_AMAZON_TEMPLATE_NAMES);
59
+ if(in_array($template_name, $aalb_default_templates)) {
60
+ wp_enqueue_style('aalb_template' . $template_name . '_css', AALB_TEMPLATE_URL . $template_name . '.css' );
61
+ } else {
62
+ $aalb_template_upload_dir = $this->helper->get_template_upload_directory();
63
+ wp_enqueue_style('aalb_template' . $template_name . '_css', '/wp-content/uploads/amazon-associates-link-builder/template/' . $template_name . '.css' );
64
+ }
65
  }
66
 
67
  /**
template/PriceLink.mustache CHANGED
@@ -1,7 +1,7 @@
1
  {{#Items}}
2
  {{#Item}}
3
  {{#aalb}}
4
- <a href="{{DetailPageURL}}" target="_blank" rel="nofollow">{{CurrentPrice}}!</a> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
5
  {{/aalb}}
6
  {{/Item}}
7
  {{/Items}}
1
  {{#Items}}
2
  {{#Item}}
3
  {{#aalb}}
4
+ <a href="{{DetailPageURL}}" target="_blank" rel="nofollow">{{CurrentPrice}}</a> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
5
  {{/aalb}}
6
  {{/Item}}
7
  {{/Items}}
template/ProductCarousel.mustache CHANGED
@@ -1,7 +1,7 @@
1
  <!-- Ad Template with Carousel Layout-->
2
  {{#Items}} <!--Section tag for iterating through the list of items-->
3
  <div class="aalb-pc-ad-unit" id="{{ID}}">
4
- <h2 class="aalb-pc-ad-header">{{#aalb-common}}{{#MarketplaceUS}}Products from Amazon.com{{/MarketplaceUS}}{{#MarketplaceFR}}Produits disponibles sur Amazon.fr {{/MarketplaceFR}}{{#MarketplaceIT}}Acquista su Amazon.it{{/MarketplaceIT}}{{#MarketplaceDE}}Produkte von Amazon.de{{/MarketplaceDE}}{{#MarketplaceES}}Producto disponible en Amazon.es{{/MarketplaceES}}{{#MarketplaceBR}}Products from Amazon.com.br{{/MarketplaceBR}}{{#MarketplaceCA}}Products from Amazon.ca{{/MarketplaceCA}}{{#MarketplaceCN}}Products from Amazon.cn{{/MarketplaceCN}}{{#MarketplaceIN}}Products from Amazon.in{{/MarketplaceIN}}{{#MarketplaceJP}}Products from Amazon.co.jp{{/MarketplaceJP}}{{#MarketplaceMX}}Products from Amazon.com.mx{{/MarketplaceMX}}{{#MarketplaceUK}}Products from Amazon.co.uk{{/MarketplaceUK}}{{/aalb-common}}</h2> <!-- Title of the ad localized according to the marketplace picked from the aalb-common tag-->
5
  <div class="aalb-pc-wrapper">
6
  <div class="aalb-pc-product-container">
7
  <ul class="aalb-pc-product-list">
1
  <!-- Ad Template with Carousel Layout-->
2
  {{#Items}} <!--Section tag for iterating through the list of items-->
3
  <div class="aalb-pc-ad-unit" id="{{ID}}">
4
+ <h2 class="aalb-pc-ad-header">{{#AalbHeader}}{{#MarketplaceUS}}Products from Amazon.com{{/MarketplaceUS}}{{#MarketplaceFR}}Produits disponibles sur Amazon.fr {{/MarketplaceFR}}{{#MarketplaceIT}}Acquista su Amazon.it{{/MarketplaceIT}}{{#MarketplaceDE}}Produkte von Amazon.de{{/MarketplaceDE}}{{#MarketplaceES}}Producto disponible en Amazon.es{{/MarketplaceES}}{{#MarketplaceBR}}Products from Amazon.com.br{{/MarketplaceBR}}{{#MarketplaceCA}}Products from Amazon.ca{{/MarketplaceCA}}{{#MarketplaceCN}}Products from Amazon.cn{{/MarketplaceCN}}{{#MarketplaceIN}}Products from Amazon.in{{/MarketplaceIN}}{{#MarketplaceJP}}Products from Amazon.co.jp{{/MarketplaceJP}}{{#MarketplaceMX}}Products from Amazon.com.mx{{/MarketplaceMX}}{{#MarketplaceUK}}Products from Amazon.co.uk{{/MarketplaceUK}}{{/AalbHeader}}</h2> <!-- Title of the ad localized according to the marketplace picked from the AalbHeader tag-->
5
  <div class="aalb-pc-wrapper">
6
  <div class="aalb-pc-product-container">
7
  <ul class="aalb-pc-product-list">
template/ProductGrid.mustache CHANGED
@@ -3,7 +3,7 @@
3
  <div class="aalb-pg-ad-unit" id="{{ID}}">
4
  <input type="hidden" name="columns" value="2" />
5
  <input type="hidden" name="rows" value="5" />
6
- <h2 class="aalb-pg-ad-header">{{#aalb-common}}{{#MarketplaceUS}}Products from Amazon.com{{/MarketplaceUS}}{{#MarketplaceFR}}Produits disponibles sur Amazon.fr {{/MarketplaceFR}}{{#MarketplaceIT}}Acquista su Amazon.it{{/MarketplaceIT}}{{#MarketplaceDE}}Produkte von Amazon.de{{/MarketplaceDE}}{{#MarketplaceES}}Producto disponible en Amazon.es{{/MarketplaceES}}{{#MarketplaceBR}}Products from Amazon.com.br{{/MarketplaceBR}}{{#MarketplaceCA}}Products from Amazon.ca{{/MarketplaceCA}}{{#MarketplaceCN}}Products from Amazon.cn{{/MarketplaceCN}}{{#MarketplaceIN}}Products from Amazon.in{{/MarketplaceIN}}{{#MarketplaceJP}}Products from Amazon.co.jp{{/MarketplaceJP}}{{#MarketplaceMX}}Products from Amazon.com.mx{{/MarketplaceMX}}{{#MarketplaceUK}}Products from Amazon.co.uk{{/MarketplaceUK}}{{/aalb-common}}</h2> <!-- Title of the ad localized according to the marketplace picked from the aalb-common tag -->
7
  <div class="aalb-pg-wrapper">
8
  <div class="aalb-pg-product-container">
9
  <ul class="aalb-pg-product-list">
3
  <div class="aalb-pg-ad-unit" id="{{ID}}">
4
  <input type="hidden" name="columns" value="2" />
5
  <input type="hidden" name="rows" value="5" />
6
+ <h2 class="aalb-pg-ad-header">{{#AalbHeader}}{{#MarketplaceUS}}Products from Amazon.com{{/MarketplaceUS}}{{#MarketplaceFR}}Produits disponibles sur Amazon.fr {{/MarketplaceFR}}{{#MarketplaceIT}}Acquista su Amazon.it{{/MarketplaceIT}}{{#MarketplaceDE}}Produkte von Amazon.de{{/MarketplaceDE}}{{#MarketplaceES}}Producto disponible en Amazon.es{{/MarketplaceES}}{{#MarketplaceBR}}Products from Amazon.com.br{{/MarketplaceBR}}{{#MarketplaceCA}}Products from Amazon.ca{{/MarketplaceCA}}{{#MarketplaceCN}}Products from Amazon.cn{{/MarketplaceCN}}{{#MarketplaceIN}}Products from Amazon.in{{/MarketplaceIN}}{{#MarketplaceJP}}Products from Amazon.co.jp{{/MarketplaceJP}}{{#MarketplaceMX}}Products from Amazon.com.mx{{/MarketplaceMX}}{{#MarketplaceUK}}Products from Amazon.co.uk{{/MarketplaceUK}}{{/AalbHeader}}</h2> <!-- Title of the ad localized according to the marketplace picked from the AalbHeader tag -->
7
  <div class="aalb-pg-wrapper">
8
  <div class="aalb-pg-product-container">
9
  <ul class="aalb-pg-product-list">