Amazon Associates Link Builder - Version 1.4.2

Version Description

This update restricts plugin activation to supported PHP versions, and fixes bug of plugin not working with other editors.

Download this release

Release Info

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

Code changes from version 1.4.1 to 1.4.2

Files changed (39) hide show
  1. aalb_config.php +125 -120
  2. admin/aalb_admin.php +203 -192
  3. admin/css/aalb_admin.css +219 -219
  4. admin/js/aalb_admin.js +268 -261
  5. admin/partials/aalb_meta_box.php +69 -65
  6. admin/sidebar/aalb_sidebar.php +106 -100
  7. admin/sidebar/js/aalb_credentials.js +36 -36
  8. admin/sidebar/js/aalb_template.js +79 -75
  9. admin/sidebar/partials/aalb_about.php +155 -125
  10. admin/sidebar/partials/aalb_admin_ui_common.php +11 -10
  11. admin/sidebar/partials/aalb_credentials.php +126 -93
  12. admin/sidebar/partials/aalb_templates.php +184 -167
  13. admin/sidebar/partials/aalb_ui_common.php +8 -8
  14. amazon-associates-link-builder.php +34 -33
  15. css/aalb_basics.css +63 -63
  16. includes/aalb_activator.php +48 -34
  17. includes/aalb_autoloader.php +41 -38
  18. includes/aalb_cache_loader.php +51 -48
  19. includes/aalb_cache_template_loader.php +24 -21
  20. includes/aalb_config_loader.php +47 -42
  21. includes/aalb_deactivator.php +41 -41
  22. includes/aalb_helper.php +241 -227
  23. includes/aalb_hook_loader.php +54 -50
  24. includes/aalb_manager.php +51 -51
  25. includes/aalb_remote_loader.php +66 -56
  26. includes/aalb_template_engine.php +115 -103
  27. lib/php/Paapi/aalb_paapi_helper.php +99 -100
  28. lib/php/aalb_internationalization_helper.php +58 -54
  29. lib/php/aalb_tracking_api_helper.php +107 -98
  30. lib/php/aalb_validation_helper.php +87 -72
  31. lib/php/aalb_xml_helper.php +269 -231
  32. readme.txt +153 -140
  33. shortcode/aalb_shortcode.php +68 -65
  34. shortcode/aalb_shortcode_helper.php +161 -142
  35. shortcode/aalb_shortcode_loader.php +72 -66
  36. shortcode/aalb_shortcode_text.php +75 -74
  37. template/ProductAd.css +184 -154
  38. template/ProductCarousel.css +187 -156
  39. template/ProductGrid.css +187 -156
aalb_config.php CHANGED
@@ -13,119 +13,124 @@ and limitations under the License.
13
  */
14
 
15
  //version
16
- define('AALB_PLUGIN_CURRENT_VERSION','1.4.1');
17
 
 
 
 
 
 
18
  //paths
19
- define('AALB_PLUGIN_DIR', plugin_dir_path( __FILE__ ));
20
- define('AALB_PLUGIN_URL', plugin_dir_url( __FILE__ ));
21
 
22
  //Project Title
23
- define('AALB_PROJECT_TITLE', 'Associates Link Builder');
24
 
25
  /**
26
  * File paths
27
  */
28
 
29
  //Library
30
- define('MUSTACHE_AUTOLOADER_PHP', AALB_PLUGIN_DIR .'lib/php/Mustache/Autoloader.php');
31
- define('AALB_PAAPI_HELPER_PHP', AALB_PLUGIN_DIR .'lib/php/Paapi/aalb_paapi_helper.php');
32
- define('AALB_VALIDATION_HELPER_PHP', AALB_PLUGIN_DIR .'lib/php/aalb_validation_helper.php');
33
- define('AALB_XML_HELPER_PHP', AALB_PLUGIN_DIR .'lib/php/aalb_xml_helper.php');
34
- define('AALB_TRACKING_API_HELPER_PHP', AALB_PLUGIN_DIR .'lib/php/aalb_tracking_api_helper.php');
35
 
36
  //Shortcode
37
- define('AALB_SHORTCODE_PHP', AALB_PLUGIN_DIR .'shortcode/aalb_shortcode.php');
38
- define('AALB_SHORTCODE_TEXT_PHP', AALB_PLUGIN_DIR .'shortcode/aalb_shortcode_text.php');
39
- define('AALB_SHORTCODE_LOADER', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_loader.php');
40
- define('AALB_SHORTCODE_HELPER', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_helper.php');
41
 
42
  //Shortcodes supported
43
- define('AALB_SHORTCODE_AMAZON_LINK', 'amazon_link');
44
- define('AALB_SHORTCODE_AMAZON_TEXT', 'amazon_textlink');
45
 
46
  //Admin
47
- define('AALB_SIDEBAR_PHP', AALB_PLUGIN_DIR .'admin/sidebar/aalb_sidebar.php');
48
- define('AALB_ADMIN_PHP', AALB_PLUGIN_DIR .'admin/aalb_admin.php');
49
- define('AALB_ABOUT_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_about.php');
50
- define('AALB_CREDENTIALS_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_credentials.php');
51
- define('AALB_TEMPLATE_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_templates.php');
52
 
53
  //Directories
54
- define('AALB_TEMPLATE_DIR', AALB_PLUGIN_DIR . 'template/');
55
- define('AALB_ADMIN_DIR', AALB_PLUGIN_DIR . 'admin/');
56
- define('AALB_SIDEBAR_DIR', AALB_PLUGIN_DIR . 'admin/sidebar/');
57
- define('AALB_INCLUDES_DIR', AALB_PLUGIN_DIR . 'includes/');
58
- define('AALB_PAAPI_DIR', AALB_PLUGIN_DIR . 'lib/php/Paapi/');
59
- define('AALB_SHORTCODE_DIR', AALB_PLUGIN_DIR . 'shortcode/');
60
- define('AALB_LIBRARY_DIR', AALB_PLUGIN_DIR . 'lib/php/');
61
 
62
  //Includes
63
- define('AALB_ACTIVATOR_PHP', AALB_PLUGIN_DIR . 'includes/aalb_activator.php');
64
- define('AALB_DEACTIVATOR_PHP', AALB_PLUGIN_DIR . 'includes/aalb_deactivator.php');
65
- define('AALB_MANAGER', AALB_PLUGIN_DIR . 'includes/aalb_manager.php');
66
- define('AALB_HOOK_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_hook_loader.php');
67
- define('AALB_CACHE_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_cache_loader.php');
68
- define('AALB_REMOTE_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_remote_loader.php');
69
- define('AALB_AUTOLOADER', AALB_PLUGIN_DIR . 'includes/aalb_autoloader.php');
70
 
71
  //Templates Directory
72
- define('AALB_TEMPLATE_URL', AALB_PLUGIN_URL . 'template/');
73
- define('AALB_TEMPLATE_UPLOADS_FOLDER', 'amazon-associates-link-builder/template/');
74
 
75
  //Partials
76
- define('AALB_META_BOX_PARTIAL', AALB_PLUGIN_DIR . 'admin/partials/aalb_meta_box.php');
77
 
78
  //Proxy
79
- define('AALB_PROXY_URL', AALB_PLUGIN_URL . 'lib/php/Paapi/aalb_paapi_proxy.php');
80
 
81
  //Tracking API Endpoint
82
- define('AALB_TRACKING_API_ENDPOINT', 'https://rx5hfxbp45.execute-api.us-east-1.amazonaws.com/aalb/');
83
- define('AALB_TRACKING_API_SOURCE_TOOL_QUERY_PARAM', 'source-tool=aalb');
84
- define('AALB_TRACKING_API_ACCESS_KEY_QUERY_PARAM', 'aws-access-key-id=');
85
 
86
  //Wordpress Pages
87
- define('WP_POST', 'post.php');
88
- define('WP_POST_NEW', 'post-new.php');
89
 
90
  /**
91
  * Styles and scripts
92
  */
93
 
94
  //Local Styles
95
- define('AALB_ADMIN_CSS', AALB_PLUGIN_URL . 'admin/css/aalb_admin.css');
96
- define('AALB_BASICS_CSS', AALB_PLUGIN_URL . 'css/aalb_basics.css');
97
 
98
  //Local Scripts
99
- define('AALB_SHA2_JS', AALB_PLUGIN_URL . 'lib/js/jssha2/sha2.js');
100
- define('AALB_ADMIN_JS', AALB_PLUGIN_URL . 'admin/js/aalb_admin.js');
101
- define('AALB_ADMIN_ITEM_SEARCH_ITEMS_URL', AALB_PLUGIN_URL . 'aalb_admin_item_search_items.hbs');
102
- define('AALB_TEMPLATE_JS', AALB_PLUGIN_URL . 'admin/sidebar/js/aalb_template.js');
103
- define('AALB_CREDENTIALS_JS', AALB_PLUGIN_URL . 'admin/sidebar/js/aalb_credentials.js');
104
 
105
  //External Scripts
106
- define('HANDLEBARS_JS', 'https://d8fd03967nrad.cloudfront.net/libs/handlebars.js/4.0.5/handlebars.min.js');
107
- define('CODEMIRROR_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/codemirror.min.js');
108
- define('CODEMIRROR_MODE_XML_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/mode/xml/xml.min.js');
109
- define('CODEMIRROR_MODE_CSS_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/mode/css/css.min.js');
110
 
111
  //External Styles
112
- define('FONT_AWESOME_CSS', 'https://d8fd03967nrad.cloudfront.net/libs/font-awesome/4.5.0/css/font-awesome.min.css');
113
- define('CODEMIRROR_CSS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/codemirror.min.css');
114
 
115
  /**
116
  * Icons
117
  */
118
- define('AALB_SECURE_HOSTNAME', 'https://images-na.ssl-images-amazon.com/');
119
- define('AALB_NORMAL_HOSTNAME', 'http://g-ecx.images-amazon.com/');
120
- define('AALB_ICON_LOCATION', 'images/G/01/PAAPI/AmazonAssociatesLinkBuilder/icon-2._V276841048_.png');
121
- define('AALB_ADMIN_ICON_LOCATION', 'images/G/01/PAAPI/AmazonAssociatesLinkBuilder/icon._V278877987_.png');
122
  //AALB_ICON URL is generated by wordpress at run-time by checking the remotehost's encryption. Image source has different URLs depending upon the encryption used.
123
- if(is_ssl()){
124
- define('AALB_ICON', AALB_SECURE_HOSTNAME . AALB_ICON_LOCATION);
125
  } else {
126
- define('AALB_ICON', AALB_NORMAL_HOSTNAME . AALB_ICON_LOCATION);
127
  }
128
- define('AALB_ADMIN_ICON', AALB_SECURE_HOSTNAME . AALB_ADMIN_ICON_LOCATION);
129
 
130
 
131
  /**
@@ -133,71 +138,71 @@ define('AALB_ADMIN_ICON', AALB_SECURE_HOSTNAME . AALB_ADMIN_ICON_LOCATION);
133
  */
134
 
135
  //Search result items. Paapi returns 10 items by default.
136
- define('AALB_MAX_SEARCH_RESULT_ITEMS', 9);
137
  //List of Default Amazon Template names
138
- define('AALB_AMAZON_TEMPLATE_NAMES', 'ProductCarousel,ProductGrid,ProductAd,PriceLink,ProductLink');
139
 
140
  //Database keys
141
- define('AALB_TEMPLATE_NAMES', 'aalb_template_names');
142
- define('AALB_MARKETPLACE_NAMES', 'aalb_marketplace_names');
143
- define('AALB_DEFAULT_TEMPLATE', 'aalb_default_template');
144
- define('AALB_DEFAULT_STORE_ID', 'aalb_default_store_id');
145
- define('AALB_DEFAULT_MARKETPLACE', 'aalb_default_marketplace');
146
- define('AALB_AWS_ACCESS_KEY', 'aalb_aws_access_key');
147
- define('AALB_AWS_SECRET_KEY', 'aalb_aws_secret_key');
148
- define('AALB_CRED_CONFIG_GROUP', 'aalb_cred_config_group');
149
- define('AALB_STORE_ID_NAMES', 'aalb_store_id_names');
150
- define('AALB_SHOW_HTTP_WARNING_ONCE', 'aalb_show_http_warning_once');
151
- define('AALB_PLUGIN_VERSION', 'aalb_plugin_version');
152
 
153
  //Masking constant
154
- define('AALB_AWS_SECRET_KEY_MASK', '••••••••••••••••••••••••••••••••••••••••');
155
 
156
 
157
  //Defaults in case DB doesn't contain them.
158
- define('AALB_DEFAULT_TEMPLATE_NAME', 'ProductCarousel');
159
- define('AALB_DEFAULT_MARKETPLACE_NAME', 'US');
160
- define('AALB_DEFAULT_STORE_ID_NAME', 'not-specified');
161
 
162
  //Marketplaces
163
- define('MARKETPLACES_URL', 'https://webservices.amazon.com/scratchpad/assets/config/config.json');
164
 
165
  //PAAPI
166
- define('PAAPI_URI', '/onca/xml');
167
- define('PAAPI_TRANSFER_PROTOCOL', 'https://');
168
- define('PAAPI_URL_QUERY_SEPARATOR', '?');
169
- define('PAAPI_SERVICE', 'AWSECommerceService');
170
- define('PAAPI_VERSION', '2013-08-01');
171
- define('PAAPI_URL_REGEX', '^https:\\/\\/(.*)\\/onca\\/xml\\?(.*)$');
172
 
173
  //HTTP Status Codes
174
- define('HTTP_SUCCESS', '200');
175
- define('HTTP_SUCCESS_MESSAGE', '<h4>Request Successful</h4>');
176
- define('HTTP_BAD_REQUEST', '400');
177
- define('HTTP_BAD_REQUEST_MESSAGE', '<h4>Your AWS Access Key Id is not registered as an Amazon Associate. Please verify that you are <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingAssociate.html" target="_blank">registered as an Amazon Associate</a> in respective locale and you added the email address registered for the Product Advertising API as a <a href="https://affiliate-program.amazon.com/help/node/topic/202049770" target="_blank">secondary email address in your Amazon Associates account</a>.</h4>');
178
- define('HTTP_REQUEST_URI_TOO_LONG', '414');
179
- define('HTTP_REQUEST_URI_TOO_LONG_MESSAGE', '<h4>Your AccessKey Id is not registered for Product Advertising API. Please sign up for Product Advertising API by <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingDev.html" target="_blank">following these guidelines</a>.</h4>');
180
- define('HTTP_FORBIDDEN', '403');
181
- define('HTTP_FORBIDDEN_MESSAGE', '<h4>Your AccessKey Id is not registered for Product Advertising API. Please sign up for Product Advertising API by <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingDev.html" target="_blank">following these guidelines</a>.</h4>');
182
- define('HTTP_INTERNAL_SERVER_ERROR', '500');
183
- define('HTTP_INTERNAL_SERVER_ERROR_MESSAGE', '<h4>Internal server error</h4>');
184
- define('HTTP_THROTTLE', '503');
185
- define('HTTP_THROTTLE_MESSAGE', '<h4>You are submitting requests too quickly. Please retry your requests at a slower rate. For more information, see <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/TroubleshootingApplications.html#efficiency-guidelines" target="_blank">Efficiency Guidelines</a>.</h4>');
186
 
187
  /**
188
  * Cipher
189
  */
190
  //Make a key of length 32 byte.
191
  //Specify your unique encryption key here.
192
- define('AALB_ENCRYPTION_KEY', 'put your unique phrase here');
193
  //Default Encryption Key. Do NOT change this.
194
- define('AALB_ENCRYPTION_KEY_DEFAULT', 'put your unique phrase here');
195
 
196
  //Make IV of 16 bytes
197
- define('AALB_ENCRYPTION_IV', '0123456789ABCDEF');
198
 
199
  //Algorithm to use
200
- define('AALB_ENCRYPTION_ALGORITHM', 'aes-256-cbc');
201
 
202
  //Caching Requirements
203
  //====================
@@ -207,25 +212,25 @@ define('AALB_ENCRYPTION_ALGORITHM', 'aes-256-cbc');
207
  //Note that the plugin uses a two tier cache. It caches the ASINs as well as the rendered templates.
208
  //At any given time the sum of ASIN cache TTL and Rendered AdUnit cache TTL should be less than or equal to one hour.
209
  //The below configuration is compliant with the License Agreement. Any modification may result in the violation of the license agreement.
210
- define('AALB_CACHE_FOR_ASIN_RAWINFO_TTL', 30*MINUTE_IN_SECONDS);
211
- define('AALB_CACHE_FOR_ASIN_ADUNIT_TTL', 30*MINUTE_IN_SECONDS);
212
 
213
  //Translation keys
214
- define('CHECK_ON_AMAZON','Check on Amazon');
215
- define('OUT_OF_STOCK','Out of stock');
216
 
217
  //Marketplaces supported for translations
218
- define('US','US');
219
- define('FR','FR');
220
- define('IT','IT');
221
- define('DE','DE');
222
- define('ES','ES');
223
- define('BR','BR');
224
- define('CA','CA');
225
- define('CN','CN');
226
- define('IN','IN');
227
- define('JP','JP');
228
- define('MX','MX');
229
- define('UK','UK');
230
 
231
  ?>
13
  */
14
 
15
  //version
16
+ define( 'AALB_PLUGIN_CURRENT_VERSION', '1.4.2' );
17
 
18
+ //PHP version compatible for AALB plugin
19
+ define('AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION','5.3.0');
20
+
21
+ //Plugin Name
22
+ define('AALB_PLUGIN_NAME','Amazon Associates Link Builder');
23
  //paths
24
+ define( 'AALB_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
25
+ define( 'AALB_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
26
 
27
  //Project Title
28
+ define( 'AALB_PROJECT_TITLE', 'Associates Link Builder' );
29
 
30
  /**
31
  * File paths
32
  */
33
 
34
  //Library
35
+ define( 'MUSTACHE_AUTOLOADER_PHP', AALB_PLUGIN_DIR . 'lib/php/Mustache/Autoloader.php' );
36
+ define( 'AALB_PAAPI_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/Paapi/aalb_paapi_helper.php' );
37
+ define( 'AALB_VALIDATION_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_validation_helper.php' );
38
+ define( 'AALB_XML_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_xml_helper.php' );
39
+ define( 'AALB_TRACKING_API_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_tracking_api_helper.php' );
40
 
41
  //Shortcode
42
+ define( 'AALB_SHORTCODE_PHP', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode.php' );
43
+ define( 'AALB_SHORTCODE_TEXT_PHP', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_text.php' );
44
+ define( 'AALB_SHORTCODE_LOADER', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_loader.php' );
45
+ define( 'AALB_SHORTCODE_HELPER', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_helper.php' );
46
 
47
  //Shortcodes supported
48
+ define( 'AALB_SHORTCODE_AMAZON_LINK', 'amazon_link' );
49
+ define( 'AALB_SHORTCODE_AMAZON_TEXT', 'amazon_textlink' );
50
 
51
  //Admin
52
+ define( 'AALB_SIDEBAR_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/aalb_sidebar.php' );
53
+ define( 'AALB_ADMIN_PHP', AALB_PLUGIN_DIR . 'admin/aalb_admin.php' );
54
+ define( 'AALB_ABOUT_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_about.php' );
55
+ define( 'AALB_CREDENTIALS_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_credentials.php' );
56
+ define( 'AALB_TEMPLATE_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_templates.php' );
57
 
58
  //Directories
59
+ define( 'AALB_TEMPLATE_DIR', AALB_PLUGIN_DIR . 'template/' );
60
+ define( 'AALB_ADMIN_DIR', AALB_PLUGIN_DIR . 'admin/' );
61
+ define( 'AALB_SIDEBAR_DIR', AALB_PLUGIN_DIR . 'admin/sidebar/' );
62
+ define( 'AALB_INCLUDES_DIR', AALB_PLUGIN_DIR . 'includes/' );
63
+ define( 'AALB_PAAPI_DIR', AALB_PLUGIN_DIR . 'lib/php/Paapi/' );
64
+ define( 'AALB_SHORTCODE_DIR', AALB_PLUGIN_DIR . 'shortcode/' );
65
+ define( 'AALB_LIBRARY_DIR', AALB_PLUGIN_DIR . 'lib/php/' );
66
 
67
  //Includes
68
+ define( 'AALB_ACTIVATOR_PHP', AALB_PLUGIN_DIR . 'includes/aalb_activator.php' );
69
+ define( 'AALB_DEACTIVATOR_PHP', AALB_PLUGIN_DIR . 'includes/aalb_deactivator.php' );
70
+ define( 'AALB_MANAGER', AALB_PLUGIN_DIR . 'includes/aalb_manager.php' );
71
+ define( 'AALB_HOOK_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_hook_loader.php' );
72
+ define( 'AALB_CACHE_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_cache_loader.php' );
73
+ define( 'AALB_REMOTE_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_remote_loader.php' );
74
+ define( 'AALB_AUTOLOADER', AALB_PLUGIN_DIR . 'includes/aalb_autoloader.php' );
75
 
76
  //Templates Directory
77
+ define( 'AALB_TEMPLATE_URL', AALB_PLUGIN_URL . 'template/' );
78
+ define( 'AALB_TEMPLATE_UPLOADS_FOLDER', 'amazon-associates-link-builder/template/' );
79
 
80
  //Partials
81
+ define( 'AALB_META_BOX_PARTIAL', AALB_PLUGIN_DIR . 'admin/partials/aalb_meta_box.php' );
82
 
83
  //Proxy
84
+ define( 'AALB_PROXY_URL', AALB_PLUGIN_URL . 'lib/php/Paapi/aalb_paapi_proxy.php' );
85
 
86
  //Tracking API Endpoint
87
+ define( 'AALB_TRACKING_API_ENDPOINT', 'https://rx5hfxbp45.execute-api.us-east-1.amazonaws.com/aalb/' );
88
+ define( 'AALB_TRACKING_API_SOURCE_TOOL_QUERY_PARAM', 'source-tool=aalb' );
89
+ define( 'AALB_TRACKING_API_ACCESS_KEY_QUERY_PARAM', 'aws-access-key-id=' );
90
 
91
  //Wordpress Pages
92
+ define( 'WP_POST', 'post.php' );
93
+ define( 'WP_POST_NEW', 'post-new.php' );
94
 
95
  /**
96
  * Styles and scripts
97
  */
98
 
99
  //Local Styles
100
+ define( 'AALB_ADMIN_CSS', AALB_PLUGIN_URL . 'admin/css/aalb_admin.css' );
101
+ define( 'AALB_BASICS_CSS', AALB_PLUGIN_URL . 'css/aalb_basics.css' );
102
 
103
  //Local Scripts
104
+ define( 'AALB_SHA2_JS', AALB_PLUGIN_URL . 'lib/js/jssha2/sha2.js' );
105
+ define( 'AALB_ADMIN_JS', AALB_PLUGIN_URL . 'admin/js/aalb_admin.js' );
106
+ define( 'AALB_ADMIN_ITEM_SEARCH_ITEMS_URL', AALB_PLUGIN_URL . 'aalb_admin_item_search_items.hbs' );
107
+ define( 'AALB_TEMPLATE_JS', AALB_PLUGIN_URL . 'admin/sidebar/js/aalb_template.js' );
108
+ define( 'AALB_CREDENTIALS_JS', AALB_PLUGIN_URL . 'admin/sidebar/js/aalb_credentials.js' );
109
 
110
  //External Scripts
111
+ define( 'HANDLEBARS_JS', 'https://d8fd03967nrad.cloudfront.net/libs/handlebars.js/4.0.5/handlebars.min.js' );
112
+ define( 'CODEMIRROR_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/codemirror.min.js' );
113
+ define( 'CODEMIRROR_MODE_XML_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/mode/xml/xml.min.js' );
114
+ define( 'CODEMIRROR_MODE_CSS_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/mode/css/css.min.js' );
115
 
116
  //External Styles
117
+ define( 'FONT_AWESOME_CSS', 'https://d8fd03967nrad.cloudfront.net/libs/font-awesome/4.5.0/css/font-awesome.min.css' );
118
+ define( 'CODEMIRROR_CSS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/codemirror.min.css' );
119
 
120
  /**
121
  * Icons
122
  */
123
+ define( 'AALB_SECURE_HOSTNAME', 'https://images-na.ssl-images-amazon.com/' );
124
+ define( 'AALB_NORMAL_HOSTNAME', 'http://g-ecx.images-amazon.com/' );
125
+ define( 'AALB_ICON_LOCATION', 'images/G/01/PAAPI/AmazonAssociatesLinkBuilder/icon-2._V276841048_.png' );
126
+ define( 'AALB_ADMIN_ICON_LOCATION', 'images/G/01/PAAPI/AmazonAssociatesLinkBuilder/icon._V278877987_.png' );
127
  //AALB_ICON URL is generated by wordpress at run-time by checking the remotehost's encryption. Image source has different URLs depending upon the encryption used.
128
+ if ( is_ssl() ) {
129
+ define( 'AALB_ICON', AALB_SECURE_HOSTNAME . AALB_ICON_LOCATION );
130
  } else {
131
+ define( 'AALB_ICON', AALB_NORMAL_HOSTNAME . AALB_ICON_LOCATION );
132
  }
133
+ define( 'AALB_ADMIN_ICON', AALB_SECURE_HOSTNAME . AALB_ADMIN_ICON_LOCATION );
134
 
135
 
136
  /**
138
  */
139
 
140
  //Search result items. Paapi returns 10 items by default.
141
+ define( 'AALB_MAX_SEARCH_RESULT_ITEMS', 9 );
142
  //List of Default Amazon Template names
143
+ define( 'AALB_AMAZON_TEMPLATE_NAMES', 'ProductCarousel,ProductGrid,ProductAd,PriceLink,ProductLink' );
144
 
145
  //Database keys
146
+ define( 'AALB_TEMPLATE_NAMES', 'aalb_template_names' );
147
+ define( 'AALB_MARKETPLACE_NAMES', 'aalb_marketplace_names' );
148
+ define( 'AALB_DEFAULT_TEMPLATE', 'aalb_default_template' );
149
+ define( 'AALB_DEFAULT_STORE_ID', 'aalb_default_store_id' );
150
+ define( 'AALB_DEFAULT_MARKETPLACE', 'aalb_default_marketplace' );
151
+ define( 'AALB_AWS_ACCESS_KEY', 'aalb_aws_access_key' );
152
+ define( 'AALB_AWS_SECRET_KEY', 'aalb_aws_secret_key' );
153
+ define( 'AALB_CRED_CONFIG_GROUP', 'aalb_cred_config_group' );
154
+ define( 'AALB_STORE_ID_NAMES', 'aalb_store_id_names' );
155
+ define( 'AALB_SHOW_HTTP_WARNING_ONCE', 'aalb_show_http_warning_once' );
156
+ define( 'AALB_PLUGIN_VERSION', 'aalb_plugin_version' );
157
 
158
  //Masking constant
159
+ define( 'AALB_AWS_SECRET_KEY_MASK', '••••••••••••••••••••••••••••••••••••••••' );
160
 
161
 
162
  //Defaults in case DB doesn't contain them.
163
+ define( 'AALB_DEFAULT_TEMPLATE_NAME', 'ProductCarousel' );
164
+ define( 'AALB_DEFAULT_MARKETPLACE_NAME', 'US' );
165
+ define( 'AALB_DEFAULT_STORE_ID_NAME', 'not-specified' );
166
 
167
  //Marketplaces
168
+ define( 'MARKETPLACES_URL', 'https://webservices.amazon.com/scratchpad/assets/config/config.json' );
169
 
170
  //PAAPI
171
+ define( 'PAAPI_URI', '/onca/xml' );
172
+ define( 'PAAPI_TRANSFER_PROTOCOL', 'https://' );
173
+ define( 'PAAPI_URL_QUERY_SEPARATOR', '?' );
174
+ define( 'PAAPI_SERVICE', 'AWSECommerceService' );
175
+ define( 'PAAPI_VERSION', '2013-08-01' );
176
+ define( 'PAAPI_URL_REGEX', '^https:\\/\\/(.*)\\/onca\\/xml\\?(.*)$' );
177
 
178
  //HTTP Status Codes
179
+ define( 'HTTP_SUCCESS', '200' );
180
+ define( 'HTTP_SUCCESS_MESSAGE', '<h4>Request Successful</h4>' );
181
+ define( 'HTTP_BAD_REQUEST', '400' );
182
+ define( 'HTTP_BAD_REQUEST_MESSAGE', '<h4>Your AWS Access Key Id is not registered as an Amazon Associate. Please verify that you are <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingAssociate.html" target="_blank">registered as an Amazon Associate</a> in respective locale and you added the email address registered for the Product Advertising API as a <a href="https://affiliate-program.amazon.com/help/node/topic/202049770" target="_blank">secondary email address in your Amazon Associates account</a>.</h4>' );
183
+ define( 'HTTP_REQUEST_URI_TOO_LONG', '414' );
184
+ define( 'HTTP_REQUEST_URI_TOO_LONG_MESSAGE', '<h4>Your AccessKey Id is not registered for Product Advertising API. Please sign up for Product Advertising API by <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingDev.html" target="_blank">following these guidelines</a>.</h4>' );
185
+ define( 'HTTP_FORBIDDEN', '403' );
186
+ define( 'HTTP_FORBIDDEN_MESSAGE', '<h4>Your AccessKey Id is not registered for Product Advertising API. Please sign up for Product Advertising API by <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingDev.html" target="_blank">following these guidelines</a>.</h4>' );
187
+ define( 'HTTP_INTERNAL_SERVER_ERROR', '500' );
188
+ define( 'HTTP_INTERNAL_SERVER_ERROR_MESSAGE', '<h4>Internal server error</h4>' );
189
+ define( 'HTTP_THROTTLE', '503' );
190
+ define( 'HTTP_THROTTLE_MESSAGE', '<h4>You are submitting requests too quickly. Please retry your requests at a slower rate. For more information, see <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/TroubleshootingApplications.html#efficiency-guidelines" target="_blank">Efficiency Guidelines</a>.</h4>' );
191
 
192
  /**
193
  * Cipher
194
  */
195
  //Make a key of length 32 byte.
196
  //Specify your unique encryption key here.
197
+ define( 'AALB_ENCRYPTION_KEY', 'put your unique phrase here' );
198
  //Default Encryption Key. Do NOT change this.
199
+ define( 'AALB_ENCRYPTION_KEY_DEFAULT', 'put your unique phrase here' );
200
 
201
  //Make IV of 16 bytes
202
+ define( 'AALB_ENCRYPTION_IV', '0123456789ABCDEF' );
203
 
204
  //Algorithm to use
205
+ define( 'AALB_ENCRYPTION_ALGORITHM', 'aes-256-cbc' );
206
 
207
  //Caching Requirements
208
  //====================
212
  //Note that the plugin uses a two tier cache. It caches the ASINs as well as the rendered templates.
213
  //At any given time the sum of ASIN cache TTL and Rendered AdUnit cache TTL should be less than or equal to one hour.
214
  //The below configuration is compliant with the License Agreement. Any modification may result in the violation of the license agreement.
215
+ define( 'AALB_CACHE_FOR_ASIN_RAWINFO_TTL', 30 * MINUTE_IN_SECONDS );
216
+ define( 'AALB_CACHE_FOR_ASIN_ADUNIT_TTL', 30 * MINUTE_IN_SECONDS );
217
 
218
  //Translation keys
219
+ define( 'CHECK_ON_AMAZON', 'Check on Amazon' );
220
+ define( 'OUT_OF_STOCK', 'Out of stock' );
221
 
222
  //Marketplaces supported for translations
223
+ define( 'US', 'US' );
224
+ define( 'FR', 'FR' );
225
+ define( 'IT', 'IT' );
226
+ define( 'DE', 'DE' );
227
+ define( 'ES', 'ES' );
228
+ define( 'BR', 'BR' );
229
+ define( 'CA', 'CA' );
230
+ define( 'CN', 'CN' );
231
+ define( 'IN', 'IN' );
232
+ define( 'JP', 'JP' );
233
+ define( 'MX', 'MX' );
234
+ define( 'UK', 'UK' );
235
 
236
  ?>
admin/aalb_admin.php CHANGED
@@ -24,205 +24,216 @@ and limitations under the License.
24
  */
25
  class Aalb_Admin {
26
 
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
-
40
- /**
41
- * Show warning message if the AWS Credentials are not yet set upon activation
42
- *
43
- * @since 1.0.0
44
- */
45
- public function aalb_plugin_activation() {
46
- if(get_option(AALB_AWS_ACCESS_KEY) == '' or get_option(AALB_AWS_SECRET_KEY) == '') {
47
- echo "<div class=\"notice notice-error\"><h3>Amazon Associates Link Builder Important Message!</h3><p>Please Note - You need to add your Access Key ID and Secret Access Key in the plugin settings page for adding links to Amazon using Amazon Associates Link Builder plugin.</p></div>";
48
  }
49
- }
50
-
51
- /**
52
- * Adding CSS for post and post-new pages
53
- *
54
- * @since 1.0.0
55
- * @param string $hook The name of the WordPress action that is being registered.
56
- */
57
- public function enqueue_styles($hook) {
58
- if(WP_POST != $hook && WP_POST_NEW != $hook){return;}
59
- wp_enqueue_style('aalb_basics_css', AALB_BASICS_CSS );
60
- wp_enqueue_style('aalb_admin_css', AALB_ADMIN_CSS);
61
- wp_enqueue_style('font_awesome_css', FONT_AWESOME_CSS);
62
- wp_enqueue_style('thickbox');
63
- }
64
-
65
- /**
66
- * Adding JS for post and post-new pages
67
- *
68
- * @since 1.0.0
69
- * @param string $hook The name of the WordPress action that is being registered.
70
- */
71
- public function enqueue_scripts($hook) {
72
- if(WP_POST != $hook && WP_POST_NEW != $hook){return;}
73
- wp_enqueue_style('thickbox');
74
- wp_enqueue_script('jquery');
75
- wp_enqueue_script('handlebars_js', HANDLEBARS_JS);
76
- wp_enqueue_script('aalb_sha2_js', AALB_SHA2_JS);
77
-
78
- wp_enqueue_script('aalb_admin_js', AALB_ADMIN_JS, array('handlebars_js', 'jquery', 'aalb_sha2_js'));
79
- wp_enqueue_style('thickbox');
80
- wp_localize_script('aalb_admin_js', 'api_pref', $this->get_paapi_pref());
81
- }
82
-
83
- /**
84
- * Returns data to be localized in the script.
85
- * Makes the variable values in PHP to be used in Javascript.
86
- *
87
- * @since 1.0.0
88
- * @return array Data to be localized in the script
89
- */
90
- private function get_paapi_pref() {
91
- return array(
92
- 'template_url' => AALB_ADMIN_ITEM_SEARCH_ITEMS_URL,
93
- 'max_search_result_items' => AALB_MAX_SEARCH_RESULT_ITEMS,
94
- 'store_id' => get_option(AALB_DEFAULT_STORE_ID),
95
- 'marketplace' => get_option(AALB_DEFAULT_MARKETPLACE),
96
- 'ajax_url' => admin_url('admin-ajax.php'),
97
- 'action' => 'get_item_search_result',
98
- 'item_search_nonce' => wp_create_nonce('aalb-item-search-nonce'),
99
- 'AALB_SHORTCODE_AMAZON_LINK' => AALB_SHORTCODE_AMAZON_LINK,
100
- 'AALB_SHORTCODE_AMAZON_TEXT' => AALB_SHORTCODE_AMAZON_TEXT
101
- );
102
- }
103
-
104
- /**
105
- * Block which run whenever the plugin has been updated.
106
- * Refreshes the templates
107
- *
108
- * @since 1.3
109
- */
110
- public function handle_plugin_update() {
111
- //Clear all transients for price changes to reflect
112
- $this->helper->clear_cache_for_substring('');
113
- $this->helper->clear_expired_transients();
114
-
115
- global $wp_filesystem;
116
- $this->helper->aalb_initialize_wp_filesystem_api();
117
- $this->helper->refresh_template_list();
118
- update_option(AALB_PLUGIN_VERSION, AALB_PLUGIN_CURRENT_VERSION);
119
- }
120
-
121
- /**
122
- * Checks if the plugin has been updated and calls required method
123
- *
124
- * @since 1.3
125
- */
126
- public function check_update() {
127
- if(AALB_PLUGIN_CURRENT_VERSION !== get_option(AALB_PLUGIN_VERSION)) {
128
- $this->handle_plugin_update();
 
 
 
129
  }
130
- }
131
-
132
- /**
133
- * Prints the aalb-admin sidebar search box.
134
- *
135
- * @since 1.0.0
136
- * @param WP_Post $post The object for the current post/page.
137
- */
138
- function admin_display_callback($post) {
139
- require_once(AALB_META_BOX_PARTIAL);
140
- }
141
-
142
- /**
143
- * Asin button in text editor for putting the shortcode template
144
- *
145
- * @since 1.0.0
146
- */
147
- function add_quicktags() {
148
- if (wp_script_is('quicktags')){
149
- ?>
150
- <script type="text/javascript">
151
- QTags.addButton( 'aalb_asin_button', 'asins', '[amazon_link asins="" template="" marketplace="" link_id=""]', '', '', 'Amazon Link');
152
- </script>
153
- <?php
154
  }
155
- }
156
-
157
- /**
158
- * Supports the ajax request for item search.
159
- *
160
- * @since 1.0.0
161
- */
162
- public function get_item_search_result() {
163
- $nonce = $_GET['item_search_nonce'];
164
-
165
- //verify the user making the request.
166
- if(!wp_verify_nonce($nonce, 'aalb-item-search-nonce')) {
167
- die('Not authorised to make a request');
168
  }
169
 
170
- //Only allow users who can edit post to make the request.
171
- if(current_user_can('edit_posts')) {
172
- $url = $this->paapi_helper->get_item_search_url($_GET['keywords'], $_GET['marketplace'], $_GET['store_id']);
173
- try{
174
- echo $this->remote_loader->load($url);
175
- } catch(Exception $e){
176
- echo $this->paapi_helper->get_error_message($e->getMessage());
177
- }
 
 
 
 
 
178
  }
179
 
180
- wp_die();
181
- }
182
-
183
- /**
184
- * Supports the ajax request for get link id API
185
- *
186
- * @since 1.0.0
187
- */
188
- public function get_link_code() {
189
-
190
- $shortcode_params_json_string = $_POST['shortcode_params'];
191
- $shortcode_name = $_POST['shortcode_name'];
192
-
193
- echo $this->tracking_api_helper->get_link_id($shortcode_name, $shortcode_params_json_string);
194
- wp_die();
195
- }
196
-
197
- /**
198
- * Supports the ajax request for getting template contents for custom templates
199
- *
200
- * @since 1.3
201
- */
202
- public function get_custom_template_content() {
203
- global $wp_filesystem;
204
- $this->helper->aalb_initialize_wp_filesystem_api();
205
- $base_path = $this->helper->get_template_upload_directory();
206
- if(current_user_can('edit_posts')) {
207
- $css_file = $_POST['css'];
208
- $real_css_file = realpath($css_file);
209
- $mustache_file = $_POST['mustache'];
210
- $real_mustache_file = realpath($mustache_file);
211
- if ($real_css_file === false || $real_mustache_file === false || strpos($real_css_file, $base_path) !== 0 || strpos($real_mustache_file, $base_path) !== 0) {
212
- //If base path is not a prefix of the realpath, this means that a directry traversal was attempted
213
- die('Not authorised to make request template content or Directory Traversal Attempted.');
214
- } else {
215
- //No vulnerability. Get file contents.
216
- $css_file_content = $wp_filesystem->get_contents($css_file);
217
- $mustache_file_content = $wp_filesystem->get_contents($mustache_file);
218
-
219
- $response = array("css" => $css_file_content, "mustache" => $mustache_file_content);
220
- echo json_encode($response);
221
- }
222
- } else {
223
- die('Not authorised to make request');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  }
225
- wp_die();
226
- }
227
  }
 
228
  ?>
24
  */
25
  class Aalb_Admin {
26
 
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
+
40
+ /**
41
+ * Show warning message if the AWS Credentials are not yet set upon activation
42
+ *
43
+ * @since 1.0.0
44
+ */
45
+ public function aalb_plugin_activation() {
46
+ if ( get_option( AALB_AWS_ACCESS_KEY ) == '' or get_option( AALB_AWS_SECRET_KEY ) == '' ) {
47
+ echo "<div class=\"notice notice-error\">
48
+ <h3>Amazon Associates Link Builder Important Message!</h3>
49
+ <p>Please Note - You need to add your Access Key ID and Secret Access Key in the plugin settings page for adding links to Amazon using Amazon Associates Link Builder plugin.</p>
50
+ </div>";
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Adding CSS for post and post-new pages
56
+ *
57
+ * @since 1.0.0
58
+ *
59
+ * @param string $hook The name of the WordPress action that is being registered.
60
+ */
61
+ public function enqueue_styles( $hook ) {
62
+ if ( WP_POST != $hook && WP_POST_NEW != $hook ) {
63
+ return;
64
+ }
65
+ wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
66
+ wp_enqueue_style( 'aalb_admin_css', AALB_ADMIN_CSS );
67
+ wp_enqueue_style( 'font_awesome_css', FONT_AWESOME_CSS );
68
+ wp_enqueue_style( 'thickbox' );
69
+ }
70
+
71
+ /**
72
+ * Adding JS for post and post-new pages
73
+ *
74
+ * @since 1.0.0
75
+ *
76
+ * @param string $hook The name of the WordPress action that is being registered.
77
+ */
78
+ public function enqueue_scripts( $hook ) {
79
+ if ( WP_POST != $hook && WP_POST_NEW != $hook ) {
80
+ return;
81
+ }
82
+ wp_enqueue_style( 'thickbox' );
83
+ wp_enqueue_script( 'jquery' );
84
+ wp_enqueue_script( 'handlebars_js', HANDLEBARS_JS );
85
+ wp_enqueue_script( 'aalb_sha2_js', AALB_SHA2_JS );
86
+
87
+ wp_enqueue_script( 'aalb_admin_js', AALB_ADMIN_JS, array( 'handlebars_js', 'jquery', 'aalb_sha2_js' ) );
88
+ wp_enqueue_style( 'thickbox' );
89
+ wp_localize_script( 'aalb_admin_js', 'api_pref', $this->get_paapi_pref() );
90
+ }
91
+
92
+ /**
93
+ * Returns data to be localized in the script.
94
+ * Makes the variable values in PHP to be used in Javascript.
95
+ *
96
+ * @since 1.0.0
97
+ * @return array Data to be localized in the script
98
+ */
99
+ private function get_paapi_pref() {
100
+ return array(
101
+ 'template_url' => AALB_ADMIN_ITEM_SEARCH_ITEMS_URL,
102
+ 'max_search_result_items' => AALB_MAX_SEARCH_RESULT_ITEMS,
103
+ 'store_id' => get_option( AALB_DEFAULT_STORE_ID ),
104
+ 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ),
105
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
106
+ 'action' => 'get_item_search_result',
107
+ 'item_search_nonce' => wp_create_nonce( 'aalb-item-search-nonce' ),
108
+ 'AALB_SHORTCODE_AMAZON_LINK' => AALB_SHORTCODE_AMAZON_LINK,
109
+ 'AALB_SHORTCODE_AMAZON_TEXT' => AALB_SHORTCODE_AMAZON_TEXT
110
+ );
111
+ }
112
+
113
+ /**
114
+ * Checks if the plugin has been updated and calls required method
115
+ *
116
+ * @since 1.3
117
+ */
118
+ public function check_update() {
119
+ if ( AALB_PLUGIN_CURRENT_VERSION !== get_option( AALB_PLUGIN_VERSION ) ) {
120
+ $this->handle_plugin_update();
121
+ }
122
  }
123
+
124
+ /**
125
+ * Block which runs whenever the plugin has been updated.
126
+ * Refreshes the templates
127
+ *
128
+ * @since 1.3
129
+ */
130
+ public function handle_plugin_update() {
131
+ //Clear all transients for price changes to reflect
132
+ $this->helper->clear_cache_for_substring( '' );
133
+ $this->helper->clear_expired_transients();
134
+
135
+ global $wp_filesystem;
136
+ $this->helper->aalb_initialize_wp_filesystem_api();
137
+ $this->helper->refresh_template_list();
138
+ update_option( AALB_PLUGIN_VERSION, AALB_PLUGIN_CURRENT_VERSION );
 
 
 
 
 
 
 
 
139
  }
140
+
141
+ /**
142
+ * Prints the aalb-admin sidebar search box.
143
+ *
144
+ * @since 1.0.0
145
+ *
146
+ * @param WP_Post $post The object for the current post/page.
147
+ */
148
+ function admin_display_callback( $post ) {
149
+ require( AALB_META_BOX_PARTIAL );
 
 
 
150
  }
151
 
152
+ /**
153
+ * Asin button in text editor for putting the shortcode template
154
+ *
155
+ * @since 1.0.0
156
+ */
157
+ function add_quicktags() {
158
+ if ( wp_script_is( 'quicktags' ) ) {
159
+ ?>
160
+ <script type="text/javascript">
161
+ QTags.addButton( 'aalb_asin_button', 'asins', '[amazon_link asins="" template="" marketplace="" link_id=""]', '', '', 'Amazon Link' );
162
+ </script>
163
+ <?php
164
+ }
165
  }
166
 
167
+ /**
168
+ * Supports the ajax request for item search.
169
+ *
170
+ * @since 1.0.0
171
+ */
172
+ public function get_item_search_result() {
173
+ $nonce = $_GET['item_search_nonce'];
174
+
175
+ //verify the user making the request.
176
+ if ( ! wp_verify_nonce( $nonce, 'aalb-item-search-nonce' ) ) {
177
+ die( 'Not authorised to make a request' );
178
+ }
179
+
180
+ //Only allow users who can edit post to make the request.
181
+ if ( current_user_can( 'edit_posts' ) ) {
182
+ $url = $this->paapi_helper->get_item_search_url( $_GET['keywords'], $_GET['marketplace'], $_GET['store_id'] );
183
+ try {
184
+ echo $this->remote_loader->load( $url );
185
+ } catch ( Exception $e ) {
186
+ echo $this->paapi_helper->get_error_message( $e->getMessage() );
187
+ }
188
+ }
189
+
190
+ wp_die();
191
+ }
192
+
193
+ /**
194
+ * Supports the ajax request for get link id API
195
+ *
196
+ * @since 1.0.0
197
+ */
198
+ public function get_link_code() {
199
+
200
+ $shortcode_params_json_string = $_POST['shortcode_params'];
201
+ $shortcode_name = $_POST['shortcode_name'];
202
+
203
+ echo $this->tracking_api_helper->get_link_id( $shortcode_name, $shortcode_params_json_string );
204
+ wp_die();
205
+ }
206
+
207
+ /**
208
+ * Supports the ajax request for getting template contents for custom templates
209
+ *
210
+ * @since 1.3
211
+ */
212
+ public function get_custom_template_content() {
213
+ global $wp_filesystem;
214
+ $this->helper->aalb_initialize_wp_filesystem_api();
215
+ $base_path = $this->helper->get_template_upload_directory();
216
+ if ( current_user_can( 'edit_posts' ) ) {
217
+ $css_file = $_POST['css'];
218
+ $real_css_file = realpath( $css_file );
219
+ $mustache_file = $_POST['mustache'];
220
+ $real_mustache_file = realpath( $mustache_file );
221
+ if ( $real_css_file === false || $real_mustache_file === false || strpos( $real_css_file, $base_path ) !== 0 || strpos( $real_mustache_file, $base_path ) !== 0 ) {
222
+ //If base path is not a prefix of the realpath, this means that a directry traversal was attempted
223
+ die( 'Not authorised to make request template content or Directory Traversal Attempted.' );
224
+ } else {
225
+ //No vulnerability. Get file contents.
226
+ $css_file_content = $wp_filesystem->get_contents( $css_file );
227
+ $mustache_file_content = $wp_filesystem->get_contents( $mustache_file );
228
+
229
+ $response = array( "css" => $css_file_content, "mustache" => $mustache_file_content );
230
+ echo json_encode( $response );
231
+ }
232
+ } else {
233
+ die( 'Not authorised to make request' );
234
+ }
235
+ wp_die();
236
  }
 
 
237
  }
238
+
239
  ?>
admin/css/aalb_admin.css CHANGED
@@ -11,328 +11,329 @@ and limitations under the License.
11
  */
12
 
13
  #aalb-admin-searchbox {
14
- display: inline;
15
  }
16
 
17
  img#aalb-admin-searchbox-amzlogo {
18
- width: 30px;
19
- height: 30px;
20
- padding: 0px;
21
  }
22
 
23
  input#aalb-admin-input-search {
24
- vertical-align: top;
25
- margin-left: 3px;
26
- margin-right: 3px;
27
- height: 28px;
28
  }
29
 
30
-
31
  a#aalb-admin-button-create-amazon-shortcode {
32
- box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.4) inset;
33
- background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
34
- background-color: transparent;
35
- background-image: linear-gradient(to bottom, #F7DFA5, #F0C14B);
36
- background-repeat: repeat;
37
- background-attachment: scroll;
38
- background-position: 0% 0%;
39
- background-clip: border-box;
40
- background-origin: padding-box;
41
- background-size: auto auto;
42
- border-color: #A88734 #9C7E31 #846A29;
43
- border-top-color: #A88734;
44
- border-right-color: #9C7E31;
45
- border-bottom-color: #846A29;
46
- border-left-color: #9C7E31;
47
- color: #111;
48
- }
49
-
50
- html, body
51
- {
52
- width: 100%;
53
- height: 100%;
54
- margin: 0;
55
- padding: 0;
56
  }
57
 
58
  #TB_ajaxContent {
59
- height:90%;
60
- width:95%;
61
  }
62
 
63
  #aalb-admin-popup-container {
64
- height: 100%;
65
- width: 100%;
66
  }
67
 
68
  #aalb-admin-popup-content {
69
- padding-top: 30px;
70
- height: 50%;
71
- width: 100%;
72
  }
73
 
74
  .aalb-modal-box {
75
- width:100%;
76
- height: 100%;
77
  }
78
 
79
  .aalb-admin-alert {
80
- padding: 15px;
81
- margin-bottom: 20px;
82
- border: 1px solid transparent;
83
- border-radius: 4px;
84
  }
85
 
86
  .aalb-admin-alert {
87
- text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2);
88
- box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px 1px 2px rgba(0, 0, 0, 0.05);
89
  }
90
 
91
  .aalb-admin-alert-info {
92
- color: #E77600;
93
- background-color: #FEF8F2;
94
- border-color: #E77600;
95
  }
96
 
97
  .aalb-admin-alert-info {
98
- background-image: linear-gradient(to bottom, #FEF8F2 0px, #FFF1E3 100%);
99
- background-repeat: repeat-x;
100
- border-color: #E77600;
101
  }
102
 
103
- #aalb-add-shortcode-alert{
104
- color: #E77600;
105
- padding: 2px;
106
- display: inline;
107
- padding-left: 10px;
108
- opacity: 0;
109
  }
110
 
111
  .aalb-admin-icon {
112
- padding-right: 5px;
113
- height: 20%;
114
- display: inline;
115
  }
116
 
117
  .aalb-admin-item-search-loading {
118
- margin-top: 20px;
119
  }
120
 
121
  .aalb-admin-item-search {
122
- width:100%;
123
- height: 90%;
124
- display: none;
125
- padding-top: 3%;
126
  }
127
 
128
  .aalb-admin-item-search-items {
129
- width:100%;
130
- height: 100%;
131
- margin: 2px;
132
- padding: 0;
133
- -moz-column-gap: 8px;
134
- -webkit-column-gap: 8px;
135
- column-gap: 8px;
136
- -moz-column-count: 3;
137
- -webkit-column-count: 3;
138
- column-count: 3;
139
  }
140
 
141
  .aalb-admin-item-search-items-item {
142
- display: inline-block;
143
- background: #fff;
144
- padding: 5px;
145
- margin: 0 0 5px;
146
- width: 100%;
147
- height:30%;
148
- -moz-box-sizing: border-box;
149
- -webkit-box-sizing: border-box;
150
- box-sizing: border-box;
151
- box-shadow: 2px 2px 4px 0 #ccc;
152
- border: 1px solid #CCC;
153
- border-radius: 4px;
154
- cursor: pointer;
155
- }
156
-
157
- .aalb-admin-item-search-items-item-img{
158
- float:left;
159
- padding-right: 5px;
160
- width: 25%;
161
- height: 100%;
162
- }
163
-
164
- #aalb-admin-item-search-items-item-img{
165
- max-width:100%;
166
- height:100%;
167
- display:block;
168
- margin-left:auto;
169
- margin-right:auto;
170
  }
171
 
172
  .aalb-admin-item-search-items-item-title {
173
- font-weight: bold;
174
- word-break: break-all;
175
- font-size: 1em;
176
- /* hide text if it more than N lines */
177
- overflow: hidden;
178
- /* for set '...' in absolute position */
179
- position: relative;
180
- /* use this value to count block height */
181
- line-height: 1.2em;
182
- /* max-height = line-height (1.2) * lines max number (2) */
183
- max-height: 2.4em;
184
- /* fix problem when last visible word doesn't adjoin right side */
185
- text-align: justify;
186
- /* place for '...' */
187
- margin-right: -1em;
188
- padding-right: 1em;
189
  }
190
 
191
  /* create the ... */
192
  .aalb-admin-item-search-items-item-title:before {
193
- /* points in the end */
194
- content: '...';
195
- /* absolute position */
196
- position: absolute;
197
- /* set position to right bottom corner of block */
198
- right: 0;
199
- bottom: 0;
200
  }
201
 
202
  /* hide ... if we have text, which is less than or equal to max lines */
203
  .aalb-admin-item-search-items-item-title:after {
204
- /* points in the end */
205
- content: '';
206
- /* absolute position */
207
- position: absolute;
208
- /* set position to right bottom corner of text */
209
- right: 0;
210
- /* set width and height */
211
- width: 1em;
212
- height: 1em;
213
- margin-top: 0.2em;
214
- /* bg color = bg color under block */
215
- background: white;
216
  }
217
 
218
  /* CSS Fix for rendering issues with safari */
219
- @media screen and (min-color-index:0)
220
- and(-webkit-min-device-pixel-ratio:0) { @media {
221
- .aalb-admin-item-search-items-item-title {
222
- position: initial;
223
- margin-left: 2em;
224
- margin-right: 0em;
 
 
225
  }
226
- }}
227
 
228
  .aalb-admin-item-search-items-item-price {
229
- font-size: 1em;
230
- color: #b12704;
231
- font-weight: bold;
232
  }
233
 
234
  .aalb-admin-item-search-items-item:hover {
235
- background-image: linear-gradient(to bottom, #FEF8F2 0px, #FFF1E3 100%);
236
- background-repeat: repeat-x;
237
- border-color: #E77600;
238
  }
239
 
240
  .aalb-admin-popup-shortocde-wrapper {
241
- display: block;
242
- width: 100%;
243
  }
244
 
245
  .aalb-admin-popup-shortcode-options {
246
- padding-top: 3%;
247
- width:100%;
248
- -moz-column-gap: 10px;
249
- -webkit-column-gap: 10px;
250
- column-gap: 10px;
251
- -moz-column-count: 3;
252
- -webkit-column-count: 3;
253
- column-count: 3;
254
  }
255
 
256
  .aalb-admin-popup-shortcode-options label {
257
- display: block;
258
- text-align: left;
259
  }
260
 
261
  .aalb-admin-item-search-templates {
262
- width:100%;
263
  }
264
 
265
  .aalb-admin-popup-store {
266
- width:100%;
267
  }
268
 
269
  .aalb-admin-item-search-marketplaces {
270
- width:100%;
271
  }
272
 
273
  .aalb-add-shortcode-button {
274
- padding-top: 20px;
275
  }
276
 
277
  .aalb-admin-popup-options {
278
- position:relative;
279
  }
280
 
281
  #aalb-admin-popup-input-search {
282
- position:absolute;
283
- width:100%;
284
- left: 0;
285
- margin-top: 1%;
286
- height:33px;
287
- vertical-align: middle;
288
  }
289
 
290
  #aalb-admin-popup-search-button {
291
- position:absolute;
292
- right:0;
293
  }
294
 
295
  .aalb-selected {
296
- height:auto;
297
- width:100%;
298
- padding-top: 10px;
299
- padding-bottom: 10px;
300
  }
301
 
302
  .aalb-selected label {
303
- display: block;
304
- text-align: left;
305
- padding: 15px 0px;
306
  }
307
 
308
  .aalb-selected-item {
309
- border: 1px solid #eee;
310
- float: left;
311
- margin: 4px 4px 4px 4px;
312
- position: relative;
313
- width: 10%;
314
- padding: 4px;
315
- font-family: Helvetica;
316
  }
317
 
318
  .aalb-selected-item:hover {
319
- border: 1px solid #900;
320
  }
321
 
322
  .aalb-selected-item-img {
323
- display:block;
324
- margin-top:auto;
325
- margin-bottom:auto;
326
- height:90px;
327
- margin-left:auto;
328
- margin-right:auto;
329
- max-width:100%;
330
  }
331
 
332
  .aalb-selected-item-img-wrap {
333
  position: relative;
334
  height: 100%;
335
  }
 
336
  .aalb-selected-item-close {
337
  position: absolute;
338
  top: -12px;
@@ -350,30 +351,29 @@ and(-webkit-min-device-pixel-ratio:0) { @media {
350
  cursor: pointer;
351
  box-shadow: 1px 1px 4px #000;
352
  background-color: #a50200;
353
- background-image: -webkit-linear-gradient(top,#cb0400,#a50200);
354
- background-image: linear-gradient(to bottom,#cb0400,#a50200);
355
  }
356
 
357
- .aalb-selected-item-title h3{
358
- margin: 2px 3px 0 2px;
359
- font-size: 8px;
360
- line-height: 12px;
361
- color: #000;
362
- position: relative;
363
- text-align: center;
364
- display: block;
365
- overflow: hidden;
366
- height: 35px;
367
  }
368
 
369
  .aalb-selected-item-price {
370
- text-align: center;
371
- color: #900;
372
- font-weight: bold;
373
- margin: 2px;
374
  }
375
 
376
-
377
  .aalb-selected-asin {
378
- display:none;
379
  }
11
  */
12
 
13
  #aalb-admin-searchbox {
14
+ display: inline;
15
  }
16
 
17
  img#aalb-admin-searchbox-amzlogo {
18
+ width: 30px;
19
+ height: 30px;
20
+ padding: 0px;
21
  }
22
 
23
  input#aalb-admin-input-search {
24
+ vertical-align: top;
25
+ margin-left: 3px;
26
+ margin-right: 3px;
27
+ height: 28px;
28
  }
29
 
 
30
  a#aalb-admin-button-create-amazon-shortcode {
31
+ box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.4) inset;
32
+ background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
33
+ background-color: transparent;
34
+ background-image: linear-gradient(to bottom, #F7DFA5, #F0C14B);
35
+ background-repeat: repeat;
36
+ background-attachment: scroll;
37
+ background-position: 0% 0%;
38
+ background-clip: border-box;
39
+ background-origin: padding-box;
40
+ background-size: auto auto;
41
+ border-color: #A88734 #9C7E31 #846A29;
42
+ border-top-color: #A88734;
43
+ border-right-color: #9C7E31;
44
+ border-bottom-color: #846A29;
45
+ border-left-color: #9C7E31;
46
+ color: #111;
47
+ }
48
+
49
+ html, body {
50
+ width: 100%;
51
+ height: 100%;
52
+ margin: 0;
53
+ padding: 0;
 
54
  }
55
 
56
  #TB_ajaxContent {
57
+ height: 90%;
58
+ width: 95%;
59
  }
60
 
61
  #aalb-admin-popup-container {
62
+ height: 100%;
63
+ width: 100%;
64
  }
65
 
66
  #aalb-admin-popup-content {
67
+ padding-top: 30px;
68
+ height: 50%;
69
+ width: 100%;
70
  }
71
 
72
  .aalb-modal-box {
73
+ width: 100%;
74
+ height: 100%;
75
  }
76
 
77
  .aalb-admin-alert {
78
+ padding: 15px;
79
+ margin-bottom: 20px;
80
+ border: 1px solid transparent;
81
+ border-radius: 4px;
82
  }
83
 
84
  .aalb-admin-alert {
85
+ text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2);
86
+ box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px 1px 2px rgba(0, 0, 0, 0.05);
87
  }
88
 
89
  .aalb-admin-alert-info {
90
+ color: #E77600;
91
+ background-color: #FEF8F2;
92
+ border-color: #E77600;
93
  }
94
 
95
  .aalb-admin-alert-info {
96
+ background-image: linear-gradient(to bottom, #FEF8F2 0px, #FFF1E3 100%);
97
+ background-repeat: repeat-x;
98
+ border-color: #E77600;
99
  }
100
 
101
+ #aalb-add-shortcode-alert {
102
+ color: #E77600;
103
+ padding: 2px;
104
+ display: inline;
105
+ padding-left: 10px;
106
+ opacity: 0;
107
  }
108
 
109
  .aalb-admin-icon {
110
+ padding-right: 5px;
111
+ height: 20%;
112
+ display: inline;
113
  }
114
 
115
  .aalb-admin-item-search-loading {
116
+ margin-top: 20px;
117
  }
118
 
119
  .aalb-admin-item-search {
120
+ width: 100%;
121
+ height: 90%;
122
+ display: none;
123
+ padding-top: 3%;
124
  }
125
 
126
  .aalb-admin-item-search-items {
127
+ width: 100%;
128
+ height: 100%;
129
+ margin: 2px;
130
+ padding: 0;
131
+ -moz-column-gap: 8px;
132
+ -webkit-column-gap: 8px;
133
+ column-gap: 8px;
134
+ -moz-column-count: 3;
135
+ -webkit-column-count: 3;
136
+ column-count: 3;
137
  }
138
 
139
  .aalb-admin-item-search-items-item {
140
+ display: inline-block;
141
+ background: #fff;
142
+ padding: 5px;
143
+ margin: 0 0 5px;
144
+ width: 100%;
145
+ height: 30%;
146
+ -moz-box-sizing: border-box;
147
+ -webkit-box-sizing: border-box;
148
+ box-sizing: border-box;
149
+ box-shadow: 2px 2px 4px 0 #ccc;
150
+ border: 1px solid #CCC;
151
+ border-radius: 4px;
152
+ cursor: pointer;
153
+ }
154
+
155
+ .aalb-admin-item-search-items-item-img {
156
+ float: left;
157
+ padding-right: 5px;
158
+ width: 25%;
159
+ height: 100%;
160
+ }
161
+
162
+ #aalb-admin-item-search-items-item-img {
163
+ max-width: 100%;
164
+ height: 100%;
165
+ display: block;
166
+ margin-left: auto;
167
+ margin-right: auto;
168
  }
169
 
170
  .aalb-admin-item-search-items-item-title {
171
+ font-weight: bold;
172
+ word-break: break-all;
173
+ font-size: 1em;
174
+ /* hide text if it more than N lines */
175
+ overflow: hidden;
176
+ /* for set '...' in absolute position */
177
+ position: relative;
178
+ /* use this value to count block height */
179
+ line-height: 1.2em;
180
+ /* max-height = line-height (1.2) * lines max number (2) */
181
+ max-height: 2.4em;
182
+ /* fix problem when last visible word doesn't adjoin right side */
183
+ text-align: justify;
184
+ /* place for '...' */
185
+ margin-right: -1em;
186
+ padding-right: 1em;
187
  }
188
 
189
  /* create the ... */
190
  .aalb-admin-item-search-items-item-title:before {
191
+ /* points in the end */
192
+ content: '...';
193
+ /* absolute position */
194
+ position: absolute;
195
+ /* set position to right bottom corner of block */
196
+ right: 0;
197
+ bottom: 0;
198
  }
199
 
200
  /* hide ... if we have text, which is less than or equal to max lines */
201
  .aalb-admin-item-search-items-item-title:after {
202
+ /* points in the end */
203
+ content: '';
204
+ /* absolute position */
205
+ position: absolute;
206
+ /* set position to right bottom corner of text */
207
+ right: 0;
208
+ /* set width and height */
209
+ width: 1em;
210
+ height: 1em;
211
+ margin-top: 0.2em;
212
+ /* bg color = bg color under block */
213
+ background: white;
214
  }
215
 
216
  /* CSS Fix for rendering issues with safari */
217
+ @media screen and (min-color-index: 0)
218
+ and(-webkit-min-device-pixel-ratio: 0) {
219
+ @media {
220
+ .aalb-admin-item-search-items-item-title {
221
+ position: initial;
222
+ margin-left: 2em;
223
+ margin-right: 0em;
224
+ }
225
  }
226
+ }
227
 
228
  .aalb-admin-item-search-items-item-price {
229
+ font-size: 1em;
230
+ color: #b12704;
231
+ font-weight: bold;
232
  }
233
 
234
  .aalb-admin-item-search-items-item:hover {
235
+ background-image: linear-gradient(to bottom, #FEF8F2 0px, #FFF1E3 100%);
236
+ background-repeat: repeat-x;
237
+ border-color: #E77600;
238
  }
239
 
240
  .aalb-admin-popup-shortocde-wrapper {
241
+ display: block;
242
+ width: 100%;
243
  }
244
 
245
  .aalb-admin-popup-shortcode-options {
246
+ padding-top: 3%;
247
+ width: 100%;
248
+ -moz-column-gap: 10px;
249
+ -webkit-column-gap: 10px;
250
+ column-gap: 10px;
251
+ -moz-column-count: 3;
252
+ -webkit-column-count: 3;
253
+ column-count: 3;
254
  }
255
 
256
  .aalb-admin-popup-shortcode-options label {
257
+ display: block;
258
+ text-align: left;
259
  }
260
 
261
  .aalb-admin-item-search-templates {
262
+ width: 100%;
263
  }
264
 
265
  .aalb-admin-popup-store {
266
+ width: 100%;
267
  }
268
 
269
  .aalb-admin-item-search-marketplaces {
270
+ width: 100%;
271
  }
272
 
273
  .aalb-add-shortcode-button {
274
+ padding-top: 20px;
275
  }
276
 
277
  .aalb-admin-popup-options {
278
+ position: relative;
279
  }
280
 
281
  #aalb-admin-popup-input-search {
282
+ position: absolute;
283
+ width: 100%;
284
+ left: 0;
285
+ margin-top: 1%;
286
+ height: 33px;
287
+ vertical-align: middle;
288
  }
289
 
290
  #aalb-admin-popup-search-button {
291
+ position: absolute;
292
+ right: 0;
293
  }
294
 
295
  .aalb-selected {
296
+ height: auto;
297
+ width: 100%;
298
+ padding-top: 10px;
299
+ padding-bottom: 10px;
300
  }
301
 
302
  .aalb-selected label {
303
+ display: block;
304
+ text-align: left;
305
+ padding: 15px 0px;
306
  }
307
 
308
  .aalb-selected-item {
309
+ border: 1px solid #eee;
310
+ float: left;
311
+ margin: 4px 4px 4px 4px;
312
+ position: relative;
313
+ width: 10%;
314
+ padding: 4px;
315
+ font-family: Helvetica;
316
  }
317
 
318
  .aalb-selected-item:hover {
319
+ border: 1px solid #900;
320
  }
321
 
322
  .aalb-selected-item-img {
323
+ display: block;
324
+ margin-top: auto;
325
+ margin-bottom: auto;
326
+ height: 90px;
327
+ margin-left: auto;
328
+ margin-right: auto;
329
+ max-width: 100%;
330
  }
331
 
332
  .aalb-selected-item-img-wrap {
333
  position: relative;
334
  height: 100%;
335
  }
336
+
337
  .aalb-selected-item-close {
338
  position: absolute;
339
  top: -12px;
351
  cursor: pointer;
352
  box-shadow: 1px 1px 4px #000;
353
  background-color: #a50200;
354
+ background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
355
+ background-image: linear-gradient(to bottom, #cb0400, #a50200);
356
  }
357
 
358
+ .aalb-selected-item-title h3 {
359
+ margin: 2px 3px 0 2px;
360
+ font-size: 8px;
361
+ line-height: 12px;
362
+ color: #000;
363
+ position: relative;
364
+ text-align: center;
365
+ display: block;
366
+ overflow: hidden;
367
+ height: 35px;
368
  }
369
 
370
  .aalb-selected-item-price {
371
+ text-align: center;
372
+ color: #900;
373
+ font-weight: bold;
374
+ margin: 2px;
375
  }
376
 
 
377
  .aalb-selected-asin {
378
+ display: none;
379
  }
admin/js/aalb_admin.js CHANGED
@@ -1,133 +1,133 @@
1
  /*
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
 
4
- Licensed under the GNU General Public License as published by the Free Software Foundation,
5
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
- A copy of the License is located in the "license" file accompanying this file.
7
 
8
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
- either express or implied. See the License for the specific language governing permissions
10
- and limitations under the License.
11
- */
12
 
13
  var template;
14
- var TB_WIDTH,TB_HEIGHT;
15
  var tb_remove;
16
  var link_id = "";
17
  var AALB_SHORTCODE_AMAZON_LINK = api_pref.AALB_SHORTCODE_AMAZON_LINK; //constant value from server side is reused here
18
  var AALB_SHORTCODE_AMAZON_TEXT = api_pref.AALB_SHORTCODE_AMAZON_TEXT;
19
 
20
- jQuery(document).ready(function() {
21
- // http://stackoverflow.com/questions/5557641/how-can-i-reset-div-to-its-original-state-after-it-has-been-modified-by-java
22
- jQuery("#aalb-admin-popup-content").data('old-state', jQuery("#aalb-admin-popup-content").html());
23
-
24
- //Load the search result template
25
- jQuery.get( api_pref.template_url, function(data) {
26
- template = Handlebars.compile(data);
27
- });
28
-
29
- //Resize thickbox on window resize
30
- jQuery(window).on('resize',resize_thickbox);
31
-
32
- //Storing the tb_remove function of Thickbox.js
33
- var old_tb_remove = window.tb_remove;
34
-
35
- //Custom tb_remove function
36
- tb_remove = function() {
37
- //call actual tb_remove
38
- old_tb_remove();
39
- //custom actions to execute
40
- jQuery(".aalb-selected-item").each(function(){
41
- aalb_remove_selected_item(this);
42
- });
43
- };
44
- });
45
 
46
  /**
47
  * Resizing thickbox on change in window dimensions
48
  * Setting a max width and height of 1280x800 px for readability and to lessen distortion
49
  */
50
- function resize_thickbox(){
51
- TB_WIDTH=Math.min(1280,0.6*jQuery(window).width());
52
- TB_HEIGHT=Math.min(800,0.9*jQuery(window).height());
53
- jQuery(document).find('#TB_ajaxContent').width(TB_WIDTH-35).height(TB_HEIGHT-90);
54
- jQuery(document).find('#TB_window').width(TB_WIDTH).height(TB_HEIGHT);
55
- jQuery(document).find('#TB_window').css({marginLeft: '-' + TB_WIDTH / 2 + 'px',top: TB_HEIGHT/12});
56
- jQuery(document).find('#TB_window').removeClass();
57
  }
58
 
59
  /**
60
  * Ensure a button click on a return key press event
61
- *
62
- * @param HTML_DOM_EVENT event OnKeyPress event
63
  * @param HTML_DOM_OBJECT button_to_click Button id to click on a return key press event
64
  */
65
- function aalb_submit_event(event,button_to_click) {
66
- //Code for the RETURN key is 13
67
- if(event.keyCode==13) {
68
- event.preventDefault();
69
- jQuery('#'+button_to_click).click();
70
- }
71
  }
72
 
73
  /**
74
  * Removes the selected HTML element
75
- *
76
- * @param HTML_DOM_OBJECT element HTML element to be removed
77
  */
78
- function aalb_remove_selected_item(element) {
79
- jQuery(element).remove();
80
  }
81
 
82
  /**
83
  * Display pop up thickbox
84
  */
85
  function aalb_admin_show_create_shortcode_popup() {
86
- // http://stackoverflow.com/questions/5557641/how-can-i-reset-div-to-its-original-state-after-it-has-been-modified-by-java
87
- jQuery("#aalb-admin-popup-content").html(jQuery("#aalb-admin-popup-content").data('old-state'));
88
- var selected = aalb_get_selected_text_from_editor();
89
- var keywords = jQuery("#aalb-admin-input-search").val();
90
- if (selected) {
91
- tb_show('Add Amazon Associates Link Builder Shortcode', '#TB_inline?inlineId=aalb-admin-popup-container',false);
92
- resize_thickbox();
93
-
94
- //Setting Search field with selected value.
95
- jQuery("#aalb-admin-input-search").attr('value',selected);
96
- // Getting the ItemSearch results
97
- aalb_admin_get_item_search_items(jQuery("#aalb-admin-input-search").val());
98
- jQuery("#aalb-admin-popup-input-search").attr('value',selected);
99
- //Chose ProductLink template By Default when some text is selected.
100
- jQuery("#aalb_template_names_list").val('ProductLink');
101
- } else if (keywords) {
102
- // Showing the TB and resetting the width - http://wordpress.stackexchange.com/questions/114107/thickbox-width-cant-be-changed-in-admin
103
- tb_show('Add Amazon Associates Link Builder Shortcode', '#TB_inline?inlineId=aalb-admin-popup-container',false);
104
- resize_thickbox();
105
-
106
- // Getting the ItemSearch results
107
- aalb_admin_get_item_search_items(jQuery("#aalb-admin-input-search").val());
108
- jQuery("#aalb-admin-popup-input-search").attr('value',keywords);
109
- } else {
110
- alert("Please enter the keywords or select some text from the editor.");
111
- jQuery("#aalb-admin-input-search").focus();
112
- }
113
-
114
  }
115
 
116
  /**
117
  * Search items from within the thickbox
118
  */
119
  function aalb_admin_popup_search_items() {
120
- var keywords = jQuery("#aalb-admin-popup-input-search").val();
121
- jQuery("#aalb-admin-popup-content").html(jQuery("#aalb-admin-popup-content").data('old-state'));
122
- if (keywords) {
123
- // Getting the ItemSearch results
124
- aalb_admin_get_item_search_items(keywords);
125
- jQuery("#aalb-admin-popup-input-search").attr('value',keywords);
126
-
127
- } else {
128
- alert("Please enter the keywords");
129
- jQuery("#aalb-admin-popup-input-search").focus();
130
- }
131
  }
132
 
133
  /**
@@ -135,178 +135,185 @@ function aalb_admin_popup_search_items() {
135
  *
136
  * @param String keywords Items to search for.
137
  */
138
- function aalb_admin_get_item_search_items(keywords) {
139
- marketplace = aalb_get_selected_marketplace();
140
- marketplace = marketplace ? marketplace : api_pref.marketplace;
141
- jQuery.get( api_pref.ajax_url, { "action" : api_pref.action, "item_search_nonce" : api_pref.item_search_nonce, "keywords" : keywords, "marketplace" : marketplace, "store_id" : api_pref.store_id}, function(xml) {
142
- var items_xml = jQuery(xml).find("Item");
143
- if(items_xml.length>0) {
144
- var items = [];
145
- var i=0;
146
- items_xml.each(function() {
147
- //selecting maximum of max_search_result_items elements
148
- if(i<api_pref.max_search_result_items){
149
- var item = {};
150
- item.asin = jQuery(this).find("ASIN").text();
151
- item.title = jQuery(this).find("Title").text();
152
- item.image = jQuery(this).find("LargeImage").first().find("URL").text();
153
- item.price = jQuery(this).find("LowestNewPrice").find("FormattedPrice").text();
154
- items.push(item);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  }
156
- i++;
157
- });
158
-
159
- var html = template(items);
160
- jQuery(".aalb-admin-item-search-items").append(html);
161
- jQuery("#aalb-admin-popup-more-results").attr('href',jQuery(xml).find("MoreSearchResultsUrl").text());
162
- jQuery(".aalb-admin-item-search-loading").slideUp("slow");
163
- jQuery(".aalb-admin-item-search").fadeIn("slow");
164
- jQuery(".aalb-admin-item-search-items-item").on("click", function() {
165
- var dataAsin = jQuery(this).attr("data-asin");
166
- var productImage = jQuery(this).find("img").attr("src");
167
- var productTitle = jQuery(this).find("div.aalb-admin-item-search-items-item-title").text();
168
- var productPrice = jQuery(this).find("div.aalb-admin-item-search-items-item-price").text();
169
-
170
- var selectedAsinHTML = '<div class="aalb-selected-item" onclick="aalb_remove_selected_item(this)"';
171
- selectedAsinHTML += ' data-asin="' + dataAsin + '">';
172
- selectedAsinHTML += '<div class="aalb-selected-item-img-wrap"><span class="aalb-selected-item-close">&times;</span>';
173
- selectedAsinHTML += '<img class="aalb-selected-item-img" src="' + productImage + '"></img></div>';
174
- selectedAsinHTML += '<div class="aalb-selected-item-title"><h3>' + productTitle + '</h3>';
175
- selectedAsinHTML += '<p class="aalb-selected-item-price">' + productPrice + '<br></p></div>';
176
-
177
- jQuery(".aalb-selected").append(selectedAsinHTML);
178
- });
179
- } else {
180
- errors_xml = jQuery(xml).find("Error");
181
- if(errors_xml.length > 0) {
182
- var htmlerror = "";
183
- errors_xml.each(function() {
184
- htmlerror += jQuery(this).find("Message").text() + "<br>";
185
- });
186
- jQuery(".aalb-admin-item-search-loading").html(htmlerror);
187
- } else {
188
- jQuery(".aalb-admin-item-search-loading").html(xml);
189
- }
190
- }
191
- });
192
- jQuery("#aalb-add-shortcode-button").unbind().click(function(){
193
- var selectedAsins=aalb_get_selected_asins();
194
- var selected = aalb_get_selected_text_from_editor();
195
- if(selectedAsins){
196
- if(selected) {
197
- /* If there was some text selected in the wordpress post editor. Implies amazon_textlink */
198
- var selectedAsinsLength = selectedAsins.split(",").length;
199
- if(selectedAsinsLength > 1) {
200
- alert("Failed to create Text Link shortcode. Editor has some text selected. Only one item can be selected while adding text links");
201
  } else {
202
- jQuery("#aalb-add-shortcode-alert").fadeTo("fast",1);
203
- aalb_add_shortcode(AALB_SHORTCODE_AMAZON_TEXT);
204
  }
205
- } else {
206
- jQuery("#aalb-add-shortcode-alert").fadeTo("fast",1);
207
- aalb_add_shortcode(AALB_SHORTCODE_AMAZON_LINK);
208
- }
209
- } else {
210
- alert("Please select atleast one product for display");
211
- }
212
- });
213
  }
214
 
215
  /**
216
  * Adds the given shortcode to the editor
217
- *
218
  * @param String Shortcode type to be added
219
  */
220
- function aalb_add_shortcode(shortcodeName) {
221
- var shortcodeJson;
222
- var selectedAsins=aalb_get_selected_asins();
223
- var selectedTemplate=aalb_get_selected_template();
224
- var selectedStore=aalb_get_selected_store();
225
- var selectedMarketplace=aalb_get_selected_marketplace_abbreviation();
226
-
227
- if(shortcodeName == AALB_SHORTCODE_AMAZON_LINK) {
228
- shortcodeJson = {
229
- "name" : AALB_SHORTCODE_AMAZON_LINK,
230
- "params" : {
231
- "asins" : selectedAsins,
232
- "template" : selectedTemplate,
233
- "store" : selectedStore,
234
- "marketplace" : selectedMarketplace,
235
- }
236
- };
237
- } else if (shortcodeName == AALB_SHORTCODE_AMAZON_TEXT) {
238
- shortcodeJson = {
239
- "name" : AALB_SHORTCODE_AMAZON_TEXT,
240
- "params" : {
241
- "asin" : selectedAsins,
242
- "text" : aalb_get_selected_text_from_editor(),
243
- "template" : selectedTemplate,
244
- "store" : selectedStore,
245
- "marketplace" : selectedMarketplace,
246
- }
247
- };
248
- } else {
249
- console.log("Invalid Shortcode provided!");
250
- return;
251
- }
252
- aalb_get_link_id(shortcodeJson);
253
  }
254
 
255
  /**
256
  * Handler function when the Add Shortcode button is clicked
257
  * and link id is retrieved.
258
- *
259
- * @param Object shortcodeJson Object describing the shortcode
260
  */
261
- function aalb_add_shortcode_click_handler(shortcodeJson) {
262
- aalb_create_shortcode(shortcodeJson);
263
- tb_remove();
264
  }
265
 
266
  /**
267
  * Builds shortcode from given JSON
268
- *
269
- * @param Object shortcodeJson Object describing the shortcode
270
  *
271
  * @return String returns the Shortcode String
272
  */
273
- function buildShortcode(shortcodeJson) {
274
- var shortcodeParamsString = "";
275
- for (var shortcodeParam in shortcodeJson.params) {
276
- if( shortcodeJson.params.hasOwnProperty(shortcodeParam) ) {
277
- shortcodeParamsString += " " + shortcodeParam + "='" + shortcodeJson.params[shortcodeParam] + "'";
278
- }
279
- }
280
-
281
- var shortcodeString = "[" + shortcodeJson.name + shortcodeParamsString + "]";
282
- return shortcodeString;
283
  }
284
 
285
  /**
286
  * Get unique link id whenever add shortcode button is clicked
287
- *
288
- * @param Object shortcodeJson Object describing the shortcode
289
  */
290
- function aalb_get_link_id(shortcodeJson) {
291
- jQuery.post( api_pref.ajax_url, { "action": "get_link_code", "shortcode_name": shortcodeJson.name, "shortcode_params": shortcodeJson.params
292
- }).success(function (data) {
293
- link_id = data;
294
- }).fail(function () {
295
- link_id = "";
296
- }).always(function () {
297
- shortcodeJson.params.link_id = link_id;
298
- jQuery("#aalb-add-shortcode-alert").fadeTo("slow", 0);
299
- aalb_add_shortcode_click_handler(shortcodeJson);
300
- });
 
301
  }
302
 
303
  /**
304
  * Add the shortcode to the display editor
305
  *
306
- * @param Object shortcodeJson Object describing the shortcode
307
  */
308
- function aalb_create_shortcode(shortcodeJson) {
309
- send_to_editor(buildShortcode(shortcodeJson));
310
  }
311
 
312
  /**
@@ -315,25 +322,25 @@ function aalb_create_shortcode(shortcodeJson) {
315
  * @return String Selected Asins
316
  */
317
  function aalb_get_selected_asins() {
318
- var selectedAsins = "";
319
- jQuery(".aalb-selected-item").each(function(){
320
- selectedAsins += jQuery(this).attr("data-asin") + ",";
321
- });
322
- return selectedAsins.slice(0,-1);
323
  }
324
 
325
  /**
326
  * Get the selected Template style
327
  *
328
- * @ereturn String Selected Template style
329
  */
330
  function aalb_get_selected_template() {
331
- var selectedTemplate = "";
332
- var $selectedTemplate = jQuery("#aalb_template_names_list option:selected");
333
- if ($selectedTemplate.length > 0) {
334
- selectedTemplate = $selectedTemplate.val();
335
- }
336
- return selectedTemplate;
337
  }
338
 
339
  /**
@@ -342,7 +349,7 @@ function aalb_get_selected_template() {
342
  * @return String Selected Associate tag
343
  */
344
  function aalb_get_selected_store() {
345
- return jQuery('#aalb-admin-popup-store-id').val();
346
  }
347
 
348
  /**
@@ -351,12 +358,12 @@ function aalb_get_selected_store() {
351
  * @return String Selected Marketplace to search the product
352
  */
353
  function aalb_get_selected_marketplace() {
354
- var selectedMarketplace = "";
355
- var $selectedMarketplace = jQuery("#aalb_marketplace_names_list option:selected");
356
- if ($selectedMarketplace.length > 0) {
357
- selectedMarketplace = $selectedMarketplace.val();
358
- }
359
- return selectedMarketplace;
360
  }
361
 
362
  /**
@@ -365,12 +372,12 @@ function aalb_get_selected_marketplace() {
365
  * @return String Selected Marketplace abbreviation for the shortcode
366
  */
367
  function aalb_get_selected_marketplace_abbreviation() {
368
- var selectedMarketplace = "";
369
- var $selectedMarketplace = jQuery("#aalb_marketplace_names_list option:selected");
370
- if ($selectedMarketplace.length > 0) {
371
- selectedMarketplace = $selectedMarketplace.text();
372
- }
373
- return selectedMarketplace;
374
  }
375
 
376
  /**
@@ -379,9 +386,9 @@ function aalb_get_selected_marketplace_abbreviation() {
379
  * @return String Selected text from the wordpress post editor.
380
  */
381
  function aalb_get_selected_text_from_editor() {
382
- if(tinyMCE.activeEditor) {
383
- return tinyMCE.activeEditor.selection.getContent({format : "text"});
384
- } else {
385
- return null;
386
- }
387
  }
1
  /*
2
+ Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
 
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
 
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
 
13
  var template;
14
+ var TB_WIDTH, TB_HEIGHT;
15
  var tb_remove;
16
  var link_id = "";
17
  var AALB_SHORTCODE_AMAZON_LINK = api_pref.AALB_SHORTCODE_AMAZON_LINK; //constant value from server side is reused here
18
  var AALB_SHORTCODE_AMAZON_TEXT = api_pref.AALB_SHORTCODE_AMAZON_TEXT;
19
 
20
+ jQuery( document ).ready( function() {
21
+ // http://stackoverflow.com/questions/5557641/how-can-i-reset-div-to-its-original-state-after-it-has-been-modified-by-java
22
+ jQuery( "#aalb-admin-popup-content" ).data( 'old-state', jQuery( "#aalb-admin-popup-content" ).html() );
23
+
24
+ //Load the search result template
25
+ jQuery.get( api_pref.template_url, function( data ) {
26
+ template = Handlebars.compile( data );
27
+ } );
28
+
29
+ //Resize thickbox on window resize
30
+ jQuery( window ).on( 'resize', resize_thickbox );
31
+
32
+ //Storing the tb_remove function of Thickbox.js
33
+ var old_tb_remove = window.tb_remove;
34
+
35
+ //Custom tb_remove function
36
+ tb_remove = function() {
37
+ //call actual tb_remove
38
+ old_tb_remove();
39
+ //custom actions to execute
40
+ jQuery( ".aalb-selected-item" ).each( function() {
41
+ aalb_remove_selected_item( this );
42
+ } );
43
+ };
44
+ } );
45
 
46
  /**
47
  * Resizing thickbox on change in window dimensions
48
  * Setting a max width and height of 1280x800 px for readability and to lessen distortion
49
  */
50
+ function resize_thickbox() {
51
+ TB_WIDTH = Math.min( 1280, 0.6 * jQuery( window ).width() );
52
+ TB_HEIGHT = Math.min( 800, 0.9 * jQuery( window ).height() );
53
+ jQuery( document ).find( '#TB_ajaxContent' ).width( TB_WIDTH - 35 ).height( TB_HEIGHT - 90 );
54
+ jQuery( document ).find( '#TB_window' ).width( TB_WIDTH ).height( TB_HEIGHT );
55
+ jQuery( document ).find( '#TB_window' ).css( { marginLeft: '-' + TB_WIDTH / 2 + 'px', top: TB_HEIGHT / 12 } );
56
+ jQuery( document ).find( '#TB_window' ).removeClass();
57
  }
58
 
59
  /**
60
  * Ensure a button click on a return key press event
61
+ *
62
+ * @param HTML_DOM_EVENT event OnKeyPress event
63
  * @param HTML_DOM_OBJECT button_to_click Button id to click on a return key press event
64
  */
65
+ function aalb_submit_event( event, button_to_click ) {
66
+ //Code for the RETURN key is 13
67
+ if ( event.keyCode == 13 ) {
68
+ event.preventDefault();
69
+ jQuery( '#' + button_to_click ).click();
70
+ }
71
  }
72
 
73
  /**
74
  * Removes the selected HTML element
75
+ *
76
+ * @param HTML_DOM_OBJECT element HTML element to be removed.
77
  */
78
+ function aalb_remove_selected_item( element ) {
79
+ jQuery( element ).remove();
80
  }
81
 
82
  /**
83
  * Display pop up thickbox
84
  */
85
  function aalb_admin_show_create_shortcode_popup() {
86
+ // http://stackoverflow.com/questions/5557641/how-can-i-reset-div-to-its-original-state-after-it-has-been-modified-by-java
87
+ jQuery( "#aalb-admin-popup-content" ).html( jQuery( "#aalb-admin-popup-content" ).data( 'old-state' ) );
88
+ var selected = aalb_get_selected_text_from_editor();
89
+ var keywords = jQuery( "#aalb-admin-input-search" ).val();
90
+ if ( selected ) {
91
+ tb_show( 'Add Amazon Associates Link Builder Shortcode', '#TB_inline?inlineId=aalb-admin-popup-container', false );
92
+ resize_thickbox();
93
+
94
+ //Setting Search field with selected value.
95
+ jQuery( "#aalb-admin-input-search" ).attr( 'value', selected );
96
+ // Getting the ItemSearch results
97
+ aalb_admin_get_item_search_items( jQuery( "#aalb-admin-input-search" ).val() );
98
+ jQuery( "#aalb-admin-popup-input-search" ).attr( 'value', selected );
99
+ //Chose ProductLink template By Default when some text is selected.
100
+ jQuery( "#aalb_template_names_list" ).val( 'ProductLink' );
101
+ } else if ( keywords ) {
102
+ // Showing the TB and resetting the width - http://wordpress.stackexchange.com/questions/114107/thickbox-width-cant-be-changed-in-admin
103
+ tb_show( 'Add Amazon Associates Link Builder Shortcode', '#TB_inline?inlineId=aalb-admin-popup-container', false );
104
+ resize_thickbox();
105
+
106
+ // Getting the ItemSearch results
107
+ aalb_admin_get_item_search_items( jQuery( "#aalb-admin-input-search" ).val() );
108
+ jQuery( "#aalb-admin-popup-input-search" ).attr( 'value', keywords );
109
+ } else {
110
+ alert( "Please enter the keywords or select some text from the editor." );
111
+ jQuery( "#aalb-admin-input-search" ).focus();
112
+ }
113
+
114
  }
115
 
116
  /**
117
  * Search items from within the thickbox
118
  */
119
  function aalb_admin_popup_search_items() {
120
+ var keywords = jQuery( "#aalb-admin-popup-input-search" ).val();
121
+ jQuery( "#aalb-admin-popup-content" ).html( jQuery( "#aalb-admin-popup-content" ).data( 'old-state' ) );
122
+ if ( keywords ) {
123
+ // Getting the ItemSearch results
124
+ aalb_admin_get_item_search_items( keywords );
125
+ jQuery( "#aalb-admin-popup-input-search" ).attr( 'value', keywords );
126
+
127
+ } else {
128
+ alert( "Please enter the keywords" );
129
+ jQuery( "#aalb-admin-popup-input-search" ).focus();
130
+ }
131
  }
132
 
133
  /**
135
  *
136
  * @param String keywords Items to search for.
137
  */
138
+ function aalb_admin_get_item_search_items( keywords ) {
139
+ marketplace = aalb_get_selected_marketplace();
140
+ marketplace = marketplace ? marketplace : api_pref.marketplace;
141
+ jQuery.get( api_pref.ajax_url, {
142
+ "action": api_pref.action,
143
+ "item_search_nonce": api_pref.item_search_nonce,
144
+ "keywords": keywords,
145
+ "marketplace": marketplace,
146
+ "store_id": api_pref.store_id
147
+ }, function( xml ) {
148
+ var items_xml = jQuery( xml ).find( "Item" );
149
+ if ( items_xml.length > 0 ) {
150
+ var items = [];
151
+ var i = 0;
152
+ items_xml.each( function() {
153
+ //selecting maximum of max_search_result_items elements
154
+ if ( i < api_pref.max_search_result_items ) {
155
+ var item = {};
156
+ item.asin = jQuery( this ).find( "ASIN" ).text();
157
+ item.title = jQuery( this ).find( "Title" ).text();
158
+ item.image = jQuery( this ).find( "LargeImage" ).first().find( "URL" ).text();
159
+ item.price = jQuery( this ).find( "LowestNewPrice" ).find( "FormattedPrice" ).text();
160
+ items.push( item );
161
+ }
162
+ i++;
163
+ } );
164
+
165
+ var html = template( items );
166
+ jQuery( ".aalb-admin-item-search-items" ).append( html );
167
+ jQuery( "#aalb-admin-popup-more-results" ).attr( 'href', jQuery( xml ).find( "MoreSearchResultsUrl" ).text() );
168
+ jQuery( ".aalb-admin-item-search-loading" ).slideUp( "slow" );
169
+ jQuery( ".aalb-admin-item-search" ).fadeIn( "slow" );
170
+ jQuery( ".aalb-admin-item-search-items-item" ).on( "click", function() {
171
+ var dataAsin = jQuery( this ).attr( "data-asin" );
172
+ var productImage = jQuery( this ).find( "img" ).attr( "src" );
173
+ var productTitle = jQuery( this ).find( "div.aalb-admin-item-search-items-item-title" ).text();
174
+ var productPrice = jQuery( this ).find( "div.aalb-admin-item-search-items-item-price" ).text();
175
+
176
+ var selectedAsinHTML = '<div class="aalb-selected-item" onclick="aalb_remove_selected_item(this)"';
177
+ selectedAsinHTML += ' data-asin="' + dataAsin + '">';
178
+ selectedAsinHTML += '<div class="aalb-selected-item-img-wrap"><span class="aalb-selected-item-close">&times;</span>';
179
+ selectedAsinHTML += '<img class="aalb-selected-item-img" src="' + productImage + '"></img></div>';
180
+ selectedAsinHTML += '<div class="aalb-selected-item-title"><h3>' + productTitle + '</h3>';
181
+ selectedAsinHTML += '<p class="aalb-selected-item-price">' + productPrice + '<br></p></div>';
182
+
183
+ jQuery( ".aalb-selected" ).append( selectedAsinHTML );
184
+ } );
185
+ } else {
186
+ errors_xml = jQuery( xml ).find( "Error" );
187
+ if ( errors_xml.length > 0 ) {
188
+ var htmlerror = "";
189
+ errors_xml.each( function() {
190
+ htmlerror += jQuery( this ).find( "Message" ).text() + "<br>";
191
+ } );
192
+ jQuery( ".aalb-admin-item-search-loading" ).html( htmlerror );
193
+ } else {
194
+ jQuery( ".aalb-admin-item-search-loading" ).html( xml );
195
+ }
196
  }
197
+ } );
198
+ jQuery( "#aalb-add-shortcode-button" ).unbind().click( function() {
199
+ var selectedAsins = aalb_get_selected_asins();
200
+ var selected = aalb_get_selected_text_from_editor();
201
+ if ( selectedAsins ) {
202
+ if ( selected ) {
203
+ /* If there was some text selected in the wordpress post editor. Implies amazon_textlink */
204
+ var selectedAsinsLength = selectedAsins.split( "," ).length;
205
+ if ( selectedAsinsLength > 1 ) {
206
+ alert( "Failed to create Text Link shortcode. Editor has some text selected. Only one item can be selected while adding text links" );
207
+ } else {
208
+ jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "fast", 1 );
209
+ aalb_add_shortcode( AALB_SHORTCODE_AMAZON_TEXT );
210
+ }
211
+ } else {
212
+ jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "fast", 1 );
213
+ aalb_add_shortcode( AALB_SHORTCODE_AMAZON_LINK );
214
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  } else {
216
+ alert( "Please select at least one product for display" );
 
217
  }
218
+ } );
 
 
 
 
 
 
 
219
  }
220
 
221
  /**
222
  * Adds the given shortcode to the editor
223
+ *
224
  * @param String Shortcode type to be added
225
  */
226
+ function aalb_add_shortcode( shortcodeName ) {
227
+ var shortcodeJson;
228
+ var selectedAsins = aalb_get_selected_asins();
229
+ var selectedTemplate = aalb_get_selected_template();
230
+ var selectedStore = aalb_get_selected_store();
231
+ var selectedMarketplace = aalb_get_selected_marketplace_abbreviation();
232
+
233
+ if ( shortcodeName == AALB_SHORTCODE_AMAZON_LINK ) {
234
+ shortcodeJson = {
235
+ "name": AALB_SHORTCODE_AMAZON_LINK,
236
+ "params": {
237
+ "asins": selectedAsins,
238
+ "template": selectedTemplate,
239
+ "store": selectedStore,
240
+ "marketplace": selectedMarketplace,
241
+ }
242
+ };
243
+ } else if ( shortcodeName == AALB_SHORTCODE_AMAZON_TEXT ) {
244
+ shortcodeJson = {
245
+ "name": AALB_SHORTCODE_AMAZON_TEXT,
246
+ "params": {
247
+ "asin": selectedAsins,
248
+ "text": aalb_get_selected_text_from_editor(),
249
+ "template": selectedTemplate,
250
+ "store": selectedStore,
251
+ "marketplace": selectedMarketplace,
252
+ }
253
+ };
254
+ } else {
255
+ console.log( "Invalid Shortcode provided!" );
256
+ return;
257
+ }
258
+ aalb_get_link_id( shortcodeJson );
259
  }
260
 
261
  /**
262
  * Handler function when the Add Shortcode button is clicked
263
  * and link id is retrieved.
264
+ *
265
+ * @param Object shortcodeJson Object describing the shortcode
266
  */
267
+ function aalb_add_shortcode_click_handler( shortcodeJson ) {
268
+ aalb_create_shortcode( shortcodeJson );
269
+ tb_remove();
270
  }
271
 
272
  /**
273
  * Builds shortcode from given JSON
274
+ *
275
+ * @param Object shortcodeJson Object describing the shortcode
276
  *
277
  * @return String returns the Shortcode String
278
  */
279
+ function buildShortcode( shortcodeJson ) {
280
+ var shortcodeParamsString = "";
281
+ for ( var shortcodeParam in shortcodeJson.params ) {
282
+ if ( shortcodeJson.params.hasOwnProperty( shortcodeParam ) ) {
283
+ shortcodeParamsString += " " + shortcodeParam + "='" + shortcodeJson.params[ shortcodeParam ] + "'";
284
+ }
285
+ }
286
+
287
+ var shortcodeString = "[" + shortcodeJson.name + shortcodeParamsString + "]";
288
+ return shortcodeString;
289
  }
290
 
291
  /**
292
  * Get unique link id whenever add shortcode button is clicked
293
+ *
294
+ * @param Object shortcodeJson Object describing the shortcode
295
  */
296
+ function aalb_get_link_id( shortcodeJson ) {
297
+ jQuery.post( api_pref.ajax_url, {
298
+ "action": "get_link_code", "shortcode_name": shortcodeJson.name, "shortcode_params": shortcodeJson.params
299
+ } ).success( function( data ) {
300
+ link_id = data;
301
+ } ).fail( function() {
302
+ link_id = "";
303
+ } ).always( function() {
304
+ shortcodeJson.params.link_id = link_id;
305
+ jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "slow", 0 );
306
+ aalb_add_shortcode_click_handler( shortcodeJson );
307
+ } );
308
  }
309
 
310
  /**
311
  * Add the shortcode to the display editor
312
  *
313
+ * @param Object shortcodeJson Object describing the shortcode
314
  */
315
+ function aalb_create_shortcode( shortcodeJson ) {
316
+ send_to_editor( buildShortcode( shortcodeJson ) );
317
  }
318
 
319
  /**
322
  * @return String Selected Asins
323
  */
324
  function aalb_get_selected_asins() {
325
+ var selectedAsins = "";
326
+ jQuery( ".aalb-selected-item" ).each( function() {
327
+ selectedAsins += jQuery( this ).attr( "data-asin" ) + ",";
328
+ } );
329
+ return selectedAsins.slice( 0, -1 );
330
  }
331
 
332
  /**
333
  * Get the selected Template style
334
  *
335
+ * @return String Selected Template style
336
  */
337
  function aalb_get_selected_template() {
338
+ var selectedTemplate = "";
339
+ var $selectedTemplate = jQuery( "#aalb_template_names_list option:selected" );
340
+ if ( $selectedTemplate.length > 0 ) {
341
+ selectedTemplate = $selectedTemplate.val();
342
+ }
343
+ return selectedTemplate;
344
  }
345
 
346
  /**
349
  * @return String Selected Associate tag
350
  */
351
  function aalb_get_selected_store() {
352
+ return jQuery( '#aalb-admin-popup-store-id' ).val();
353
  }
354
 
355
  /**
358
  * @return String Selected Marketplace to search the product
359
  */
360
  function aalb_get_selected_marketplace() {
361
+ var selectedMarketplace = "";
362
+ var $selectedMarketplace = jQuery( "#aalb_marketplace_names_list option:selected" );
363
+ if ( $selectedMarketplace.length > 0 ) {
364
+ selectedMarketplace = $selectedMarketplace.val();
365
+ }
366
+ return selectedMarketplace;
367
  }
368
 
369
  /**
372
  * @return String Selected Marketplace abbreviation for the shortcode
373
  */
374
  function aalb_get_selected_marketplace_abbreviation() {
375
+ var selectedMarketplace = "";
376
+ var $selectedMarketplace = jQuery( "#aalb_marketplace_names_list option:selected" );
377
+ if ( $selectedMarketplace.length > 0 ) {
378
+ selectedMarketplace = $selectedMarketplace.text();
379
+ }
380
+ return selectedMarketplace;
381
  }
382
 
383
  /**
386
  * @return String Selected text from the wordpress post editor.
387
  */
388
  function aalb_get_selected_text_from_editor() {
389
+ if ( tinyMCE.activeEditor ) {
390
+ return tinyMCE.activeEditor.selection.getContent( { format: "text" } );
391
+ } else {
392
+ return null;
393
+ }
394
  }
admin/partials/aalb_meta_box.php CHANGED
@@ -12,80 +12,84 @@ either express or implied. See the License for the specific language governing p
12
  and limitations under the License.
13
  */
14
 
15
- $aalb_template_names = get_option(AALB_TEMPLATE_NAMES);
16
- $config_loader = new Aalb_Config_Loader();
17
- $aalb_marketplace_names = $config_loader->fetch_marketplaces();
18
- $helper = new Aalb_Helper();
19
- $aalb_store_id_names = $helper->get_store_ids_array();
20
- ?>
21
- <div id="aalb-admin-searchbox">
22
- <img src=<?=AALB_ADMIN_ICON?> id="aalb-admin-searchbox-amzlogo" style="height: 30px; width: 30px; padding: 0px;"><input type="text" id="aalb-admin-input-search" name="aalb-admin-input-search" placeholder="Enter keyword(s)" onkeypress='aalb_submit_event(event,"aalb-admin-button-create-amazon-shortcode")'/><a class="button" title="Add Amazon Associates Link Builder Shortcode" id="aalb-admin-button-create-amazon-shortcode" onclick="aalb_admin_show_create_shortcode_popup()">Search</a>
23
- </div>
24
- <div id="aalb-admin-popup-container" style="display:none;">
 
 
 
 
 
 
 
 
25
  <div class="aalb-admin-popup-options">
26
- <input type="text" id="aalb-admin-popup-input-search" name="aalb-admin-popup-input-search" placeholder="Enter keyword(s)" onkeypress='aalb_submit_event(event,"aalb-admin-popup-search-button")'/>
27
- <button class="aalb-btn aalb-btn-primary" id="aalb-admin-popup-search-button" type="button" onclick="aalb_admin_popup_search_items()" style="margin-top:1%">Search</button>
 
 
 
28
  </div><!--end .aalb-admin-popup-options-->
29
  <div id="aalb-admin-popup-content">
30
- <div class="aalb-admin-alert aalb-admin-alert-info aalb-admin-item-search-loading"><div class="aalb-admin-icon"><i class="fa fa-spinner fa-pulse"></i></div>Searching relevant products from Amazon
31
- </div><!--end .aalb-admin-item-search-loading-->
32
- <div class="aalb-admin-item-search">
33
- Click to select product(s) to advertise
34
- <div class="aalb-admin-item-search-items"></div>
35
- <a href="#" target="_blank" id="aalb-admin-popup-more-results" class="pull-right">Check more search results on Amazon</a>
36
- </div><!--end .aalb-admin-item-serch-->
 
 
 
37
  </div><!--end .aalb-admin-popup-content-->
38
  <div class="aalb-selected">
39
- <label>List of Selected Products</label>
40
  </div>
41
  <div class="aalb-admin-popup-shortocde-wrapper">
42
- <div class="aalb-admin-popup-shortcode-options">
43
- <div class="aalb-admin-item-search-templates">
44
- <label>Ad Template</label>
45
- <?php $aalb_default_template=get_option(AALB_DEFAULT_TEMPLATE,AALB_DEFAULT_TEMPLATE_NAME);?>
46
- <select id="aalb_template_names_list" name="aalb_template_names_list" style="width:100%">
47
- <?php
48
- foreach ($aalb_template_names as $aalb_template_name) {
49
- ?>
50
- <option value="<?=$aalb_template_name?>" <?php selected($aalb_default_template,$aalb_template_name); ?>><?=$aalb_template_name?></option>
51
- <?php
52
- }
53
- ?>
54
- </select>
55
- </div>
56
- <div class="aalb-admin-popup-store">
57
- <label>Associate ID</label>
58
- <?php $aalb_default_store_id=get_option(AALB_DEFAULT_STORE_ID,AALB_DEFAULT_STORE_ID_NAME);?>
59
- <select id="aalb-admin-popup-store-id" name="aalb-admin-popup-store-id" style="width:100%">
60
- <?php
61
- foreach ($aalb_store_id_names as $aalb_store_id) {
62
- ?>
63
- <option value="<?=$aalb_store_id?>" <?php selected($aalb_default_store_id,$aalb_store_id); ?>><?=$aalb_store_id?></option>
64
- <?php
65
- }
66
- ?>
67
- </select>
68
- </div>
69
- <div class="aalb-admin-item-search-marketplaces">
70
- <label>Marketplace</label>
71
- <?php $aalb_default_marketplace=get_option(AALB_DEFAULT_MARKETPLACE,AALB_DEFAULT_MARKETPLACE_NAME);?>
72
- <select id="aalb_marketplace_names_list" name="aalb_marketplace_names_list" style="width:100%">
73
- <?php
74
- foreach ($aalb_marketplace_names as $aalb_marketplace => $aalb_marketplace_abbr) {
75
- ?>
76
- <option value="<?=$aalb_marketplace?>" <?php selected($aalb_default_marketplace,$aalb_marketplace_abbr); ?>><?=$aalb_marketplace_abbr?></option>
77
- <?php
78
- }
79
- ?>
80
- </select>
81
  </div>
82
- </div>
83
  </div><!--end .aalb-admin-popup-shortcode-options-->
84
  <div class="aalb-add-shortcode-button">
85
- <button class="aalb-btn aalb-btn-primary" id="aalb-add-shortcode-button" type="button">Add Shortcode</button>
86
- <div id="aalb-add-shortcode-alert"><div class="aalb-admin-icon"><i class="fa fa-spinner fa-pulse"></i></div>Creating shortcode. Please wait....
87
- </div>
 
 
88
  </div><!--end .aalb-add-shortcode-button-->
89
- </div><!--end .aalb-admin-popup-container-->
90
- <?php
91
  ?>
12
  and limitations under the License.
13
  */
14
 
15
+ $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
16
+ $config_loader = new Aalb_Config_Loader();
17
+ $aalb_marketplace_names = $config_loader->fetch_marketplaces();
18
+ $helper = new Aalb_Helper();
19
+ $aalb_store_id_names = $helper->get_store_ids_array();
20
+ ?>
21
+ <div id="aalb-admin-searchbox">
22
+ <img src=<?= AALB_ADMIN_ICON ?> id="aalb-admin-searchbox-amzlogo"
23
+ style="height: 30px; width: 30px; padding: 0px;">
24
+ <input type="text" id="aalb-admin-input-search"
25
+ name="aalb-admin-input-search"
26
+ placeholder="Enter keyword(s)"
27
+ onkeypress='aalb_submit_event(event,"aalb-admin-button-create-amazon-shortcode")'/>
28
+ <a class="button" title="Add Amazon Associates Link Builder Shortcode"
29
+ id="aalb-admin-button-create-amazon-shortcode" onclick="aalb_admin_show_create_shortcode_popup()">Search
30
+ </a>
31
+ </div>
32
+ <div id="aalb-admin-popup-container" style="display:none;">
33
  <div class="aalb-admin-popup-options">
34
+ <input type="text" id="aalb-admin-popup-input-search" name="aalb-admin-popup-input-search"
35
+ placeholder="Enter keyword(s)" onkeypress='aalb_submit_event(event,"aalb-admin-popup-search-button")'/>
36
+ <button class="aalb-btn aalb-btn-primary" id="aalb-admin-popup-search-button" type="button"
37
+ onclick="aalb_admin_popup_search_items()" style="margin-top:1%">Search
38
+ </button>
39
  </div><!--end .aalb-admin-popup-options-->
40
  <div id="aalb-admin-popup-content">
41
+ <div class="aalb-admin-alert aalb-admin-alert-info aalb-admin-item-search-loading">
42
+ <div class="aalb-admin-icon"><i class="fa fa-spinner fa-pulse"></i></div>
43
+ Searching relevant products from Amazon
44
+ </div><!--end .aalb-admin-item-search-loading-->
45
+ <div class="aalb-admin-item-search">
46
+ Click to select product(s) to advertise
47
+ <div class="aalb-admin-item-search-items"></div>
48
+ <a href="#" target="_blank" id="aalb-admin-popup-more-results" class="pull-right">Check more search results
49
+ on Amazon</a>
50
+ </div><!--end .aalb-admin-item-serch-->
51
  </div><!--end .aalb-admin-popup-content-->
52
  <div class="aalb-selected">
53
+ <label>List of Selected Products</label>
54
  </div>
55
  <div class="aalb-admin-popup-shortocde-wrapper">
56
+ <div class="aalb-admin-popup-shortcode-options">
57
+ <div class="aalb-admin-item-search-templates">
58
+ <label>Ad Template</label>
59
+ <?php $aalb_default_template = get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ); ?>
60
+ <select id="aalb_template_names_list" name="aalb_template_names_list" style="width:100%">
61
+ <?php foreach ( $aalb_template_names as $aalb_template_name ) { ?>
62
+ <option value="<?= $aalb_template_name ?>" <?php selected( $aalb_default_template, $aalb_template_name ); ?>><?= $aalb_template_name ?></option>
63
+ <?php } ?>
64
+ </select>
65
+ </div>
66
+ <div class="aalb-admin-popup-store">
67
+ <label>Associate ID</label>
68
+ <?php $aalb_default_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME ); ?>
69
+ <select id="aalb-admin-popup-store-id" name="aalb-admin-popup-store-id" style="width:100%">
70
+ <?php foreach ( $aalb_store_id_names as $aalb_store_id ) { ?>
71
+ <option value="<?= $aalb_store_id ?>" <?php selected( $aalb_default_store_id, $aalb_store_id ); ?>> <?= $aalb_store_id ?> </option>
72
+ <?php } ?>
73
+ </select>
74
+ </div>
75
+ <div class="aalb-admin-item-search-marketplaces">
76
+ <label>Marketplace</label>
77
+ <?php $aalb_default_marketplace = get_option( AALB_DEFAULT_MARKETPLACE, AALB_DEFAULT_MARKETPLACE_NAME ); ?>
78
+ <select id="aalb_marketplace_names_list" name="aalb_marketplace_names_list" style="width:100%">
79
+ <?php foreach ( $aalb_marketplace_names as $aalb_marketplace => $aalb_marketplace_abbr ) { ?>
80
+ <option value="<?= $aalb_marketplace ?>" <?php selected( $aalb_default_marketplace, $aalb_marketplace_abbr ); ?>><?= $aalb_marketplace_abbr ?></option>
81
+ <?php } ?>
82
+ </select>
83
+ </div>
 
 
 
 
 
 
 
 
 
 
 
84
  </div>
 
85
  </div><!--end .aalb-admin-popup-shortcode-options-->
86
  <div class="aalb-add-shortcode-button">
87
+ <button class="aalb-btn aalb-btn-primary" id="aalb-add-shortcode-button" type="button">Add Shortcode</button>
88
+ <div id="aalb-add-shortcode-alert">
89
+ <div class="aalb-admin-icon"><i class="fa fa-spinner fa-pulse"></i></div>
90
+ Creating shortcode. Please wait....
91
+ </div>
92
  </div><!--end .aalb-add-shortcode-button-->
93
+ </div><!--end .aalb-admin-popup-container-->
94
+ <?php
95
  ?>
admin/sidebar/aalb_sidebar.php CHANGED
@@ -15,114 +15,120 @@ and limitations under the License.
15
  /**
16
  * The class for adding menu and submenu pages on the sidebar.
17
  * Registers the settings using the Wordpress Settings API for suing in the partials
18
- *
19
  * @since 1.0.0
20
  * @package AmazonAssociatesLinkBuilder
21
  * @subpackage AmazonAssociatesLinkBuilder/admin/sidebar
22
  */
23
  class Aalb_Sidebar {
24
 
25
- /**
26
- * Adds categories to the menu page
27
- *
28
- * @since 1.0.0
29
- */
30
- public function register_sidebar_config_page() {
31
- // Create new top-level menu
32
- add_menu_page(AALB_PROJECT_TITLE, AALB_PROJECT_TITLE, 'manage_options', 'associates-link-builder-about', array($this, 'about_callback'), AALB_ICON);
33
- add_submenu_page('associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' About', 'About', 'manage_options', 'associates-link-builder-about', array($this, 'about_callback'));
34
- add_submenu_page('associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' Settings', 'Settings', 'manage_options', 'associates-link-builder-settings', array($this, 'settings_callback'));
35
- add_submenu_page('associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' Templates', 'Templates', 'manage_options', 'associates-link-builder-templates', array($this, 'templates_callback'));
36
- }
37
-
38
- /**
39
- * Registers credentials to the config group
40
- *
41
- * @since 1.0.0
42
- */
43
- public function register_cred_config_group() {
44
- // Register Credentials
45
- register_setting(AALB_CRED_CONFIG_GROUP, AALB_AWS_ACCESS_KEY, array($this, 'validate_access_key'));
46
- register_setting(AALB_CRED_CONFIG_GROUP, AALB_AWS_SECRET_KEY, array($this, 'validate_secret_key'));
47
- register_setting(AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_STORE_ID);
48
- register_setting(AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_MARKETPLACE);
49
- register_setting(AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_TEMPLATE);
50
- register_setting(AALB_CRED_CONFIG_GROUP, AALB_STORE_ID_NAMES);
51
- }
52
-
53
- /**
54
- * Load the about page partial
55
- * Callbacks to load the page makes the url to use the slug, making it clean.
56
- *
57
- * @since 1.0.0
58
- */
59
- public function about_callback() {
60
- require_once(AALB_ABOUT_PHP);
61
- }
62
-
63
- /**
64
- * Load the settings page partial
65
- * The page to save the credentials and default settings of the admin.
66
- *
67
- * @since 1.0.0
68
- */
69
- public function settings_callback() {
70
- require_once(AALB_CREDENTIALS_PHP);
71
- }
72
-
73
- /**
74
- * Load the template page partial
75
- * The page to make changes to the templates, add new templates or remove existing templates.
76
- *
77
- * @since 1.0.0
78
- */
79
- public function templates_callback() {
80
- require_once(AALB_TEMPLATE_PHP);
81
- }
82
-
83
- /**
84
- * Sanitize the access key provided by the admin.
85
- * Encrypt the access key and store in the db.
86
- *
87
- * @since 1.0.0
88
- * @param string $input Access key input by the user.
89
- */
90
- public function validate_access_key($input) {
91
- $old_data = get_option(AALB_AWS_ACCESS_KEY);
92
- return $this->encrypt_keys($input, $old_data);
93
- }
94
-
95
- /**
96
- * Sanitize the secret key provided by the admin.
97
- * Encrypt the secret key and store in the db.
98
- *
99
- * @since 1.0.0
100
- * @param string $input Secret key input by the user.
101
- */
102
- public function validate_secret_key($input) {
103
- $old_data = get_option(AALB_AWS_SECRET_KEY);
104
- return $this->encrypt_keys($input, $old_data);
105
- }
106
-
107
- /**
108
- * Encrypt the keys provided by the user.
109
- * If the data already exists in the database, then do not retrieve and print it on the viewer page.
110
- * Else encrypt the data and store it in the db.
111
- *
112
- * @since 1.0.0
113
- * @param string $input Key input by the user to encrypt.
114
- * @param string $old_data The data if already stored in the database.
115
- */
116
- private function encrypt_keys($input, $old_data) {
117
- if (!isset($input) || trim($input) === '') {
118
- return $input;
119
- } elseif ($input == AALB_AWS_SECRET_KEY_MASK){
120
- return $old_data;
121
  }
122
 
123
- $output = base64_encode(openssl_encrypt($input, AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV));
124
- return $output;
125
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
  }
128
 
15
  /**
16
  * The class for adding menu and submenu pages on the sidebar.
17
  * Registers the settings using the Wordpress Settings API for suing in the partials
18
+ *
19
  * @since 1.0.0
20
  * @package AmazonAssociatesLinkBuilder
21
  * @subpackage AmazonAssociatesLinkBuilder/admin/sidebar
22
  */
23
  class Aalb_Sidebar {
24
 
25
+ /**
26
+ * Adds categories to the menu page
27
+ *
28
+ * @since 1.0.0
29
+ */
30
+ public function register_sidebar_config_page() {
31
+ // Create new top-level menu
32
+ add_menu_page( AALB_PROJECT_TITLE, AALB_PROJECT_TITLE, 'manage_options', 'associates-link-builder-about', array( $this, 'about_callback' ), AALB_ICON );
33
+ add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' About', 'About', 'manage_options', 'associates-link-builder-about', array( $this, 'about_callback' ) );
34
+ add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' Settings', 'Settings', 'manage_options', 'associates-link-builder-settings', array( $this, 'settings_callback' ) );
35
+ add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' Templates', 'Templates', 'manage_options', 'associates-link-builder-templates', array( $this, 'templates_callback' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
 
38
+ /**
39
+ * Registers credentials to the config group
40
+ *
41
+ * @since 1.0.0
42
+ */
43
+ public function register_cred_config_group() {
44
+ // Register Credentials
45
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_AWS_ACCESS_KEY, array( $this, 'validate_access_key' ) );
46
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_AWS_SECRET_KEY, array( $this, 'validate_secret_key' ) );
47
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_STORE_ID );
48
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_MARKETPLACE );
49
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_TEMPLATE );
50
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_STORE_ID_NAMES );
51
+ }
52
+
53
+ /**
54
+ * Load the about page partial
55
+ * Callbacks to load the page makes the url to use the slug, making it clean.
56
+ *
57
+ * @since 1.0.0
58
+ */
59
+ public function about_callback() {
60
+ require_once( AALB_ABOUT_PHP );
61
+ }
62
+
63
+ /**
64
+ * Load the settings page partial
65
+ * The page to save the credentials and default settings of the admin.
66
+ *
67
+ * @since 1.0.0
68
+ */
69
+ public function settings_callback() {
70
+ require_once( AALB_CREDENTIALS_PHP );
71
+ }
72
+
73
+ /**
74
+ * Load the template page partial
75
+ * The page to make changes to the templates, add new templates or remove existing templates.
76
+ *
77
+ * @since 1.0.0
78
+ */
79
+ public function templates_callback() {
80
+ require_once( AALB_TEMPLATE_PHP );
81
+ }
82
+
83
+ /**
84
+ * Sanitize the access key provided by the admin.
85
+ * Encrypt the access key and store in the db.
86
+ *
87
+ * @since 1.0.0
88
+ *
89
+ * @param string $input Access key input by the user.
90
+ */
91
+ public function validate_access_key( $input ) {
92
+ $old_data = get_option( AALB_AWS_ACCESS_KEY );
93
+
94
+ return $this->encrypt_keys( $input, $old_data );
95
+ }
96
+
97
+ /**
98
+ * Sanitize the secret key provided by the admin.
99
+ * Encrypt the secret key and store in the db.
100
+ *
101
+ * @since 1.0.0
102
+ *
103
+ * @param string $input Secret key input by the user.
104
+ */
105
+ public function validate_secret_key( $input ) {
106
+ $old_data = get_option( AALB_AWS_SECRET_KEY );
107
+
108
+ return $this->encrypt_keys( $input, $old_data );
109
+ }
110
+
111
+ /**
112
+ * Encrypt the keys provided by the user.
113
+ * If the data already exists in the database, then do not retrieve and print it on the viewer page.
114
+ * Else encrypt the data and store it in the db.
115
+ *
116
+ * @since 1.0.0
117
+ *
118
+ * @param string $input Key input by the user to encrypt.
119
+ * @param string $old_data The data if already stored in the database.
120
+ */
121
+ private function encrypt_keys( $input, $old_data ) {
122
+ if ( ! isset( $input ) || trim( $input ) === '' ) {
123
+ return $input;
124
+ } elseif ( $input == AALB_AWS_SECRET_KEY_MASK ) {
125
+ return $old_data;
126
+ }
127
+
128
+ $output = base64_encode( openssl_encrypt( $input, AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV ) );
129
+
130
+ return $output;
131
+ }
132
 
133
  }
134
 
admin/sidebar/js/aalb_credentials.js CHANGED
@@ -1,54 +1,54 @@
1
  /*
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
 
4
- Licensed under the GNU General Public License as published by the Free Software Foundation,
5
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
- A copy of the License is located in the "license" file accompanying this file.
7
 
8
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
- either express or implied. See the License for the specific language governing permissions
10
- and limitations under the License.
11
- */
12
 
13
  /**
14
  * Update the Default Store ID dropdown onchange
15
  *
16
  * @param HTML DOM OBJECT element list of store IDs in "Store IDs" field
17
  */
18
- function aalb_credentials_store_ids_onchange(element) {
19
- var aalb_store_ids = element.value;
20
- var aalb_store_ids_array = aalb_store_ids.trim().split(/[\n]+/);
21
- //Selected Store ID
22
- var aalb_store_ids_selected = jQuery('#aalb_default_store_id').val();
23
- var aalb_store_id_dropdown_html = "";
24
- for(var i = 0; i < aalb_store_ids_array.length; i++) {
25
- if(aalb_store_ids_array[i].length>0){
26
- aalb_store_ids_array[i] = aalb_store_ids_array[i].trim();
27
- aalb_store_id_dropdown_html += "<option value='" + aalb_store_ids_array[i] + "'>" + aalb_store_ids_array[i] + "</option>\n";
 
 
 
 
 
 
 
 
 
 
 
28
  } else {
29
- //Remove empty lines
30
- aalb_store_ids_array.splice(i,1);
31
  }
32
- }
33
- jQuery('#aalb_store_id_names').val(aalb_store_ids_array.join("\r\n"));
34
- //Set the HTML of select dropdown with updated store ids
35
- jQuery('#aalb_default_store_id').html(aalb_store_id_dropdown_html);
36
- //Select the previously selected option value if it exists in the new list
37
- if (aalb_store_ids_selected.length > 0 && jQuery.inArray(aalb_store_ids_selected, aalb_store_ids_array) > 0){
38
- jQuery('#aalb_default_store_id').val(aalb_store_ids_selected);
39
- } else {
40
- //If no value is selected, automatically selects first element.
41
- jQuery("#aalb_default_store_id").val(jQuery("#aalb_default_store_id option:first").val());
42
- }
43
  }
44
  /**
45
  * OnClick Handler for aalb terms and conditions checkbox.
46
  *
47
  */
48
- jQuery('#aalb-terms-checkbox').click(function(){
49
- if(jQuery(this).is(':checked')){
50
- jQuery("#submit").removeAttr('disabled');
51
  } else {
52
- jQuery('#submit').attr('disabled','disabled');
53
  }
54
- });
1
  /*
2
+ Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
 
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
 
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
 
13
  /**
14
  * Update the Default Store ID dropdown onchange
15
  *
16
  * @param HTML DOM OBJECT element list of store IDs in "Store IDs" field
17
  */
18
+ function aalb_credentials_store_ids_onchange( element ) {
19
+ var aalb_store_ids = element.value;
20
+ var aalb_store_ids_array = aalb_store_ids.trim().split( /[\n]+/ );
21
+ //Selected Store ID
22
+ var aalb_store_ids_selected = jQuery( '#aalb_default_store_id' ).val();
23
+ var aalb_store_id_dropdown_html = "";
24
+ for ( var i = 0; i < aalb_store_ids_array.length; i++ ) {
25
+ if ( aalb_store_ids_array[ i ].length > 0 ) {
26
+ aalb_store_ids_array[ i ] = aalb_store_ids_array[ i ].trim();
27
+ aalb_store_id_dropdown_html += "<option value='" + aalb_store_ids_array[ i ] + "'>" + aalb_store_ids_array[ i ] + "</option>\n";
28
+ } else {
29
+ //Remove empty lines
30
+ aalb_store_ids_array.splice( i, 1 );
31
+ }
32
+ }
33
+ jQuery( '#aalb_store_id_names' ).val( aalb_store_ids_array.join( "\r\n" ) );
34
+ //Set the HTML of select dropdown with updated store ids
35
+ jQuery( '#aalb_default_store_id' ).html( aalb_store_id_dropdown_html );
36
+ //Select the previously selected option value if it exists in the new list
37
+ if ( aalb_store_ids_selected.length > 0 && jQuery.inArray( aalb_store_ids_selected, aalb_store_ids_array ) > 0 ) {
38
+ jQuery( '#aalb_default_store_id' ).val( aalb_store_ids_selected );
39
  } else {
40
+ //If no value is selected, automatically selects first element.
41
+ jQuery( "#aalb_default_store_id" ).val( jQuery( "#aalb_default_store_id option:first" ).val() );
42
  }
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
  /**
45
  * OnClick Handler for aalb terms and conditions checkbox.
46
  *
47
  */
48
+ jQuery( '#aalb-terms-checkbox' ).click( function() {
49
+ if ( jQuery( this ).is( ':checked' ) ) {
50
+ jQuery( "#submit" ).removeAttr( 'disabled' );
51
  } else {
52
+ jQuery( '#submit' ).attr( 'disabled', 'disabled' );
53
  }
54
+ } );
admin/sidebar/js/aalb_template.js CHANGED
@@ -1,80 +1,84 @@
1
  /*
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
 
4
- Licensed under the GNU General Public License as published by the Free Software Foundation,
5
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
- A copy of the License is located in the "license" file accompanying this file.
7
 
8
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
- either express or implied. See the License for the specific language governing permissions
10
- and limitations under the License.
11
- */
12
 
13
- var codeMirrorHtml = CodeMirror.fromTextArea(document.getElementById('aalb_template_template_html_box'), {
14
- lineNumbers: true,
15
- value: "",
16
- mode: "xml"
17
- });
18
 
19
- var codeMirrorCss = CodeMirror.fromTextArea(document.getElementById('aalb_template_template_css_box'), {
20
- lineNumbers: true,
21
- value: "",
22
- mode: "css"
23
- });
24
 
25
- jQuery.ajaxSetup ({
26
- //Disable caching of AJAX responses
27
- cache: false
28
- });
29
 
30
  /**
31
  * Trigger onChange event of the template select dropdown on page load
32
  */
33
- jQuery(document).ready(function() {
34
- if(jQuery('#aalb_template_list_select').val() != 'new') {
35
- jQuery("#aalb_template_list_select").trigger("change");
36
- }
37
- });
38
 
39
  /**
40
  * Set the JS and CSS of the particular template in the respective text area
41
  *
42
  * @param HTML DOM OBJECT element Selected Template name
43
  */
44
- function aalb_template_select_template_onchange(element) {
45
- if (element.value == 'new') {
46
- codeMirrorCss.setValue('');
47
- codeMirrorHtml.setValue('');
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
  }
79
 
80
  /**
@@ -82,20 +86,20 @@ function aalb_template_select_template_onchange(element) {
82
  *
83
  */
84
  function clone_existing_template() {
85
- var templateNameToClone = jQuery('#aalb_template_list_select').val();
86
- jQuery('#aalb_template_list_select').val('new');
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);
94
- var randomNumForPrefix = Math.floor((Math.random() * 1000) + 1);
95
- var prefixRegExObject = new RegExp('aalb-', "g");
96
- var prefixReplaceValue = 'aalb-' + randomNumForPrefix + '-';
97
- codeMirrorHtml.setValue(codeMirrorHtml.getValue().replace(prefixRegExObject, prefixReplaceValue));
98
- codeMirrorCss.setValue(codeMirrorCss.getValue().replace(prefixRegExObject, prefixReplaceValue));
99
  }
100
  }
101
 
@@ -103,7 +107,7 @@ function clone_existing_template() {
103
  * Sets the HTML and CSS boxes to read only if TRUE is passed.
104
  *
105
  */
106
- function set_template_read_only(isReadOnly) {
107
- codeMirrorHtml.setOption("readOnly", isReadOnly);
108
- codeMirrorCss.setOption("readOnly", isReadOnly);
109
  }
1
  /*
2
+ Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
 
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
 
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
 
13
+ var codeMirrorHtml = CodeMirror.fromTextArea( document.getElementById( 'aalb_template_template_html_box' ), {
14
+ lineNumbers: true,
15
+ value: "",
16
+ mode: "xml"
17
+ } );
18
 
19
+ var codeMirrorCss = CodeMirror.fromTextArea( document.getElementById( 'aalb_template_template_css_box' ), {
20
+ lineNumbers: true,
21
+ value: "",
22
+ mode: "css"
23
+ } );
24
 
25
+ jQuery.ajaxSetup( {
26
+ //Disable caching of AJAX responses
27
+ cache: false
28
+ } );
29
 
30
  /**
31
  * Trigger onChange event of the template select dropdown on page load
32
  */
33
+ jQuery( document ).ready( function() {
34
+ if ( jQuery( '#aalb_template_list_select' ).val() != 'new' ) {
35
+ jQuery( "#aalb_template_list_select" ).trigger( "change" );
36
+ }
37
+ } );
38
 
39
  /**
40
  * Set the JS and CSS of the particular template in the respective text area
41
  *
42
  * @param HTML DOM OBJECT element Selected Template name
43
  */
44
+ function aalb_template_select_template_onchange( element ) {
45
+ if ( element.value == 'new' ) {
46
+ codeMirrorCss.setValue( '' );
47
+ codeMirrorHtml.setValue( '' );
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, {
73
+ "action": "get_custom_template_content",
74
+ "css": base + ".css",
75
+ "mustache": base + ".mustache"
76
+ }, function( json ) {
77
+ codeMirrorCss.setValue( json.css );
78
+ codeMirrorHtml.setValue( json.mustache );
79
+ }, "json" );
80
+ }
81
  }
 
82
  }
83
 
84
  /**
86
  *
87
  */
88
  function clone_existing_template() {
89
+ var templateNameToClone = jQuery( '#aalb_template_list_select' ).val();
90
+ jQuery( '#aalb_template_list_select' ).val( 'new' );
91
+ jQuery( '#aalb_template_name' ).removeAttr( "readonly" );
92
+ jQuery( '#aalb_template_name' ).val( 'CopyOf-' + templateNameToClone );
93
+ jQuery( '#clone_template' ).attr( 'disabled', 'disabled' );
94
+ jQuery( '#submit_remove' ).attr( 'disabled', 'disabled' );
95
  //Add CSS Prefix for Amazon Default Templates to prevent style overlapping for clones
96
+ if ( wp_opt.aalb_default_templates.split( "," ).indexOf( templateNameToClone ) >= 0 ) {
97
+ set_template_read_only( false );
98
+ var randomNumForPrefix = Math.floor( (Math.random() * 1000) + 1 );
99
+ var prefixRegExObject = new RegExp( 'aalb-', "g" );
100
+ var prefixReplaceValue = 'aalb-' + randomNumForPrefix + '-';
101
+ codeMirrorHtml.setValue( codeMirrorHtml.getValue().replace( prefixRegExObject, prefixReplaceValue ) );
102
+ codeMirrorCss.setValue( codeMirrorCss.getValue().replace( prefixRegExObject, prefixReplaceValue ) );
103
  }
104
  }
105
 
107
  * Sets the HTML and CSS boxes to read only if TRUE is passed.
108
  *
109
  */
110
+ function set_template_read_only( isReadOnly ) {
111
+ codeMirrorHtml.setOption( "readOnly", isReadOnly );
112
+ codeMirrorCss.setOption( "readOnly", isReadOnly );
113
  }
admin/sidebar/partials/aalb_about.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  /*
4
  Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@@ -14,128 +14,158 @@ and limitations under the License.
14
 
15
  include 'aalb_admin_ui_common.php'; ?>
16
  <div class="wrap">
17
- <h2><?=AALB_PROJECT_TITLE?></h2>
18
- <div class="card" style="max-width:100%;">
19
- <h2>About Amazon Associates Program</h2>
20
- <p>
21
- The Amazon Associates Program is one of the original affiliate marketing programs. Available in geographies across the globe, the Amazon Associates Program has been partnering with content creators to help them monetize their passions since 1996. To learn more about the Amazon Associates Program, please click <a target="_blank" href="https://affiliate-program.amazon.com/">here</a>.
22
- </p>
23
- <h2>About Amazon Associates Link Builder </h2>
24
- <p>
25
- 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.
26
- </p>
27
- <b>Note</b>
28
- <ul>
29
- <li>
30
- You must review and accept the Amazon Associates Link Builder <a href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf" target="_blank">Conditions of Use</a>.
31
- </li>
32
- <li>
33
- The plugin is currently in beta form. We intend to regularly add new features and enhancements throughout the beta period and beyond, and welcome your feedback and input.
34
- </li>
35
- </ul>
36
- <h2>Getting Started</h2>
37
- <h3>Step 1 - Become an Associate</h3>
38
- <p>
39
- To become an Associate, create an Amazon Associates account using URL for your country:
40
- </p>
41
- <table border="0" cellpadding="10">
42
- <tr>
43
- <td><b>Brazil</b></td>
44
- <td>
45
- <a href="https://associados.amazon.com.br/" target="_blank">https://associados.amazon.com.br/</a>
46
- </td>
47
- </tr>
48
- <tr>
49
- <td><b>Canada</b></td>
50
- <td>
51
- <a href="https://associates.amazon.ca/" target="_blank">https://associates.amazon.ca/</a>
52
- </td>
53
- </tr>
54
- <tr>
55
- <td><b>China</b></td>
56
- <td>
57
- <a href="https://associates.amazon.cn/" target="_blank">https://associates.amazon.cn/</a>
58
- </td>
59
- </tr>
60
- <tr>
61
- <td><b>France</b></td>
62
- <td>
63
- <a href="http://partenaires.amazon.fr/" target="_blank">http://partenaires.amazon.fr/</a>
64
- </td>
65
- </tr>
66
- <tr>
67
- <td><b>Germany</b></td>
68
- <td>
69
- <a href="https://partnernet.amazon.de/" target="_blank">https://partnernet.amazon.de/</a>
70
- </td>
71
- </tr>
72
- <tr>
73
- <td><b>India</b></td>
74
- <td>
75
- <a href="http://affiliate-program.amazon.in/" target="_blank">http://affiliate-program.amazon.in/</a>
76
- </td>
77
- </tr>
78
- <tr>
79
- <td><b>Italy</b></td>
80
- <td>
81
- <a href="https://programma-affiliazione.amazon.it/" target="_blank">https://programma-affiliazione.amazon.it/</a>
82
- </td>
83
- </tr>
84
- <tr>
85
- <td><b>Japan</b></td>
86
- <td>
87
- <a href="https://affiliate.amazon.co.jp/" target="_blank">https://affiliate.amazon.co.jp/</a>
88
- </td>
89
- </tr>
90
- <tr>
91
- <td><b>Mexico</b></td>
92
- <td>
93
- <a href="https://afiliados.amazon.com.mx/" target="_blank">https://afiliados.amazon.com.mx/</a>
94
- </td>
95
- </tr>
96
- <tr>
97
- <td><b>Spain</b></td>
98
- <td>
99
- <a href="https://afiliados.amazon.es/" target="_blank">https://afiliados.amazon.es/</a>
100
- </td>
101
- </tr>
102
- <tr>
103
- <td><b>United Kingdom</b></td>
104
- <td>
105
- <a href="https://affiliate-program.amazon.co.uk/" target="_blank">https://affiliate-program.amazon.co.uk/</a>
106
- </td>
107
- </tr>
108
- <tr>
109
- <td><b>United States</b></td>
110
- <td>
111
- <a href="https://affiliate-program.amazon.com/" target="_blank">https://affiliate-program.amazon.com/</a>
112
- </td>
113
- </tr>
114
- </table>
115
- <p>
116
- Your Associate ID works only in the country in which you register. If you’d like to be an Associate in more than one country, please register separately for each country.
117
- </p>
118
- <h3>Step 2 - Sign up for the Amazon Product Advertising API</h3>
119
- <p>
120
- Sign up for the Amazon Product Advertising API by following the instructions listed <a target="_blank" href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html">here</a>. The Amazon Product Advertising API is a popular e-commerce service, powering Amazon-integrated experiences around the world, serving tens of thousands of applications and more than 1 billion API requests every day. It exposes a web-service, which allows Associates to programmatically search and look up items in the Amazon product catalog. The Link Builder plugin integrates the Product Advertising API, allowing you to access Amazon.com product catalog data without requiring additional software development.
121
- </p>
122
- <h3>Step 3 - Configure plugin for first use </h3>
123
- <p>
124
- Use the Associates Link Builder->Settings screen to configure the plugin.
125
- </p>
126
- <ol>
127
- <li>Set Access Key ID and Secret Access Key in the Settings section. These credentials are used to invoke requests to the Amazon Product Advertising API for fetching information on an item.</li>
128
- <li>Set default Associate ID. Associate ID is used to monitor traffic and sales from your links to Amazon. You can also define a list of valid Associate IDs (store ids or tracking ids). You should create a new tracking ID in your Amazon Associates account for using it as Associate ID in the plugin.</li>
129
- <li>Set the default Amazon marketplace based on the Amazon Associates Program for which you are registered (for example, if you’ve signed up for the Amazon Associates Program in UK, then your default marketplace selection should be UK) and select an appropriate template for rendering your ads.</li>
130
- </ol>
131
- <p>
132
- That's it! You’re all set to start adding Amazon affiliate links to your posts using the Amazon Associates Link Builder plugin!
133
- </p>
134
- <h2>User Guide</h2>
135
- <p>
136
- Review <a target="_blank" href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf">Link Builder User Guide</a> for more information on getting started and key features of the plugin.
137
- </p>
138
- <h2>Support</h2>
139
- <p>If you get stuck, or have any questions, you can ask for help in the <a href="https://wordpress.org/support/plugin/amazon-associates-link-builder" target="_blank">Amazon Associates Link Builder plugin forum</a>.</p>
140
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  </div>
1
+ <?php
2
 
3
  /*
4
  Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
14
 
15
  include 'aalb_admin_ui_common.php'; ?>
16
  <div class="wrap">
17
+ <h2><?= AALB_PROJECT_TITLE ?></h2>
18
+ <div class="card" style="max-width:100%;">
19
+ <h2>About Amazon Associates Program</h2>
20
+ <p>
21
+ The Amazon Associates Program is one of the original affiliate marketing programs. Available in geographies
22
+ across the globe, the Amazon Associates Program has been partnering with content creators to help them
23
+ monetize their passions since 1996. To learn more about the Amazon Associates Program, please click <a
24
+ target="_blank" href="https://affiliate-program.amazon.com/">here</a>.
25
+ </p>
26
+ <h2>About Amazon Associates Link Builder </h2>
27
+ <p>
28
+ Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to
29
+ search for products in the Amazon catalog, access real-time price and availability information, and easily
30
+ create links in your posts to products on Amazon.com. You will be able to generate text links, create custom
31
+ ad units, or take advantage of out-of-the-box widgets that we’ve designed and included with the plugin.
32
+ </p>
33
+ <b>Note</b>
34
+ <ul>
35
+ <li>
36
+ You must review and accept the Amazon Associates Link Builder <a
37
+ href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf"
38
+ target="_blank">Conditions of Use</a>.
39
+ </li>
40
+ <li>
41
+ The plugin is currently in beta form. We intend to regularly add new features and enhancements
42
+ throughout the beta period and beyond, and welcome your feedback and input.
43
+ </li>
44
+ </ul>
45
+ <h2>Getting Started</h2>
46
+ <h3>Step 1 - Become an Associate</h3>
47
+ <p>
48
+ To become an Associate, create an Amazon Associates account using URL for your country:
49
+ </p>
50
+ <table border="0" cellpadding="10">
51
+ <tr>
52
+ <td><b>Brazil</b></td>
53
+ <td>
54
+ <a href="https://associados.amazon.com.br/" target="_blank">https://associados.amazon.com.br/</a>
55
+ </td>
56
+ </tr>
57
+ <tr>
58
+ <td><b>Canada</b></td>
59
+ <td>
60
+ <a href="https://associates.amazon.ca/" target="_blank">https://associates.amazon.ca/</a>
61
+ </td>
62
+ </tr>
63
+ <tr>
64
+ <td><b>China</b></td>
65
+ <td>
66
+ <a href="https://associates.amazon.cn/" target="_blank">https://associates.amazon.cn/</a>
67
+ </td>
68
+ </tr>
69
+ <tr>
70
+ <td><b>France</b></td>
71
+ <td>
72
+ <a href="http://partenaires.amazon.fr/" target="_blank">http://partenaires.amazon.fr/</a>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td><b>Germany</b></td>
77
+ <td>
78
+ <a href="https://partnernet.amazon.de/" target="_blank">https://partnernet.amazon.de/</a>
79
+ </td>
80
+ </tr>
81
+ <tr>
82
+ <td><b>India</b></td>
83
+ <td>
84
+ <a href="http://affiliate-program.amazon.in/"
85
+ target="_blank">http://affiliate-program.amazon.in/</a>
86
+ </td>
87
+ </tr>
88
+ <tr>
89
+ <td><b>Italy</b></td>
90
+ <td>
91
+ <a href="https://programma-affiliazione.amazon.it/" target="_blank">https://programma-affiliazione.amazon.it/</a>
92
+ </td>
93
+ </tr>
94
+ <tr>
95
+ <td><b>Japan</b></td>
96
+ <td>
97
+ <a href="https://affiliate.amazon.co.jp/" target="_blank">https://affiliate.amazon.co.jp/</a>
98
+ </td>
99
+ </tr>
100
+ <tr>
101
+ <td><b>Mexico</b></td>
102
+ <td>
103
+ <a href="https://afiliados.amazon.com.mx/" target="_blank">https://afiliados.amazon.com.mx/</a>
104
+ </td>
105
+ </tr>
106
+ <tr>
107
+ <td><b>Spain</b></td>
108
+ <td>
109
+ <a href="https://afiliados.amazon.es/" target="_blank">https://afiliados.amazon.es/</a>
110
+ </td>
111
+ </tr>
112
+ <tr>
113
+ <td><b>United Kingdom</b></td>
114
+ <td>
115
+ <a href="https://affiliate-program.amazon.co.uk/" target="_blank">https://affiliate-program.amazon.co.uk/</a>
116
+ </td>
117
+ </tr>
118
+ <tr>
119
+ <td><b>United States</b></td>
120
+ <td>
121
+ <a href="https://affiliate-program.amazon.com/" target="_blank">https://affiliate-program.amazon.com/</a>
122
+ </td>
123
+ </tr>
124
+ </table>
125
+ <p>
126
+ Your Associate ID works only in the country in which you register. If you’d like to be an Associate in more
127
+ than one country, please register separately for each country.
128
+ </p>
129
+ <h3>Step 2 - Sign up for the Amazon Product Advertising API</h3>
130
+ <p>
131
+ Sign up for the Amazon Product Advertising API by following the instructions listed
132
+ <a target="_blank" href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html">here</a>.
133
+ The Amazon Product Advertising API is a popular e-commerce service, powering Amazon-integrated experiences
134
+ around the world, serving tens of thousands of applications and more than 1 billion API requests every day.
135
+ It exposes a web-service, which allows Associates to programmatically search and look up items in the Amazon
136
+ product catalog. The Link Builder plugin integrates the Product Advertising API, allowing you to access
137
+ Amazon.com product catalog data without requiring additional software development.
138
+ </p>
139
+ <h3>Step 3 - Configure plugin for first use </h3>
140
+ <p>
141
+ Use the Associates Link Builder->Settings screen to configure the plugin.
142
+ </p>
143
+ <ol>
144
+ <li>Set Access Key ID and Secret Access Key in the Settings section. These credentials are used to invoke
145
+ requests to the Amazon Product Advertising API for fetching information on an item.
146
+ </li>
147
+ <li>Set default Associate ID. Associate ID is used to monitor traffic and sales from your links to Amazon.
148
+ You can also define a list of valid Associate IDs (store ids or tracking ids). You should create a new
149
+ tracking ID in your Amazon Associates account for using it as Associate ID in the plugin.
150
+ </li>
151
+ <li>Set the default Amazon marketplace based on the Amazon Associates Program for which you are registered
152
+ (for example, if you’ve signed up for the Amazon Associates Program in UK, then your default marketplace
153
+ selection should be UK) and select an appropriate template for rendering your ads.
154
+ </li>
155
+ </ol>
156
+ <p>
157
+ That's it! You’re all set to start adding Amazon affiliate links to your posts using the Amazon Associates
158
+ Link Builder plugin!
159
+ </p>
160
+ <h2>User Guide</h2>
161
+ <p>
162
+ Review
163
+ <a target="_blank" href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf">Link
164
+ Builder User Guide</a> for more information on getting started and key features of the plugin.
165
+ </p>
166
+ <h2>Support</h2>
167
+ <p>If you get stuck, or have any questions, you can ask for help in the <a href="https://wordpress.org/support/plugin/amazon-associates-link-builder"
168
+ target="_blank">Amazon Associates Link Builder plugin forum</a>.
169
+ </p>
170
+ </div>
171
  </div>
admin/sidebar/partials/aalb_admin_ui_common.php CHANGED
@@ -16,16 +16,17 @@ and limitations under the License.
16
 
17
  include 'aalb_ui_common.php';
18
 
19
- if (!is_admin())
20
- die("Permission Denied");
21
-
22
- if (!is_ssl()) {
23
- //action when page is NOT using SSL
24
- if(!get_option(AALB_SHOW_HTTP_WARNING_ONCE)) {
25
- // This info message is showed only once.
26
- aalb_info_notice('We <b>recommend</b> using HTTPs connection for improved security.');
27
- update_option(AALB_SHOW_HTTP_WARNING_ONCE, true);
28
- }
 
29
  }
30
 
31
  ?>
16
 
17
  include 'aalb_ui_common.php';
18
 
19
+ if ( ! is_admin() ) {
20
+ die( "Permission Denied" );
21
+ }
22
+
23
+ if ( ! is_ssl() ) {
24
+ //action when page is NOT using SSL
25
+ if ( ! get_option( AALB_SHOW_HTTP_WARNING_ONCE ) ) {
26
+ // This info message is showed only once.
27
+ aalb_info_notice( 'We <b>recommend</b> using HTTPs connection for improved security.' );
28
+ update_option( AALB_SHOW_HTTP_WARNING_ONCE, true );
29
+ }
30
  }
31
 
32
  ?>
admin/sidebar/partials/aalb_credentials.php CHANGED
@@ -15,101 +15,134 @@ and limitations under the License.
15
  include 'aalb_admin_ui_common.php';
16
  $helper = new Aalb_Helper();
17
  $aalb_store_id_names = $helper->get_store_ids_array();
18
- wp_enqueue_script('jquery');
19
- wp_enqueue_script('aalb_credentials_js', AALB_CREDENTIALS_JS, array('jquery'));
20
- wp_localize_script('aalb_credentials_js', 'wp_opt', array('plugin_url' => AALB_PLUGIN_URL));
21
  ?>
22
 
23
  <div class="wrap">
24
- <h2>Settings for <?=AALB_PROJECT_TITLE?></h2>
25
- <br>
26
- <form method="post" action="options.php">
27
- <?php settings_fields(AALB_CRED_CONFIG_GROUP);do_settings_sections(AALB_CRED_CONFIG_GROUP);?>
28
- <table class="widefat fixed">
29
- <tr>
30
- <th scope="row" style="width:15%;">Access Key ID</th>
31
- <td style="vertical-align:middle;"><input type="text" name="aalb_aws_access_key" required style="width:90%" value="<?php echo esc_attr(openssl_decrypt(base64_decode(get_option(AALB_AWS_ACCESS_KEY)), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV)); ?>" /></td>
32
- <td>Your Access Key ID that you generated after signing up for the Amazon Product Advertising API. If you have not already signed up for the Amazon Product Advertising API, you can do so by following instructions listed <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html" target="_blank">here</a>.</td>
33
- </tr>
34
- <tr>
35
- <th scope="row" style="width:15%;">Secret Access Key</th>
36
- <?php $secret_key = get_option(AALB_AWS_SECRET_KEY);
37
- if($secret_key)
38
- $secret_key = AALB_AWS_SECRET_KEY_MASK;
39
- ?>
40
- <td style="vertical-align:middle;"><input type="password" name="aalb_aws_secret_key" required style="width:90%" value="<?php echo esc_attr($secret_key); ?>" autocomplete="off"/></td>
41
- <td>A key that is used in conjunction with the Access Key ID to cryptographically sign an API request. To retrieve your Access Key ID or Secret Access Key, go to <a href="https://affiliate-program.amazon.com/gp/advertising/api/detail/your-account.html" target="_blank">Manage Your Account</a>. The plugin uses a default encryption key for encrypting the Secret Key. You can change the key using AALB_ENCRYPTION_KEY parameter defined in /aalb_config.php.</td>
42
- </tr>
43
- <tr>
44
- <th scope="row" style="width:15%;">Associate ID</th>
45
- <td style="width:90%;vertical-align:middle;">
46
- <textarea type="text" id="aalb_store_id_names" name="aalb_store_id_names" style="width:90%" value="<?php echo esc_attr(get_option(AALB_STORE_ID_NAMES)); ?>" onchange="aalb_credentials_store_ids_onchange(this)"><?php echo esc_attr(get_option(AALB_STORE_ID_NAMES)); ?></textarea>
47
- </td>
48
- <td>Associate ID is used to monitor traffic and sales from your links to Amazon. You can add one store id or tracking id per row. You are recommended to create a new tracking ID in your Amazon Associates account for using it as Associate ID in the plugin.</td>
49
- </tr>
50
- <tr>
51
- <th scope="row" style="width:15%;">Default Associate ID</th>
52
- <td style="vertical-align:middle;">
53
- <?php $default_store_id=get_option(AALB_DEFAULT_STORE_ID,AALB_DEFAULT_STORE_ID_NAME);?>
54
- <select id="aalb_default_store_id" name="aalb_default_store_id" style="width:90%">
55
- <?php
56
- foreach ($aalb_store_id_names as $store_id) {
57
- echo '<option value="' . $store_id . '"';
58
- selected($default_store_id,$store_id);
59
- echo '>'. $store_id . '</option>\n';
60
- }
61
- ?>
62
- </select>
63
- </td>
64
- <td>The Associate ID that will be used for tagging the affiliate links generated by the plugin if no tag is specified in the short code.</td>
65
- </tr>
66
- <tr>
67
- <th scope="row" style="width:15%;">Default Marketplace</th>
68
- <td style="vertical-align:middle;">
69
- <?php $default_marketplace=get_option(AALB_DEFAULT_MARKETPLACE,AALB_DEFAULT_MARKETPLACE_NAME);?>
70
- <select name="aalb_default_marketplace" style="width:90%">
71
- <?php
72
- $config_loader = new Aalb_Config_Loader();
73
- $aalb_marketplace_names = $config_loader->fetch_marketplaces();
74
- foreach ($aalb_marketplace_names as $marketplace) {
75
- echo '<option value="' . $marketplace . '"';
76
- selected($default_marketplace,$marketplace);
77
- echo '>'. $marketplace . '</option>\n';
78
- }
79
- ?>
80
- </select>
81
- </td>
82
- <td>Set the default Amazon marketplace based on the Amazon website that is identified in your Associates Account (for instance, if you have signed up for Amazon.co.uk site, then your default marketplace selection should be UK).</td>
83
- </tr>
84
- <tr>
85
- <th scope="row" style="width:15%;">Default Template</th>
86
- <td style="vertical-align:middle;">
87
- <?php $default_template=get_option(AALB_DEFAULT_TEMPLATE,AALB_DEFAULT_TEMPLATE_NAME);?>
88
- <select name="aalb_default_template" style="width:90%">
89
- <?php
90
- $templates=get_option(AALB_TEMPLATE_NAMES,$default_template);
91
- foreach ($templates as $template) {
92
- echo '<option value="' . $template . '"';
93
- selected($default_template,$template);
94
- echo '>'. $template . '</option>\n';
95
- }
96
- ?>
97
- </select>
98
- </td>
99
- <td>The ad template that will be used for rendering the ad if no template is specified in the short code.</td>
100
- </tr>
101
- </table>
102
  <br>
103
- <table>
104
- <tr>
105
- <th scope="row" style="width:1%;">
106
- <input id="aalb-terms-checkbox" type="checkbox" name="demo-checkbox" value="1" />
107
- </th>
108
- <td style="vertical-align:middle;">
109
- Check here to indicate that you have read and agree to the Amazon Associates Link Builder <a href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf" target="_blank">Conditions of Use</a>.
110
- </td>
111
- </tr>
112
- </table>
113
- <?php submit_button('Save Changes', 'primary', 'submit', true, array( 'disabled' => 'disabled' )); ?>
114
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  </div>
15
  include 'aalb_admin_ui_common.php';
16
  $helper = new Aalb_Helper();
17
  $aalb_store_id_names = $helper->get_store_ids_array();
18
+ wp_enqueue_script( 'jquery' );
19
+ wp_enqueue_script( 'aalb_credentials_js', AALB_CREDENTIALS_JS, array( 'jquery' ) );
20
+ wp_localize_script( 'aalb_credentials_js', 'wp_opt', array( 'plugin_url' => AALB_PLUGIN_URL ) );
21
  ?>
22
 
23
  <div class="wrap">
24
+ <h2>Settings for <?= AALB_PROJECT_TITLE ?></h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  <br>
26
+ <form method="post" action="options.php">
27
+ <?php settings_fields( AALB_CRED_CONFIG_GROUP );
28
+ do_settings_sections( AALB_CRED_CONFIG_GROUP ); ?>
29
+ <table class="widefat fixed">
30
+ <tr>
31
+ <th scope="row" style="width:15%;">Access Key ID</th>
32
+ <td style="vertical-align:middle;">
33
+ <input type="text" name="aalb_aws_access_key" required style="width:90%"
34
+ value="<?php echo esc_attr( openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV ) ); ?>"/>
35
+ </td>
36
+ <td>Your Access Key ID that you generated after signing up for the Amazon Product Advertising API. If
37
+ you have not already signed up for the Amazon Product Advertising API, you can do so by following
38
+ instructions listed <a
39
+ href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html"
40
+ target="_blank">here</a>.
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <th scope="row" style="width:15%;">Secret Access Key</th>
45
+ <?php $secret_key = get_option( AALB_AWS_SECRET_KEY );
46
+ if ( $secret_key ) {
47
+ $secret_key = AALB_AWS_SECRET_KEY_MASK;
48
+ }
49
+ ?>
50
+ <td style="vertical-align:middle;"><input type="password" name="aalb_aws_secret_key" required
51
+ style="width:90%" value="<?php echo esc_attr( $secret_key ); ?>"
52
+ autocomplete="off"/></td>
53
+ <td>A key that is used in conjunction with the Access Key ID to cryptographically sign an API request.
54
+ To retrieve your Access Key ID or Secret Access Key, go to <a
55
+ href="https://affiliate-program.amazon.com/gp/advertising/api/detail/your-account.html"
56
+ target="_blank">Manage Your Account</a>. The plugin uses a default encryption key for
57
+ encrypting the Secret Key. You can change the key using AALB_ENCRYPTION_KEY parameter defined in
58
+ /aalb_config.php.
59
+ </td>
60
+ </tr>
61
+ <tr>
62
+ <th scope="row" style="width:15%;">Associate ID</th>
63
+ <td style="width:90%;vertical-align:middle;">
64
+ <textarea type="text" id="aalb_store_id_names" name="aalb_store_id_names" style="width:90%"
65
+ value="<?php echo esc_attr( get_option( AALB_STORE_ID_NAMES ) ); ?>"
66
+ onchange="aalb_credentials_store_ids_onchange(this)"><?php echo esc_attr( get_option( AALB_STORE_ID_NAMES ) ); ?>
67
+ </textarea>
68
+ </td>
69
+ <td>Associate ID is used to monitor traffic and sales from your links to Amazon. You can add one store
70
+ id or tracking id per row. You are recommended to create a new tracking ID in your Amazon Associates
71
+ account for using it as Associate ID in the plugin.
72
+ </td>
73
+ </tr>
74
+ <tr>
75
+ <th scope="row" style="width:15%;">Default Associate ID</th>
76
+ <td style="vertical-align:middle;">
77
+ <?php $default_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME ); ?>
78
+ <select id="aalb_default_store_id" name="aalb_default_store_id" style="width:90%">
79
+ <?php
80
+ foreach ( $aalb_store_id_names as $store_id ) {
81
+ echo '<option value="' . $store_id . '"';
82
+ selected( $default_store_id, $store_id );
83
+ echo '>' . $store_id . '</option>\n';
84
+ }
85
+ ?>
86
+ </select>
87
+ </td>
88
+ <td>The Associate ID that will be used for tagging the affiliate links generated by the plugin if no tag
89
+ is specified in the short code.
90
+ </td>
91
+ </tr>
92
+ <tr>
93
+ <th scope="row" style="width:15%;">Default Marketplace</th>
94
+ <td style="vertical-align:middle;">
95
+ <?php $default_marketplace = get_option( AALB_DEFAULT_MARKETPLACE, AALB_DEFAULT_MARKETPLACE_NAME ); ?>
96
+ <select name="aalb_default_marketplace" style="width:90%">
97
+ <?php
98
+ $config_loader = new Aalb_Config_Loader();
99
+ $aalb_marketplace_names = $config_loader->fetch_marketplaces();
100
+ foreach ( $aalb_marketplace_names as $marketplace ) {
101
+ echo '<option value="' . $marketplace . '"';
102
+ selected( $default_marketplace, $marketplace );
103
+ echo '>' . $marketplace . '</option>\n';
104
+ }
105
+ ?>
106
+ </select>
107
+ </td>
108
+ <td>Set the default Amazon marketplace based on the Amazon website that is identified in your Associates
109
+ Account (for instance, if you have signed up for Amazon.co.uk site, then your default marketplace
110
+ selection should be UK).
111
+ </td>
112
+ </tr>
113
+ <tr>
114
+ <th scope="row" style="width:15%;">Default Template</th>
115
+ <td style="vertical-align:middle;">
116
+ <?php $default_template = get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ); ?>
117
+ <select name="aalb_default_template" style="width:90%">
118
+ <?php
119
+ $templates = get_option( AALB_TEMPLATE_NAMES, $default_template );
120
+ foreach ( $templates as $template ) {
121
+ echo '<option value="' . $template . '"';
122
+ selected( $default_template, $template );
123
+ echo '>' . $template . '</option>\n';
124
+ }
125
+ ?>
126
+ </select>
127
+ </td>
128
+ <td>The ad template that will be used for rendering the ad if no template is specified in the short
129
+ code.
130
+ </td>
131
+ </tr>
132
+ </table>
133
+ <br>
134
+ <table>
135
+ <tr>
136
+ <th scope="row" style="width:1%;">
137
+ <input id="aalb-terms-checkbox" type="checkbox" name="demo-checkbox" value="1"/>
138
+ </th>
139
+ <td style="vertical-align:middle;">
140
+ Check here to indicate that you have read and agree to the Amazon Associates Link Builder <a
141
+ href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf"
142
+ target="_blank">Conditions of Use</a>.
143
+ </td>
144
+ </tr>
145
+ </table>
146
+ <?php submit_button( 'Save Changes', 'primary', 'submit', true, array( 'disabled' => 'disabled' ) ); ?>
147
+ </form>
148
  </div>
admin/sidebar/partials/aalb_templates.php CHANGED
@@ -19,217 +19,234 @@ $helper->aalb_initialize_wp_filesystem_api();
19
  /**
20
  * Verifies whether file exists and is writable
21
  *
22
- * @since 1.0.0
23
- * @param string $file Name of the file
24
- * @return bool TRUE if file exists and is writable or if it's a new file which, throws exception otherwise
 
 
25
  */
26
- function aalb_verify_file_is_writable($file) {
27
- if(is_file($file) and !is_writable($file))
28
- throw new Exception("Save Failed. The existing file " . $file . " is not writable.");
 
29
 
30
- return true;
31
  }
32
 
33
  /**
34
  * Writes content to a file
35
  *
36
- * @since 1.0.0
37
- * @param string $file Name of the file
38
- * @param string $content Content to be written
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;
47
  }
48
 
49
  /**
50
  * Saves new or updates existing template.
51
  * Writes template CSS and HTML into files.
52
  *
53
- * @since 1.0.0
54
- * @param string $file Name of the file without .extension
55
- * @param string $conntent_html HTML content to be saved
56
- * @param string $content_css CSS content to be saved
 
57
  */
58
- function aalb_save_template($file, $content_html, $content_css) {
59
- $file_mustache = $file . ".mustache";
60
- $file_css = $file. ".css";
61
- try{
62
- if((aalb_verify_file_is_writable($file_css) and aalb_verify_file_is_writable($file_mustache))) {
63
- //Both files are (existing and writable) or (a new file is specified)
64
- if(aalb_write_to_file($file_mustache, $content_html) and aalb_write_to_file($file_css, $content_css)) {
65
- //Both files were saved successfully
66
- //Else case never occurs as an exception is thrown in false case
67
- $saveFailed = false;
68
- aalb_success_notice("Template Saved Successfully");
69
- }
 
 
 
70
  }
71
- } catch(Exception $e) {
72
- throw new Exception($e->getMessage());
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)) {
116
- aalb_error_notice("Please define the template name for the new template");
117
- } elseif (!ctype_alnum(str_replace(array('-', '_'), '', $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)) {
126
- aalb_error_notice("Save Failed. A template with the name \"". $aalb_template_name . "\" already exists. Please specify some other name for the template");
127
- //Ensures state is saved even on save failures
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) {
135
- aalb_error_notice($e->getMessage());
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
- }
138
- }
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());
152
- }
153
- }
154
- } elseif ($_POST["submit"] == "Remove") {
155
- if ($_POST["aalb_template_list"] == "new") {
156
- aalb_error_notice("Cannot remove new template. Please select a valid template to remove.");
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 = "";
 
179
  }
180
- }
181
  }
182
 
183
- wp_enqueue_script('jquery');
184
- wp_enqueue_script('codemirror_js', CODEMIRROR_JS);
185
- wp_enqueue_script('codemirror_mode_xml_js', CODEMIRROR_MODE_XML_JS);
186
- wp_enqueue_script('codemirror_mode_css_js', CODEMIRROR_MODE_CSS_JS);
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">
194
- <h2>Templates for <?=AALB_PROJECT_TITLE?></h2>
195
- <br>
196
- <form method="post">
197
- <table class="widefat fixed">
198
- <tr>
199
- <th scope="row" style="width:15%;">Select Template</th>
200
- <td>
201
- <select id="aalb_template_list_select" name="aalb_template_list" style="width:50%" onchange="aalb_template_select_template_onchange(this)">
202
- <option value="new">Create new template</option>
203
- <?php
204
- foreach ($aalb_template_names as $aalb_template) {
205
- ?>
206
- <option value="<?=$aalb_template?>" <?php $saveFailed===false ? selected($aalb_template, (isset($aalb_template_name))?$aalb_template_name:'') : selected($aalb_template, "") ?>><?=$aalb_template?></option>
207
- <?php
208
- }
209
- ?>
210
- </select>
211
- <input type="button" name="clone" id="clone_template" class="button button-secondary" value="Clone" onclick="clone_existing_template()" disabled>
212
- </td>
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>
19
  /**
20
  * Verifies whether file exists and is writable
21
  *
22
+ * @since 1.0.0
23
+ *
24
+ * @param string $file Name of the file
25
+ *
26
+ * @return bool TRUE if file exists and is writable or if it's a new file which, throws exception otherwise
27
  */
28
+ function aalb_verify_file_is_writable( $file ) {
29
+ if ( is_file( $file ) and ! is_writable( $file ) ) {
30
+ throw new Exception( "Save Failed. The existing file " . $file . " is not writable." );
31
+ }
32
 
33
+ return true;
34
  }
35
 
36
  /**
37
  * Writes content to a file
38
  *
39
+ * @since 1.0.0
40
+ *
41
+ * @param string $file Name of the file
42
+ * @param string $content Content to be written
43
+ *
44
+ * @return bool TRUE if write was successful, throws exception otherwise
45
  */
46
+ function aalb_write_to_file( $file, $content ) {
47
+ global $wp_filesystem;
48
+ if ( $wp_filesystem->put_contents( $file, $content ) === false ) {
49
+ throw new Exception( "Save Failed. Error writing contents to file: " . $file );
50
+ }
51
 
52
+ return true;
53
  }
54
 
55
  /**
56
  * Saves new or updates existing template.
57
  * Writes template CSS and HTML into files.
58
  *
59
+ * @since 1.0.0
60
+ *
61
+ * @param string $file Name of the file without .extension
62
+ * @param string $content_html HTML content to be saved
63
+ * @param string $content_css CSS content to be saved
64
  */
65
+ function aalb_save_template( $file, $content_html, $content_css ) {
66
+ $file_mustache = $file . ".mustache";
67
+ $file_css = $file . ".css";
68
+ try {
69
+ if ( ( aalb_verify_file_is_writable( $file_css ) and aalb_verify_file_is_writable( $file_mustache ) ) ) {
70
+ //Both files are (existing and writable) or (a new file is specified)
71
+ if ( aalb_write_to_file( $file_mustache, $content_html ) and aalb_write_to_file( $file_css, $content_css ) ) {
72
+ //Both files were saved successfully
73
+ //Else case never occurs as an exception is thrown in false case
74
+ $saveFailed = false;
75
+ aalb_success_notice( "Template Saved Successfully" );
76
+ }
77
+ }
78
+ } catch ( Exception $e ) {
79
+ throw new Exception( $e->getMessage() );
80
  }
 
 
 
81
  }
82
 
83
  /**
84
  * Finds any change in the current list of templates.
85
  * Flags a note if either a template is added or removed.
86
  *
87
+ * @since 1.3
88
+ *
89
+ * @param array $aalb_current_template_names Current list of templates
90
+ * @param array $aalb_template_names Refreshed list of templates
91
  */
92
+ function aalb_find_template_change( $aalb_current_template_names, $aalb_template_names ) {
93
+ $templates_added = array_diff( $aalb_template_names, $aalb_current_template_names );
94
+ $templates_deleted = array_diff( $aalb_current_template_names, $aalb_template_names );
95
+ if ( sizeof( $templates_added ) > 0 ) {
96
+ aalb_info_notice( sizeof( $templates_added ) . " template(s) added: " . implode( ', ', $templates_added ) );
97
+ }
98
+ if ( sizeof( $templates_deleted ) > 0 ) {
99
+ aalb_info_notice( sizeof( $templates_deleted ) . " template(s) deleted: " . implode( ', ', $templates_deleted ) );
100
+ }
101
  }
102
 
103
  //Flag to check if the save is failed.
104
  $saveFailed = false;
105
+ $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
106
 
107
+ $aalb_current_template_names = get_option( AALB_TEMPLATE_NAMES );
108
 
109
  //Refresh templates
110
  $helper->refresh_template_list();
111
 
112
+ $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
113
+ aalb_find_template_change( $aalb_current_template_names, $aalb_template_names );
114
+
115
+ if ( ! empty( $_POST["submit"] ) ) {
116
+ $aalb_template_name = stripslashes( $_POST["aalb_template_name"] );
117
+ $aalb_template_template_html_box = stripslashes( $_POST["aalb_template_template_html_box"] );
118
+ $aalb_template_template_css_box = stripslashes( $_POST["aalb_template_template_css_box"] );
119
+ $dir = AALB_TEMPLATE_DIR;
120
+ $aalb_template_upload_dir = $helper->get_template_upload_directory();
121
+ if ( $_POST["submit"] == "Save" ) {
122
+ if ( $_POST["aalb_template_list"] == "new" ) {
123
+ if ( empty( $aalb_template_name ) ) {
124
+ aalb_error_notice( "Please define the template name for the new template" );
125
+ } elseif ( ! ctype_alnum( str_replace( array( '-', '_' ), '', $aalb_template_name ) ) ) {
126
+ //The template name can only be alphanumeric characters plus hyphens (-) and underscores (_)
127
+ aalb_error_notice( "Save Failed. Only alphanumeric characters allowed for template name." );
 
 
 
 
 
 
 
 
 
128
  } else {
129
+ if ( ! is_dir( $aalb_template_upload_dir ) or ! is_writable( $aalb_template_upload_dir ) ) {
130
+ 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/" );
131
+ } else {
132
+ //Check if template of that name already exists
133
+ if ( in_array( $aalb_template_name, $aalb_template_names ) ) {
134
+ aalb_error_notice( "Save Failed. A template with the name \"" . $aalb_template_name . "\" already exists. Please specify some other name for the template" );
135
+ //Ensures state is saved even on save failures
136
+ $saveFailed = true;
137
+ } else {
138
+ try {
139
+ aalb_save_template( $aalb_template_upload_dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
140
+ array_push( $aalb_template_names, $aalb_template_name );
141
+ update_option( 'aalb_template_names', $aalb_template_names );
142
+ } catch ( Exception $e ) {
143
+ aalb_error_notice( $e->getMessage() );
144
+ }
145
+ }
146
+ }
147
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  } else {
149
+ try {
150
+ if ( in_array( $aalb_template_name, $aalb_default_templates ) ) {
151
+ aalb_save_template( $dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
152
+ } else {
153
+ aalb_save_template( $aalb_template_upload_dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
154
+ }
155
+
156
+ //clears the cached rendered templates whenever the template is modified
157
+ $helper->clear_cache_for_template( $aalb_template_name );
158
+ } catch ( Exception $e ) {
159
+ aalb_error_notice( $e->getMessage() );
160
+ }
161
  }
162
+ } elseif ( $_POST["submit"] == "Remove" ) {
163
+ if ( $_POST["aalb_template_list"] == "new" ) {
164
+ aalb_error_notice( "Cannot remove new template. Please select a valid template to remove." );
165
  } else {
166
+ $aalb_template_names = array_diff( $aalb_template_names, array( $aalb_template_name ) );
167
+ update_option( 'aalb_template_names', $aalb_template_names );
168
+ if ( in_array( $aalb_template_name, $aalb_default_templates ) ) {
169
+ //If Default Amazon Template is Removed
170
+ aalb_error_notice( "Couldn't remove Default Template" );
171
+ } else {
172
+ if ( unlink( $aalb_template_upload_dir . $aalb_template_name . ".mustache" ) ) {
173
+ aalb_success_notice( "Successfully removed Template HTML" );
174
+ } else {
175
+ aalb_error_notice( "Couldn't remove Template HTML. Please manually remove " . $dir . $aalb_template_name . ".mustache" );
176
+ }
177
+ if ( unlink( $aalb_template_upload_dir . $aalb_template_name . ".css" ) ) {
178
+ aalb_success_notice( "Successfully removed Template CSS" );
179
+ } else {
180
+ aalb_error_notice( "Couldn't remove Template CSS. Please manually remove " . $dir . $aalb_template_name . ".css" );
181
+ }
182
+ }
183
 
184
+ $aalb_template_name = "";
185
+ $aalb_template_template_html_box = "";
186
+ $aalb_template_template_css_box = "";
187
+ }
188
  }
 
189
  }
190
 
191
+ wp_enqueue_script( 'jquery' );
192
+ wp_enqueue_script( 'codemirror_js', CODEMIRROR_JS );
193
+ wp_enqueue_script( 'codemirror_mode_xml_js', CODEMIRROR_MODE_XML_JS );
194
+ wp_enqueue_script( 'codemirror_mode_css_js', CODEMIRROR_MODE_CSS_JS );
195
+ wp_enqueue_style( 'codemirror_css', CODEMIRROR_CSS );
196
 
197
+ wp_enqueue_script( 'aalb_template_js', AALB_TEMPLATE_JS, array( 'jquery', 'codemirror_js', 'codemirror_mode_xml_js', 'codemirror_mode_css_js' ) );
198
+ 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 ) );
199
 
200
  ?>
201
  <div class="wrap">
202
+ <h2>Templates for <?= AALB_PROJECT_TITLE ?></h2>
203
+ <br>
204
+ <form method="post">
205
+ <table class="widefat fixed">
206
+ <tr>
207
+ <th scope="row" style="width:15%;">Select Template</th>
208
+ <td>
209
+ <select id="aalb_template_list_select" name="aalb_template_list" style="width:50%"
210
+ onchange="aalb_template_select_template_onchange(this)">
211
+ <option value="new">Create new template</option>
212
+ <?php
213
+ foreach ( $aalb_template_names as $aalb_template ) {
214
+ ?>
215
+ <option value="<?= $aalb_template ?>" <?php $saveFailed === false ? selected( $aalb_template, ( isset( $aalb_template_name ) ) ? $aalb_template_name : '' ) : selected( $aalb_template, "" ) ?>><?= $aalb_template ?></option>
216
+ <?php
217
+ }
218
+ ?>
219
+ </select>
220
+ <input type="button" name="clone" id="clone_template" class="button button-secondary" value="Clone"
221
+ onclick="clone_existing_template()" disabled>
222
+ </td>
223
+ </tr>
224
+ <tr>
225
+ <th scope="row" style="width:15%;">Set a name for your template</th>
226
+ <td>
227
+ <input type="text" id="aalb_template_name" name="aalb_template_name" style="width:50%"
228
+ value="<?= ( isset( $aalb_template_name ) ) ? $aalb_template_name : '' ?>"/>
229
+ <span style="font-size:0.9em;">[<a
230
+ href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToCreateCustomTemplates.pdf"
231
+ target="_blank">Guide for creating custom templates</a>]</span>
232
+ </td>
233
+ </tr>
234
+ <tr>
235
+ <th scope="row" style="width:15%;">Add HTML for your template</th>
236
+ <td><textarea id="aalb_template_template_html_box"
237
+ name="aalb_template_template_html_box"><?= ( isset( $aalb_template_template_html_box ) ) ? $aalb_template_template_html_box : '' ?></textarea>
238
+ </td>
239
+ </tr>
240
+ <tr>
241
+ <th scope="row" style="width:15%;">Add CSS for your template</th>
242
+ <td><textarea id="aalb_template_template_css_box"
243
+ name="aalb_template_template_css_box"><?= ( isset( $aalb_template_template_css_box ) ) ? $aalb_template_template_css_box : '' ?></textarea>
244
+ </td>
245
+ </tr>
246
+ </table>
247
+ <p class="submit">
248
+ <input name="submit" id="submit_save" class="button button-primary" value="Save" type="submit">
249
+ <input name="submit" id="submit_remove" class="button button-secondary" value="Remove" type="submit" disabled>
250
+ </p>
251
+ </form>
252
  </div>
admin/sidebar/partials/aalb_ui_common.php CHANGED
@@ -14,20 +14,20 @@ and limitations under the License.
14
 
15
  //some commonly used UI functionality
16
 
17
- function aalb_info_notice($message) {
18
- echo "<div class=\"notice notice-info is-dismissible\"><p>INFO - " . $message . "</p></div>";
19
  }
20
 
21
- function aalb_warning_notice($message) {
22
- echo "<div class=\"notice notice-warning\"><p>WARNING - " . $message . "</p></div>";
23
  }
24
 
25
- function aalb_error_notice($message) {
26
- echo "<div class=\"notice notice-error\"><p>ERROR - " . $message . "</p></div>";
27
  }
28
 
29
- function aalb_success_notice($message) {
30
- echo "<div class=\"notice notice-success is-dismissible\"><p>SUCCESS - " . $message . "</p></div>";
31
  }
32
 
33
  ?>
14
 
15
  //some commonly used UI functionality
16
 
17
+ function aalb_info_notice( $message ) {
18
+ echo "<div class=\"notice notice-info is-dismissible\"><p>INFO - " . $message . "</p></div>";
19
  }
20
 
21
+ function aalb_warning_notice( $message ) {
22
+ echo "<div class=\"notice notice-warning\"><p>WARNING - " . $message . "</p></div>";
23
  }
24
 
25
+ function aalb_error_notice( $message ) {
26
+ echo "<div class=\"notice notice-error\"><p>ERROR - " . $message . "</p></div>";
27
  }
28
 
29
+ function aalb_success_notice( $message ) {
30
+ echo "<div class=\"notice notice-success is-dismissible\"><p>SUCCESS - " . $message . "</p></div>";
31
  }
32
 
33
  ?>
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.4.1
11
  Author: Amazon Associates Program
12
  Author URI: https://affiliate-program.amazon.com/
13
  License: GPLv2
@@ -26,35 +26,35 @@ and limitations under the License.
26
  */
27
 
28
  if ( ! defined( 'WPINC' ) ) {
29
- die;
30
  }
31
 
32
- require_once( plugin_dir_path( __FILE__ ) . 'aalb_config.php');
33
 
34
- add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'add_action_links' );
35
- function add_action_links ( $links ) {
36
- $mylinks = array(
37
- '<a href="' . admin_url( 'admin.php?page=associates-link-builder-about' ) . '">About</a>',
38
- '<a href="' . admin_url( 'admin.php?page=associates-link-builder-settings' ) . '">Settings</a>',
39
- '<a href="' . admin_url( 'admin.php?page=associates-link-builder-templates' ) . '">Templates</a>',
 
40
 
41
- );
42
- return array_merge( $links, $mylinks );
43
  }
44
 
45
  /**
46
  * Autoload the files required for the plugin.
47
  *
48
- * @since 1.0.0
49
  */
50
  function aalb_autoload() {
51
- //Load the autoloader for mustache.
52
- require_once(MUSTACHE_AUTOLOADER_PHP);
53
- Mustache_Autoloader::register();
54
 
55
- //Load the autoloader for plugin files.
56
- require_once(AALB_AUTOLOADER);
57
- Aalb_Autoloader::register();
58
  }
59
 
60
  aalb_autoload();
@@ -62,13 +62,14 @@ aalb_autoload();
62
  /**
63
  * The code to run on activation
64
  *
65
- * @since 1.0.0
66
  */
67
  function aalb_activate() {
68
- $aalb_activator = new Aalb_Activator();
69
- $aalb_activator->load_templates();
70
- $aalb_activator->load_db_keys();
71
- $aalb_activator->load_store_ids();
 
72
  }
73
 
74
  register_activation_hook( __FILE__, 'aalb_activate' );
@@ -76,11 +77,11 @@ register_activation_hook( __FILE__, 'aalb_activate' );
76
  /**
77
  * The code to run on deactivation
78
  *
79
- * @since 1.0.0
80
  */
81
  function aalb_deactivate() {
82
- $aalb_deactivator = new Aalb_Deactivator();
83
- $aalb_deactivator->remove_cache();
84
  }
85
 
86
  register_deactivation_hook( __FILE__, 'aalb_deactivate' );
@@ -88,12 +89,12 @@ register_deactivation_hook( __FILE__, 'aalb_deactivate' );
88
  /**
89
  * The code to run on uninstalltion
90
  *
91
- * @since 1.0.0
92
  */
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' );
@@ -101,11 +102,11 @@ register_uninstall_hook( __FILE__, 'aalb_uninstall' );
101
  /**
102
  * Execute the plugin
103
  *
104
- * @since 1.0.0
105
  */
106
  function aalb_execute() {
107
- $aalb_manager = new Aalb_Manager();
108
- $aalb_manager->execute();
109
  }
110
 
111
  aalb_execute();
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.4.2
11
  Author: Amazon Associates Program
12
  Author URI: https://affiliate-program.amazon.com/
13
  License: GPLv2
26
  */
27
 
28
  if ( ! defined( 'WPINC' ) ) {
29
+ die;
30
  }
31
 
32
+ require_once( plugin_dir_path( __FILE__ ) . 'aalb_config.php' );
33
 
34
+ add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'add_action_links' );
35
+ function add_action_links( $links ) {
36
+ $mylinks = array(
37
+ '<a href="' . admin_url( 'admin.php?page=associates-link-builder-about' ) . '">About</a>',
38
+ '<a href="' . admin_url( 'admin.php?page=associates-link-builder-settings' ) . '">Settings</a>',
39
+ '<a href="' . admin_url( 'admin.php?page=associates-link-builder-templates' ) . '">Templates</a>',
40
+ );
41
 
42
+ return array_merge( $links, $mylinks );
 
43
  }
44
 
45
  /**
46
  * Autoload the files required for the plugin.
47
  *
48
+ * @since 1.0.0
49
  */
50
  function aalb_autoload() {
51
+ //Load the autoloader for mustache.
52
+ require_once( MUSTACHE_AUTOLOADER_PHP );
53
+ Mustache_Autoloader::register();
54
 
55
+ //Load the autoloader for plugin files.
56
+ require_once( AALB_AUTOLOADER );
57
+ Aalb_Autoloader::register();
58
  }
59
 
60
  aalb_autoload();
62
  /**
63
  * The code to run on activation
64
  *
65
+ * @since 1.0.0
66
  */
67
  function aalb_activate() {
68
+ $aalb_activator = new Aalb_Activator();
69
+ $aalb_activator->check_php_version_compatibility();
70
+ $aalb_activator->load_templates();
71
+ $aalb_activator->load_db_keys();
72
+ $aalb_activator->load_store_ids();
73
  }
74
 
75
  register_activation_hook( __FILE__, 'aalb_activate' );
77
  /**
78
  * The code to run on deactivation
79
  *
80
+ * @since 1.0.0
81
  */
82
  function aalb_deactivate() {
83
+ $aalb_deactivator = new Aalb_Deactivator();
84
+ $aalb_deactivator->remove_cache();
85
  }
86
 
87
  register_deactivation_hook( __FILE__, 'aalb_deactivate' );
89
  /**
90
  * The code to run on uninstalltion
91
  *
92
+ * @since 1.0.0
93
  */
94
  function aalb_uninstall() {
95
+ $aalb_deactivator = new Aalb_Deactivator();
96
+ $aalb_deactivator->remove_settings();
97
+ $aalb_deactivator->remove_uploads_dir();
98
  }
99
 
100
  register_uninstall_hook( __FILE__, 'aalb_uninstall' );
102
  /**
103
  * Execute the plugin
104
  *
105
+ * @since 1.0.0
106
  */
107
  function aalb_execute() {
108
+ $aalb_manager = new Aalb_Manager();
109
+ $aalb_manager->execute();
110
  }
111
 
112
  aalb_execute();
css/aalb_basics.css CHANGED
@@ -11,73 +11,73 @@ and limitations under the License.
11
  */
12
 
13
  .aalb-btn {
14
- padding: 6px 12px;
15
- padding-top: 6px;
16
- padding-right: 12px;
17
- padding-bottom: 6px;
18
- padding-left: 12px;
19
- margin-bottom: 0px;
20
- font-size: 14px;
21
- font-weight: normal;
22
- line-height: 1.42857;
23
- text-align: center;
24
- white-space: nowrap;
25
- vertical-align: middle;
26
- cursor: pointer;
27
- -moz-user-select: none;
28
- background-image: none;
29
- border: 1px solid transparent;
30
- border-top-width: 1px;
31
- border-right-width: 1px;
32
- border-bottom-width: 1px;
33
- border-left-width: 1px;
34
- border-top-style: solid;
35
- border-right-style: solid;
36
- border-bottom-style: solid;
37
- border-left-style: solid;
38
- border-top-color: transparent;
39
- border-right-color: transparent;
40
- border-bottom-color: transparent;
41
- border-left-color: transparent;
42
- -moz-border-top-color: none;
43
- -moz-border-right-color: none;
44
- -moz-border-bottom-color: none;
45
- -moz-border-left-color: none;
46
- border-image-source: none;
47
- border-image-slice: 100% 100% 100% 100%;
48
- border-image-width: 1 1 1 1;
49
- border-image-outset: 0 0 0 0;
50
- border-image-repeat: stretch stretch;
51
- border-radius: 4px;
52
- border-top-left-radius: 4px;
53
- border-top-right-radius: 4px;
54
- border-bottom-right-radius: 4px;
55
- border-bottom-left-radius: 4px;
56
  }
57
-
58
  .aalb-btn-primary {
59
- box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.4) inset;
60
- background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
61
- background-color: transparent;
62
- background-image: linear-gradient(to bottom, #F7DFA5, #F0C14B);
63
- background-repeat: repeat;
64
- background-attachment: scroll;
65
- background-position: 0% 0%;
66
- background-clip: border-box;
67
- background-origin: padding-box;
68
- background-size: auto auto;
69
- border-color: #A88734 #9C7E31 #846A29;
70
- border-top-color: #A88734;
71
- border-right-color: #9C7E31;
72
- border-bottom-color: #846A29;
73
- border-left-color: #9C7E31;
74
- color: #111;
75
  }
76
-
77
  .pull-right {
78
- float:right;
79
  }
80
-
81
  .pull-left {
82
- float:left;
83
  }
11
  */
12
 
13
  .aalb-btn {
14
+ padding: 6px 12px;
15
+ padding-top: 6px;
16
+ padding-right: 12px;
17
+ padding-bottom: 6px;
18
+ padding-left: 12px;
19
+ margin-bottom: 0px;
20
+ font-size: 14px;
21
+ font-weight: normal;
22
+ line-height: 1.42857;
23
+ text-align: center;
24
+ white-space: nowrap;
25
+ vertical-align: middle;
26
+ cursor: pointer;
27
+ -moz-user-select: none;
28
+ background-image: none;
29
+ border: 1px solid transparent;
30
+ border-top-width: 1px;
31
+ border-right-width: 1px;
32
+ border-bottom-width: 1px;
33
+ border-left-width: 1px;
34
+ border-top-style: solid;
35
+ border-right-style: solid;
36
+ border-bottom-style: solid;
37
+ border-left-style: solid;
38
+ border-top-color: transparent;
39
+ border-right-color: transparent;
40
+ border-bottom-color: transparent;
41
+ border-left-color: transparent;
42
+ -moz-border-top-color: none;
43
+ -moz-border-right-color: none;
44
+ -moz-border-bottom-color: none;
45
+ -moz-border-left-color: none;
46
+ border-image-source: none;
47
+ border-image-slice: 100% 100% 100% 100%;
48
+ border-image-width: 1 1 1 1;
49
+ border-image-outset: 0 0 0 0;
50
+ border-image-repeat: stretch stretch;
51
+ border-radius: 4px;
52
+ border-top-left-radius: 4px;
53
+ border-top-right-radius: 4px;
54
+ border-bottom-right-radius: 4px;
55
+ border-bottom-left-radius: 4px;
56
  }
57
+
58
  .aalb-btn-primary {
59
+ box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.4) inset;
60
+ background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
61
+ background-color: transparent;
62
+ background-image: linear-gradient(to bottom, #F7DFA5, #F0C14B);
63
+ background-repeat: repeat;
64
+ background-attachment: scroll;
65
+ background-position: 0% 0%;
66
+ background-clip: border-box;
67
+ background-origin: padding-box;
68
+ background-size: auto auto;
69
+ border-color: #A88734 #9C7E31 #846A29;
70
+ border-top-color: #A88734;
71
+ border-right-color: #9C7E31;
72
+ border-bottom-color: #846A29;
73
+ border-left-color: #9C7E31;
74
+ color: #111;
75
  }
76
+
77
  .pull-right {
78
+ float: right;
79
  }
80
+
81
  .pull-left {
82
+ float: left;
83
  }
includes/aalb_activator.php CHANGED
@@ -23,46 +23,60 @@ and limitations under the License.
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
- /**
42
- * Add the aws key options into the database on activation.
43
- * This solves the problem of encryption as wordpress called an update option before calling
44
- * add option while sanitizing.
45
- * https://codex.wordpress.org/Function_Reference/register_setting
46
- *
47
- * @since 1.0.0
48
- */
49
- public function load_db_keys() {
50
- if(!get_option(AALB_AWS_ACCESS_KEY)) {
51
- update_option(AALB_AWS_ACCESS_KEY, '');
 
 
 
 
52
  }
53
- if(!get_option(AALB_AWS_SECRET_KEY)) {
54
- update_option(AALB_AWS_SECRET_KEY, '');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
- }
57
 
58
- /**
59
- * Init store ids key and add todatabase.
60
- *
61
- * @since 1.0.0
62
- */
63
- public function load_store_ids() {
64
- update_option(AALB_STORE_IDS, '');
65
- }
66
  }
67
 
68
  ?>
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
+ /**
42
+ * Add the aws key options into the database on activation.
43
+ * This solves the problem of encryption as wordpress called an update option before calling
44
+ * add option while sanitizing.
45
+ * https://codex.wordpress.org/Function_Reference/register_setting
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function load_db_keys() {
50
+ if ( ! get_option( AALB_AWS_ACCESS_KEY ) ) {
51
+ update_option( AALB_AWS_ACCESS_KEY, '' );
52
+ }
53
+ if ( ! get_option( AALB_AWS_SECRET_KEY ) ) {
54
+ update_option( AALB_AWS_SECRET_KEY, '' );
55
+ }
56
  }
57
+
58
+ /**
59
+ * Init store ids key and add todatabase.
60
+ *
61
+ * @since 1.0.0
62
+ */
63
+ public function load_store_ids() {
64
+ update_option( AALB_STORE_IDS, '' );
65
+ }
66
+
67
+ /**
68
+ * Checks current PHP version of user and exits with error message
69
+ * in case user's phpVersion is less than AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION
70
+ *
71
+ * @since 1.4.2
72
+ */
73
+ public function check_php_version_compatibility() {
74
+ $phpversion = phpversion();
75
+ if(version_compare($phpversion, AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION) < 0) {
76
+ exit(sprintf('<span style="color:red;">%s plugin requires %s or higher. You’re still on %s.</span>', AALB_PLUGIN_NAME, AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION, $phpversion));
77
+ }
78
  }
 
79
 
 
 
 
 
 
 
 
 
80
  }
81
 
82
  ?>
includes/aalb_autoloader.php CHANGED
@@ -23,47 +23,50 @@ and limitations under the License.
23
  */
24
  class Aalb_Autoloader {
25
 
26
- private $dir;
27
 
28
- /**
29
- * Register the autoloader for a directory in the plugin.
30
- *
31
- * @since 1.0.0
32
- * @param string $dir Path of the directory.
33
- */
34
- public function __construct($dir = '') {
35
- if(!empty($dir)) {
36
- $this->dir = $dir;
37
- }
 
38
 
39
- spl_autoload_register(array($this, 'autoload'));
40
- }
41
 
42
- /**
43
- * Make instances of the autoloaders for each directory in the plugin.
44
- *
45
- * @since 1.0.0
46
- */
47
- public static function register() {
48
- new self(AALB_INCLUDES_DIR);
49
- new self(AALB_ADMIN_DIR);
50
- new self(AALB_SIDEBAR_DIR);
51
- new self(AALB_PAAPI_DIR);
52
- new self(AALB_SHORTCODE_DIR);
53
- new self(AALB_LIBRARY_DIR);
54
- }
55
 
56
- /**
57
- * Callback function of spl_autoload_register to autoload the class.
58
- *
59
- * @since 1.0.0
60
- * @param string $class Name of the class to autoload.
61
- */
62
- public function autoload($class) {
63
- $path = $this->dir . strtolower($class) . '.php';
64
- if(file_exists($path)) {
65
- require_once($path);
66
- }
67
- }
 
68
  }
 
69
  ?>
23
  */
24
  class Aalb_Autoloader {
25
 
26
+ private $dir;
27
 
28
+ /**
29
+ * Register the autoloader for a directory in the plugin.
30
+ *
31
+ * @since 1.0.0
32
+ *
33
+ * @param string $dir Path of the directory.
34
+ */
35
+ public function __construct( $dir = '' ) {
36
+ if ( ! empty( $dir ) ) {
37
+ $this->dir = $dir;
38
+ }
39
 
40
+ spl_autoload_register( array( $this, 'autoload' ) );
41
+ }
42
 
43
+ /**
44
+ * Make instances of the autoloaders for each directory in the plugin.
45
+ *
46
+ * @since 1.0.0
47
+ */
48
+ public static function register() {
49
+ new self( AALB_INCLUDES_DIR );
50
+ new self( AALB_ADMIN_DIR );
51
+ new self( AALB_SIDEBAR_DIR );
52
+ new self( AALB_PAAPI_DIR );
53
+ new self( AALB_SHORTCODE_DIR );
54
+ new self( AALB_LIBRARY_DIR );
55
+ }
56
 
57
+ /**
58
+ * Callback function of spl_autoload_register to autoload the class.
59
+ *
60
+ * @since 1.0.0
61
+ *
62
+ * @param string $class Name of the class to autoload.
63
+ */
64
+ public function autoload( $class ) {
65
+ $path = $this->dir . strtolower( $class ) . '.php';
66
+ if ( file_exists( $path ) ) {
67
+ require_once( $path );
68
+ }
69
+ }
70
  }
71
+
72
  ?>
includes/aalb_cache_loader.php CHANGED
@@ -24,62 +24,65 @@ and limitations under the License.
24
  */
25
  class Aalb_Cache_Loader {
26
 
27
- public $loader;
28
- protected $helper;
29
 
30
- public function __construct($loader) {
31
- $this->loader = $loader;
32
- $this->helper = new Aalb_Helper();
33
- }
34
 
35
- /**
36
- * If the information is in the cache, then retrieve the information from the cache.
37
- * Else get the information by making a GET request.
38
- *
39
- * @param string $key Unique identification of the information.
40
- * @param string $url URL for making a request.
41
- * @return string GET Response.
42
- */
43
- public function load($key, $url) {
44
- $info = $this->lookup($key);
45
- if($info !== false){
46
- return $info;
47
- } else {
48
- return $this->load_and_save($key,$url);
 
 
49
  }
50
- }
51
 
52
- /**
53
- * Lookup in the cache for a particular key.
54
- * If the key exists in the cache, the data is return.
55
- * Else false is returned.
56
- *
57
- * @param string $key Unique identification of the information.
58
- * @return string Data in the cache.
59
- */
60
- private function lookup($key) {
61
- return get_transient($key);
62
- }
 
63
 
64
- /**
65
- * Load the information with a GET request and save it in the cache. Return the loaded information.
66
- *
67
- * @param string $key Unique identification of the information.
68
- * @param string $url URL for making a request.
69
- * @return string GET Response.
70
- */
71
- private function load_and_save($key, $url) {
72
- $info = $this->loader->load($url);
 
73
 
74
- //use wordpress linkcode
75
- $info = str_replace('linkCode%3Dxm2', 'linkCode%3Dalb', $info);
76
- $info = str_replace('linkCode=xm2', 'linkCode=alb', $info);
77
 
78
- $this->helper->clear_expired_transients_at_intervals();
79
- set_transient($key, $info, AALB_CACHE_FOR_ASIN_RAWINFO_TTL);
80
 
81
- return $info;
82
- }
83
  }
84
 
85
  ?>
24
  */
25
  class Aalb_Cache_Loader {
26
 
27
+ public $loader;
28
+ protected $helper;
29
 
30
+ public function __construct( $loader ) {
31
+ $this->loader = $loader;
32
+ $this->helper = new Aalb_Helper();
33
+ }
34
 
35
+ /**
36
+ * If the information is in the cache, then retrieve the information from the cache.
37
+ * Else get the information by making a GET request.
38
+ *
39
+ * @param string $key Unique identification of the information.
40
+ * @param string $url URL for making a request.
41
+ *
42
+ * @return string GET Response.
43
+ */
44
+ public function load( $key, $url ) {
45
+ $info = $this->lookup( $key );
46
+ if ( $info !== false ) {
47
+ return $info;
48
+ } else {
49
+ return $this->load_and_save( $key, $url );
50
+ }
51
  }
 
52
 
53
+ /**
54
+ * Lookup in the cache for a particular key.
55
+ * If the key exists in the cache, the data is return.
56
+ * Else false is returned.
57
+ *
58
+ * @param string $key Unique identification of the information.
59
+ *
60
+ * @return string Data in the cache.
61
+ */
62
+ private function lookup( $key ) {
63
+ return get_transient( $key );
64
+ }
65
 
66
+ /**
67
+ * Load the information with a GET request and save it in the cache. Return the loaded information.
68
+ *
69
+ * @param string $key Unique identification of the information.
70
+ * @param string $url URL for making a request.
71
+ *
72
+ * @return string GET Response.
73
+ */
74
+ private function load_and_save( $key, $url ) {
75
+ $info = $this->loader->load( $url );
76
 
77
+ //use wordpress linkcode
78
+ $info = str_replace( 'linkCode%3Dxm2', 'linkCode%3Dalb', $info );
79
+ $info = str_replace( 'linkCode=xm2', 'linkCode=alb', $info );
80
 
81
+ $this->helper->clear_expired_transients_at_intervals();
82
+ set_transient( $key, $info, AALB_CACHE_FOR_ASIN_RAWINFO_TTL );
83
 
84
+ return $info;
85
+ }
86
  }
87
 
88
  ?>
includes/aalb_cache_template_loader.php CHANGED
@@ -23,27 +23,30 @@ and limitations under the License.
23
  */
24
  class Aalb_Cache_Template_Loader {
25
 
26
- /**
27
- * Get the html of the display unit from the cache
28
- *
29
- * @since 1.0.0
30
- * @param string $key Unique Key for the display unit in cache.
31
- * @return string HTML of the display unit.
32
- */
33
- public function get_display_unit($key) {
34
- return get_transient($key);
35
- }
36
-
37
- /**
38
- * Get the product information.
39
- *
40
- * @since 1.0.0
41
- * @param string $key Unique identification of the product.
42
- * @param string $display_unit HTML of the display unit to save in the cache.
43
- */
44
- public function save_display_unit($key, $display_unit) {
45
- set_transient($key, $display_unit, AALB_CACHE_FOR_ASIN_ADUNIT_TTL);
46
- }
 
 
 
47
 
48
  }
49
 
23
  */
24
  class Aalb_Cache_Template_Loader {
25
 
26
+ /**
27
+ * Get the html of the display unit from the cache
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param string $key Unique Key for the display unit in cache.
32
+ *
33
+ * @return string HTML of the display unit.
34
+ */
35
+ public function get_display_unit( $key ) {
36
+ return get_transient( $key );
37
+ }
38
+
39
+ /**
40
+ * Get the product information.
41
+ *
42
+ * @since 1.0.0
43
+ *
44
+ * @param string $key Unique identification of the product.
45
+ * @param string $display_unit HTML of the display unit to save in the cache.
46
+ */
47
+ public function save_display_unit( $key, $display_unit ) {
48
+ set_transient( $key, $display_unit, AALB_CACHE_FOR_ASIN_ADUNIT_TTL );
49
+ }
50
 
51
  }
52
 
includes/aalb_config_loader.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  /*
4
  Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@@ -13,7 +13,7 @@ and limitations under the License.
13
  */
14
 
15
  /**
16
- * The class reponsible for getting all the configuration
17
  *
18
  * Loads the class with respect to their respective directories.
19
  *
@@ -22,51 +22,56 @@ and limitations under the License.
22
  * @subpackage AmazonAssociatesLinkBuilder/includes
23
  */
24
  class Aalb_Config_Loader {
25
-
26
- private $cache_loader;
27
 
28
- public function __construct() {
29
- $this->cache_loader = new Aalb_Cache_Loader(new Aalb_Remote_Loader());
30
- }
31
 
32
- /**
33
- * Updating marketplaces from the external config file and storing it in the database.
34
- *
35
- * If some error occurs while fetching from external source, the error message
36
- * will be logged and marketplace endpoints would be retrieved from database.
37
- *
38
- * @since 1.0.0
39
- */
40
- public function fetch_marketplaces() {
41
- try{
42
- $body = $this->cache_loader->load(AALB_MARKETPLACE_NAMES, MARKETPLACES_URL);
43
- return $this->parse_json($body);
44
- } catch(Exception $e) {
45
- error_log($e->getMessage());
46
- return get_option(AALB_MARKETPLACE_NAMES);
47
  }
48
- }
49
 
50
- /**
51
- * Parse the json file and extract the marketplace endpoints
52
- *
53
- * @since 1.0.0
54
- * @param string $json_body Json retrieved from the server to parse.
55
- * @return array Mapping of marketplace endpoint and its abbreviation.
56
- */
57
- private function parse_json($json_body) {
58
- $body = json_decode($json_body,true);
59
- if(json_last_error() !== JSON_ERROR_NONE) {
60
- throw new Exception('Invalid Json returned by server' . json_last_error());
61
- }
62
- $marketplaces_info = $body['Local']['Marketplace'];
63
- $updated_marketplace = array();
64
- foreach ($marketplaces_info as $key => $value) {
65
- $updated_marketplace[substr($value['Endpoint'],0,strpos($value['Endpoint'],'/'))] = $key;
 
 
66
  }
67
- update_option(AALB_MARKETPLACE_NAMES, $updated_marketplace);
68
 
69
- return $updated_marketplace;
70
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
 
72
  ?>
1
+ <?php
2
 
3
  /*
4
  Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
13
  */
14
 
15
  /**
16
+ * The class responsible for getting all the configuration
17
  *
18
  * Loads the class with respect to their respective directories.
19
  *
22
  * @subpackage AmazonAssociatesLinkBuilder/includes
23
  */
24
  class Aalb_Config_Loader {
 
 
25
 
26
+ private $cache_loader;
 
 
27
 
28
+ public function __construct() {
29
+ $this->cache_loader = new Aalb_Cache_Loader( new Aalb_Remote_Loader() );
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  }
 
31
 
32
+ /**
33
+ * Updating marketplaces from the external config file and storing it in the database.
34
+ *
35
+ * If some error occurs while fetching from external source, the error message
36
+ * will be logged and marketplace endpoints would be retrieved from database.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ public function fetch_marketplaces() {
41
+ try {
42
+ $body = $this->cache_loader->load( AALB_MARKETPLACE_NAMES, MARKETPLACES_URL );
43
+
44
+ return $this->parse_json( $body );
45
+ } catch ( Exception $e ) {
46
+ error_log( $e->getMessage() );
47
+
48
+ return get_option( AALB_MARKETPLACE_NAMES );
49
+ }
50
  }
 
51
 
52
+ /**
53
+ * Parse the json file and extract the marketplace endpoints
54
+ *
55
+ * @since 1.0.0
56
+ *
57
+ * @param string $json_body Json retrieved from the server to parse.
58
+ *
59
+ * @return array Mapping of marketplace endpoint and its abbreviation.
60
+ */
61
+ private function parse_json( $json_body ) {
62
+ $body = json_decode( $json_body, true );
63
+ if ( json_last_error() !== JSON_ERROR_NONE ) {
64
+ throw new Exception( 'Invalid Json returned by server' . json_last_error() );
65
+ }
66
+ $marketplaces_info = $body['Local']['Marketplace'];
67
+ $updated_marketplace = array();
68
+ foreach ( $marketplaces_info as $key => $value ) {
69
+ $updated_marketplace[ substr( $value['Endpoint'], 0, strpos( $value['Endpoint'], '/' ) ) ] = $key;
70
+ }
71
+ update_option( AALB_MARKETPLACE_NAMES, $updated_marketplace );
72
+
73
+ return $updated_marketplace;
74
+ }
75
  }
76
+
77
  ?>
includes/aalb_deactivator.php CHANGED
@@ -21,52 +21,52 @@ and limitations under the License.
21
  */
22
  class Aalb_Deactivator {
23
 
24
- protected $helper;
25
 
26
- public function __construct() {
27
- $this->helper = new Aalb_Helper();
28
- }
29
-
30
- /**
31
- * Remove the settings stored by the admin in the database
32
- *
33
- * @since 1.0.0
34
- */
35
- public function remove_settings() {
36
- global $wpdb;
37
- $table_prefix = $wpdb->prefix;
38
- $statement = 'DELETE from ' . $table_prefix . 'options
39
- WHERE option_name like %s';
40
- $settings = "aalb%";
41
- $prepared_statement = $wpdb->prepare($statement, $settings);
42
 
43
- try {
44
- $wpdb->query($prepared_statement);
45
- } catch(Exception $e) {
46
- error_log('Unable to clear settings. Query failed with the Exception ' . $e->getMessage());
 
47
  }
48
- }
49
 
50
- /**
51
- * Remove the cache stored in the database.
52
- *
53
- * @since 1.0.0
54
- */
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
  ?>
21
  */
22
  class Aalb_Deactivator {
23
 
24
+ protected $helper;
25
 
26
+ public function __construct() {
27
+ $this->helper = new Aalb_Helper();
28
+ }
29
+
30
+ /**
31
+ * Remove the settings stored by the admin in the database
32
+ *
33
+ * @since 1.0.0
34
+ */
35
+ public function remove_settings() {
36
+ global $wpdb;
37
+ $table_prefix = $wpdb->prefix;
38
+ $statement = 'DELETE from ' . $table_prefix . 'options
39
+ WHERE option_name like %s';
40
+ $settings = "aalb%";
41
+ $prepared_statement = $wpdb->prepare( $statement, $settings );
42
 
43
+ try {
44
+ $wpdb->query( $prepared_statement );
45
+ } catch ( Exception $e ) {
46
+ error_log( 'Unable to clear settings. Query failed with the Exception ' . $e->getMessage() );
47
+ }
48
  }
 
49
 
50
+ /**
51
+ * Remove the cache stored in the database.
52
+ *
53
+ * @since 1.0.0
54
+ */
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
@@ -19,265 +19,279 @@ and limitations under the License.
19
  * @package AmazonAssociatesLinkBuilder
20
  * @subpackage AmazonAssociatesLinkBuilder/includes
21
  */
22
- class Aalb_Helper{
23
 
24
- /**
25
- * Build key for storing rendered template in cache.
26
- *
27
- * @since 1.0.0
28
- * @param string $asins List of hyphen separated asins.
29
- * @param string $marketplace Marketplace of the asin to look into.
30
- * @param string $store The identifier of the store to be used for current adunit
31
- * @param string $template Template to render the display unit.
32
- * @return string Template cache key.
33
- */
34
- public function build_template_cache_key($asins, $marketplace, $store, $template) {
35
- return 'aalb' . '-' . $asins . '-' . $marketplace . '-' . $store . '-' . $template;
36
- }
 
 
37
 
38
- /**
39
- * Build key for storing product information in cache.
40
- *
41
- * @since 1.0.0
42
- * @param string $asins List of hyphen separated asins.
43
- * @param string $marketplace Marketplace of the asin to look into.
44
- * @param string $store The identifier of the store to be used for current adunit
45
- * @return string Products information cache key.
46
- */
47
- public function build_products_cache_key($asins, $marketplace, $store) {
48
- return 'aalb' . '-' . $asins . '-' . $marketplace . '-' . $store;
49
- }
 
 
50
 
51
- /**
52
- * Clears the cache for the given template name
53
- *
54
- * @since 1.0.0
55
- * @param string $template The template to clear the cache for
56
- */
57
- public function clear_cache_for_template($template) {
58
- $this->clear_cache_for_substring($template);
59
- }
 
60
 
61
- /**
62
- * Clear the cache for keys which contain the given substring
63
- *
64
- * @since 1.0.0
65
- * @param string $substring The subtring which is a part of the keys to be cleared
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 . '%';
74
- $prepared_statement = $wpdb->prepare($statement, $transient_timeout_cache, $transient_cache);
75
 
76
- try {
77
- $wpdb->query($prepared_statement);
78
- } catch(Exception $e) {
79
- error_log('Unable to clear cache. Query to clear cache for substring ' . $substring . ' failed with the Exception ' . $e->getMessage());
 
80
  }
81
- }
82
 
83
- /**
84
- * Clear the dead expired transients from cache at intervals
85
- *
86
- * @since 1.0.0
87
- */
88
- public function clear_expired_transients_at_intervals() {
89
- $randomNumber = rand(1,50);
90
- // Clear the expired transients approximately once in 50 requests.
91
- if($randomNumber == 25) {
92
- $this->clear_expired_transients();
 
93
  }
94
- }
95
 
96
- /**
97
- * Clear the dead expired transients from cache
98
- *
99
- * @since 1.0.0
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
112
- );
113
- $transients = $wpdb -> get_col( $sql );
114
- foreach( $transients as $transient ) {
115
- // Strip away the WordPress prefix in order to arrive at the transient key.
116
- $key = str_replace( '_transient_timeout_', '', $transient );
117
- delete_transient($key);
118
  }
119
- wp_cache_flush();
120
- }
121
 
122
- /**
123
- * Displays error messages in preview mode only
124
- *
125
- * @since 1.0.0
126
- * @param string $error_message Error message to be displayed
127
- */
128
- public function show_error_in_preview($error_message) {
129
- if (is_preview()) {
130
- //If it's preview mode
131
- echo "<br><font color='red'><b>" . $error_message . "</b></font>";
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
133
- }
134
 
135
- /**
136
- * Returns the Store IDs Array.
137
- * Returns AALB_DEFAULT_STORE_ID_NAME if the nothing is specified.
138
- *
139
- * @since 1.0.0
140
- */
141
- public function get_store_ids_array(){
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
- *
148
- * @since 1.0.0
149
- * @return string Version number of Wordpress
150
- */
151
- function get_wordpress_version() {
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'] ) . AALB_TEMPLATE_UPLOADS_FOLDER;
200
- }
 
201
 
202
- /**
203
- * Gets the template uploads dir URL.
204
- *
205
- * @since 1.3.2
206
- * @return full URL of the template uploads directory
207
- */
208
- public function get_template_upload_directory_url() {
209
- $upload_dir = wp_upload_dir();
210
- return $upload_dir['baseurl'] . '/' . AALB_TEMPLATE_UPLOADS_FOLDER;
211
- }
212
 
213
- /**
214
- * Loads necessary files and initializes WP Filesystem API
215
- *
216
- * @since 1.3
217
- */
218
- public function aalb_initialize_wp_filesystem_api() {
219
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
220
- WP_Filesystem();
221
- }
 
 
 
 
 
 
 
222
 
223
- /**
224
- * Gets the extension of the file
225
- *
226
- * @since 1.0
227
- * @param string $file_name Name of the file
228
- * @return string Extension of the file
229
- */
230
- public function aalb_get_file_extension($file_name) {
231
- return substr(strrchr($file_name,'.'),1);
232
- }
233
 
234
- /**
235
- * Gets the name of the file without the extension
236
- *
237
- * @since 1.0
238
- * @param string $file_name Name of the file
239
- * @return string Name of the file without the extension
240
- */
241
- function aalb_get_file_name($file_name) {
242
- return substr($file_name, 0, strlen($file_name) - strlen(strrchr($file_name,'.')));
243
- }
244
 
245
- /**
246
- * Reads both the templates/ and the uploads/ directory and updates the template list.
247
- * Helper to replicate the current status of the default and custom templates
248
- *
249
- * @since 1.3
250
- */
251
- public function refresh_template_list() {
252
- global $wp_filesystem;
253
- $this->aalb_initialize_wp_filesystem_api();
254
 
255
- $aalb_templates = array();
256
- $upload_dir = $this->get_template_upload_directory();
 
 
 
 
 
 
 
 
257
 
258
- //Read and update templates from the plugin's template/ directory (Default Templates)
259
- if ($handle = opendir(AALB_TEMPLATE_DIR)) {
260
- while (false !== ($entry = readdir($handle))) {
261
- $file_name = $this->aalb_get_file_name($entry);
262
- $file_extension = $this->aalb_get_file_extension($entry);
263
- if ($file_extension == "css" and file_exists(AALB_TEMPLATE_DIR . $file_name . '.mustache')) {
264
- $aalb_templates[] = $file_name;
265
  }
266
- }
267
- closedir($handle);
268
  }
269
 
270
- //Read and update templates from the uploads/ directory (Custom Templates)
271
- if ($handle = opendir($upload_dir)) {
272
- while (false !== ($entry = readdir($handle))) {
273
- $file_name = $this->aalb_get_file_name($entry);
274
- $file_extension = $this->aalb_get_file_extension($entry);
275
- if ($file_extension == "css" and file_exists($upload_dir . $file_name . '.mustache')) {
276
- $aalb_templates[] = $file_name;
277
- }
278
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  }
280
- update_option(AALB_TEMPLATE_NAMES, $aalb_templates);
281
- }
282
  }
 
283
  ?>
19
  * @package AmazonAssociatesLinkBuilder
20
  * @subpackage AmazonAssociatesLinkBuilder/includes
21
  */
22
+ class Aalb_Helper {
23
 
24
+ /**
25
+ * Build key for storing rendered template in cache.
26
+ *
27
+ * @since 1.0.0
28
+ *
29
+ * @param string $asins List of hyphen separated asins.
30
+ * @param string $marketplace Marketplace of the asin to look into.
31
+ * @param string $store The identifier of the store to be used for current adunit
32
+ * @param string $template Template to render the display unit.
33
+ *
34
+ * @return string Template cache key.
35
+ */
36
+ public function build_template_cache_key( $asins, $marketplace, $store, $template ) {
37
+ return 'aalb' . '-' . $asins . '-' . $marketplace . '-' . $store . '-' . $template;
38
+ }
39
 
40
+ /**
41
+ * Build key for storing product information in cache.
42
+ *
43
+ * @since 1.0.0
44
+ *
45
+ * @param string $asins List of hyphen separated asins.
46
+ * @param string $marketplace Marketplace of the asin to look into.
47
+ * @param string $store The identifier of the store to be used for current adunit
48
+ *
49
+ * @return string Products information cache key.
50
+ */
51
+ public function build_products_cache_key( $asins, $marketplace, $store ) {
52
+ return 'aalb' . '-' . $asins . '-' . $marketplace . '-' . $store;
53
+ }
54
 
55
+ /**
56
+ * Clears the cache for the given template name
57
+ *
58
+ * @since 1.0.0
59
+ *
60
+ * @param string $template The template to clear the cache for
61
+ */
62
+ public function clear_cache_for_template( $template ) {
63
+ $this->clear_cache_for_substring( $template );
64
+ }
65
 
66
+ /**
67
+ * Clear the cache for keys which contain the given substring
68
+ *
69
+ * @since 1.0.0
70
+ *
71
+ * @param string $substring The substring which is a part of the keys to be cleared
72
+ */
73
+ public function clear_cache_for_substring( $substring ) {
74
+ global $wpdb;
75
+ $table_prefix = $wpdb->prefix;
76
+ $statement = 'DELETE from ' . $table_prefix . 'options
77
  WHERE option_name like %s or option_name like %s';
78
+ $transient_timeout_cache = '_transient_timeout_aalb%' . $substring . '%';
79
+ $transient_cache = '_transient_aalb%' . $substring . '%';
80
+ $prepared_statement = $wpdb->prepare( $statement, $transient_timeout_cache, $transient_cache );
81
 
82
+ try {
83
+ $wpdb->query( $prepared_statement );
84
+ } catch ( Exception $e ) {
85
+ error_log( 'Unable to clear cache. Query to clear cache for substring ' . $substring . ' failed with the Exception ' . $e->getMessage() );
86
+ }
87
  }
 
88
 
89
+ /**
90
+ * Clear the dead expired transients from cache at intervals
91
+ *
92
+ * @since 1.0.0
93
+ */
94
+ public function clear_expired_transients_at_intervals() {
95
+ $randomNumber = rand( 1, 50 );
96
+ // Clear the expired transients approximately once in 50 requests.
97
+ if ( $randomNumber == 25 ) {
98
+ $this->clear_expired_transients();
99
+ }
100
  }
 
101
 
102
+ /**
103
+ * Clear the dead expired transients from cache
104
+ *
105
+ * @since 1.0.0
106
+ */
107
+ public function clear_expired_transients() {
108
+ global $wpdb;
109
+ $table_prefix = $wpdb->prefix;
110
+ $transients_prefix = esc_sql( "_transient_timeout_aalb%" );
111
+ $sql = $wpdb->prepare( '
 
112
  SELECT option_name
113
  FROM ' . $table_prefix . 'options
114
  WHERE option_name LIKE %s
115
+ ', $transients_prefix );
116
+ $transients = $wpdb->get_col( $sql );
117
+ foreach ( $transients as $transient ) {
118
+ // Strip away the WordPress prefix in order to arrive at the transient key.
119
+ $key = str_replace( '_transient_timeout_', '', $transient );
120
+ delete_transient( $key );
121
+ }
122
+ wp_cache_flush();
123
  }
 
 
124
 
125
+ /**
126
+ * Displays error messages in preview mode only
127
+ *
128
+ * @since 1.0.0
129
+ *
130
+ * @param string $error_message Error message to be displayed
131
+ */
132
+ public function show_error_in_preview( $error_message ) {
133
+ if ( is_preview() ) {
134
+ //If it's preview mode
135
+ echo "<br><font color='red'><b>" . $error_message . "</b></font>";
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Returns the Store IDs Array.
141
+ * Returns AALB_DEFAULT_STORE_ID_NAME if the nothing is specified.
142
+ *
143
+ * @since 1.0.0
144
+ */
145
+ public function get_store_ids_array() {
146
+ return explode( "\r\n", strlen( get_option( AALB_STORE_ID_NAMES ) ) ? get_option( AALB_STORE_ID_NAMES ) : AALB_DEFAULT_STORE_ID_NAME );
147
  }
 
148
 
149
+ /**
150
+ * Fetches the Wordpress version number
151
+ *
152
+ * @since 1.0.0
153
+ * @return string Version number of Wordpress
154
+ */
155
+ function get_wordpress_version() {
156
+ global $wp_version;
157
+ return $wp_version;
158
+ }
159
 
160
+ /**
161
+ * Gets the template uploads dir URL.
162
+ *
163
+ * @since 1.3.2
164
+ * @return full URL of the template uploads directory
165
+ */
166
+ public function get_template_upload_directory_url() {
167
+ $upload_dir = wp_upload_dir();
 
 
168
 
169
+ return $upload_dir['baseurl'] . '/' . AALB_TEMPLATE_UPLOADS_FOLDER;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  }
 
 
171
 
172
+ /**
173
+ * Reads both the templates/ and the uploads/ directory and updates the template list.
174
+ * Helper to replicate the current status of the default and custom templates
175
+ *
176
+ * @since 1.3
177
+ */
178
+ public function refresh_template_list() {
179
+ global $wp_filesystem;
180
+ $this->aalb_initialize_wp_filesystem_api();
181
+
182
+ $aalb_templates = array();
183
+ $upload_dir = $this->get_template_upload_directory();
184
+
185
+ //Read and update templates from the plugin's template/ directory (Default Templates)
186
+ if ( $handle = opendir( AALB_TEMPLATE_DIR ) ) {
187
+ while ( false !== ( $entry = readdir( $handle ) ) ) {
188
+ $file_name = $this->aalb_get_file_name( $entry );
189
+ $file_extension = $this->aalb_get_file_extension( $entry );
190
+ if ( $file_extension == "css" and file_exists( AALB_TEMPLATE_DIR . $file_name . '.mustache' ) ) {
191
+ $aalb_templates[] = $file_name;
192
+ }
193
+ }
194
+ closedir( $handle );
195
+ }
196
 
197
+ //Read and update templates from the uploads/ directory (Custom Templates)
198
+ if ( $handle = opendir( $upload_dir ) ) {
199
+ while ( false !== ( $entry = readdir( $handle ) ) ) {
200
+ $file_name = $this->aalb_get_file_name( $entry );
201
+ $file_extension = $this->aalb_get_file_extension( $entry );
202
+ if ( $file_extension == "css" and file_exists( $upload_dir . $file_name . '.mustache' ) ) {
203
+ $aalb_templates[] = $file_name;
204
+ }
205
+ }
206
+ }
207
+ update_option( AALB_TEMPLATE_NAMES, $aalb_templates );
208
+ }
209
 
210
+ /**
211
+ * Loads necessary files and initializes WP Filesystem API
212
+ *
213
+ * @since 1.3
214
+ */
215
+ public function aalb_initialize_wp_filesystem_api() {
216
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
217
+ WP_Filesystem();
218
+ }
 
219
 
220
+ /**
221
+ * Fetches the Uploads Directory where custom templates are stored.
222
+ * If the dir doesn't exists, it is created and returned.
223
+ *
224
+ * @since 1.3
225
+ * @return Full directory path of the template uploads directory
226
+ */
227
+ public function get_template_upload_directory() {
228
+ global $wp_filesystem;
229
+ $this->aalb_initialize_wp_filesystem_api();
230
+ $aalb_template_upload_dir = $this->get_template_upload_directory_name( $wp_filesystem );
231
+ if ( ! $wp_filesystem->is_dir( $aalb_template_upload_dir ) ) {
232
+ if ( ! $this->create_template_upload_dir( $aalb_template_upload_dir ) ) {
233
+ return false;
234
+ }
235
+ }
236
 
237
+ return $aalb_template_upload_dir;
238
+ }
 
 
 
 
 
 
 
 
239
 
240
+ /**
241
+ * Gets the template uploads dir name.
242
+ *
243
+ * @since 1.3
244
+ * @return full path of the template uploads directory
245
+ */
246
+ public function get_template_upload_directory_name() {
247
+ global $wp_filesystem;
248
+ $upload_dir = wp_upload_dir();
 
249
 
250
+ return $wp_filesystem->find_folder( $upload_dir['basedir'] ) . AALB_TEMPLATE_UPLOADS_FOLDER;
251
+ }
 
 
 
 
 
 
 
252
 
253
+ /**
254
+ * Creates the Uploads Directory where custom templates are stored
255
+ *
256
+ * @since 1.3
257
+ * @return TRUE on successful creation of the dir; FALSE otherwise
258
+ */
259
+ public function create_template_upload_dir( $aalb_template_upload_dir ) {
260
+ global $wp_filesystem;
261
+ if ( ! wp_mkdir_p( $aalb_template_upload_dir ) ) {
262
+ error_log( "Error Creating Dir . " . $aalb_template_upload_dir . ". Please set the folder permissions correctly." );
263
 
264
+ return false;
 
 
 
 
 
 
265
  }
266
+
267
+ return true;
268
  }
269
 
270
+ /**
271
+ * Gets the name of the file without the extension
272
+ *
273
+ * @since 1.0
274
+ *
275
+ * @param string $file_name Name of the file
276
+ *
277
+ * @return string Name of the file without the extension
278
+ */
279
+ function aalb_get_file_name( $file_name ) {
280
+ return substr( $file_name, 0, strlen( $file_name ) - strlen( strrchr( $file_name, '.' ) ) );
281
+ }
282
+
283
+ /**
284
+ * Gets the extension of the file
285
+ *
286
+ * @since 1.0
287
+ *
288
+ * @param string $file_name Name of the file
289
+ *
290
+ * @return string Extension of the file
291
+ */
292
+ public function aalb_get_file_extension( $file_name ) {
293
+ return substr( strrchr( $file_name, '.' ), 1 );
294
  }
 
 
295
  }
296
+
297
  ?>
includes/aalb_hook_loader.php CHANGED
@@ -21,61 +21,65 @@ and limitations under the License.
21
  */
22
  class Aalb_Hook_Loader {
23
 
24
- protected $actions;
25
 
26
- public function __construct() {
27
- $this->actions = array();
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- /**
31
- * Add a new action to the collection to be registered with WordPress.
32
- *
33
- * @since 1.0.0
34
- * @param string $hook The name of the WordPress action that is being registered.
35
- * @param object $component A reference to the instance of the object on which the action is defined.
36
- * @param string $callback The name of the function definition on the $component.
37
- * @param int $priority Optional. he priority at which the function should be fired. Default is 10.
38
- * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
39
- */
40
- public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
41
- $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
42
- }
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- /**
45
- * A utility function that is used to register the actions and hooks into a single
46
- * collection.
47
- *
48
- * @since 1.0.0
49
- * @access private
50
- * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
51
- * @param string $hook The name of the WordPress filter that is being registered.
52
- * @param object $component A reference to the instance of the object on which the filter is defined.
53
- * @param string $callback The name of the function definition on the $component.
54
- * @param int $priority The priority at which the function should be fired.
55
- * @param int $accepted_args The number of arguments that should be passed to the $callback.
56
- * @return array The collection of actions and filters registered with WordPress.
57
- */
58
- private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
59
- $hooks[] = array(
60
- 'hook' => $hook,
61
- 'component' => $component,
62
- 'callback' => $callback,
63
- 'priority' => $priority,
64
- 'accepted_args' => $accepted_args
65
- );
66
- return $hooks;
67
- }
68
 
69
- /**
70
- * Register the filters and actions with WordPress.
71
- *
72
- * @since 1.0.0
73
- */
74
- public function execute() {
75
- foreach ( $this->actions as $hook ) {
76
- add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
 
77
  }
78
- }
79
 
80
  }
81
 
21
  */
22
  class Aalb_Hook_Loader {
23
 
24
+ protected $actions;
25
 
26
+ public function __construct() {
27
+ $this->actions = array();
28
+ }
29
+
30
+ /**
31
+ * Add a new action to the collection to be registered with WordPress.
32
+ *
33
+ * @since 1.0.0
34
+ *
35
+ * @param string $hook The name of the WordPress action that is being registered.
36
+ * @param object $component A reference to the instance of the object on which the action is defined.
37
+ * @param string $callback The name of the function definition on the $component.
38
+ * @param int $priority Optional. he priority at which the function should be fired. Default is 10.
39
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
40
+ */
41
+ public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
42
+ $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
43
+ }
44
 
45
+ /**
46
+ * A utility function that is used to register the actions and hooks into a single
47
+ * collection.
48
+ *
49
+ * @since 1.0.0
50
+ * @access private
51
+ *
52
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
53
+ * @param string $hook The name of the WordPress filter that is being registered.
54
+ * @param object $component A reference to the instance of the object on which the filter is defined.
55
+ * @param string $callback The name of the function definition on the $component.
56
+ * @param int $priority The priority at which the function should be fired.
57
+ * @param int $accepted_args The number of arguments that should be passed to the $callback.
58
+ *
59
+ * @return array The collection of actions and filters registered with WordPress.
60
+ */
61
+ private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
62
+ $hooks[] = array(
63
+ 'hook' => $hook,
64
+ 'component' => $component,
65
+ 'callback' => $callback,
66
+ 'priority' => $priority,
67
+ 'accepted_args' => $accepted_args
68
+ );
69
 
70
+ return $hooks;
71
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ /**
74
+ * Register the filters and actions with WordPress.
75
+ *
76
+ * @since 1.0.0
77
+ */
78
+ public function execute() {
79
+ foreach ( $this->actions as $hook ) {
80
+ add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
81
+ }
82
  }
 
83
 
84
  }
85
 
includes/aalb_manager.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  /*
4
  Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@@ -21,62 +21,62 @@ and limitations under the License.
21
  */
22
  class Aalb_Manager {
23
 
24
- protected $hook_loader;
25
- protected $shortcode_loader;
26
 
27
- public function __construct() {
28
- $this->hook_loader = new Aalb_Hook_Loader();
29
- $this->shortcode_loader = new Aalb_Shortcode_Loader();
30
 
31
- //add the hooks specific to admin.
32
- $this->add_admin_hooks();
33
 
34
- //add the hooks for shortcode rendering.
35
- $this->register_shortcode_hooks();
36
- }
37
-
38
- /**
39
- * Add the hooks in the admin section
40
- *
41
- * @since 1.0.0
42
- */
43
- private function add_admin_hooks() {
44
- $aalb_admin = new Aalb_Admin();
45
- $this->hook_loader->add_action( 'admin_enqueue_scripts', $aalb_admin, 'enqueue_styles' );
46
- $this->hook_loader->add_action( 'admin_enqueue_scripts', $aalb_admin, 'enqueue_scripts' );
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');
56
- $this->hook_loader->add_action( 'admin_menu', $aalb_sidebar, 'register_sidebar_config_page');
57
- }
 
 
 
 
 
 
 
 
 
 
 
58
 
59
- /**
60
- * Add the hooks for the shortcode rendering.
61
- *
62
- * @since 1.0.0
63
- */
64
- private function register_shortcode_hooks() {
65
- $aalb_shortcode = $this->shortcode_loader->get_amazon_link_shortcode();
66
- $aalb_shortcode_text = $this->shortcode_loader->get_amazon_textlink_shortcode();
67
- $this->hook_loader->add_action('wp_enqueue_scripts', $aalb_shortcode, 'enqueue_styles');
68
- $this->hook_loader->add_action('wp_enqueue_scripts', $aalb_shortcode_text, 'enqueue_styles');
69
- }
70
 
71
- /**
72
- * Execute all the wordpress hooks and shortcodes.
73
- *
74
- * @since 1.0.0
75
- */
76
- public function execute() {
77
- $this->hook_loader->execute();
78
- $this->shortcode_loader->add_shortcode();
79
- }
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  }
82
 
1
+ <?php
2
 
3
  /*
4
  Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
21
  */
22
  class Aalb_Manager {
23
 
24
+ protected $hook_loader;
25
+ protected $shortcode_loader;
26
 
27
+ public function __construct() {
28
+ $this->hook_loader = new Aalb_Hook_Loader();
29
+ $this->shortcode_loader = new Aalb_Shortcode_Loader();
30
 
31
+ //add the hooks specific to admin.
32
+ $this->add_admin_hooks();
33
 
34
+ //add the hooks for shortcode rendering.
35
+ $this->register_shortcode_hooks();
36
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ /**
39
+ * Add the hooks in the admin section
40
+ *
41
+ * @since 1.0.0
42
+ */
43
+ private function add_admin_hooks() {
44
+ $aalb_admin = new Aalb_Admin();
45
+ $this->hook_loader->add_action( 'admin_enqueue_scripts', $aalb_admin, 'enqueue_styles' );
46
+ $this->hook_loader->add_action( 'admin_enqueue_scripts', $aalb_admin, 'enqueue_scripts' );
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' );
56
+ $this->hook_loader->add_action( 'admin_menu', $aalb_sidebar, 'register_sidebar_config_page' );
57
+ }
 
 
 
 
 
 
 
58
 
59
+ /**
60
+ * Add the hooks for the shortcode rendering.
61
+ *
62
+ * @since 1.0.0
63
+ */
64
+ private function register_shortcode_hooks() {
65
+ $aalb_shortcode = $this->shortcode_loader->get_amazon_link_shortcode();
66
+ $aalb_shortcode_text = $this->shortcode_loader->get_amazon_textlink_shortcode();
67
+ $this->hook_loader->add_action( 'wp_enqueue_scripts', $aalb_shortcode, 'enqueue_styles' );
68
+ $this->hook_loader->add_action( 'wp_enqueue_scripts', $aalb_shortcode_text, 'enqueue_styles' );
69
+ }
70
+
71
+ /**
72
+ * Execute all the wordpress hooks and shortcodes.
73
+ *
74
+ * @since 1.0.0
75
+ */
76
+ public function execute() {
77
+ $this->hook_loader->execute();
78
+ $this->shortcode_loader->add_shortcode();
79
+ }
80
 
81
  }
82
 
includes/aalb_remote_loader.php CHANGED
@@ -23,67 +23,77 @@ and limitations under the License.
23
  */
24
  class Aalb_Remote_Loader {
25
 
26
- /**
27
- * Load the information by making a GET request.
28
- *
29
- * @since 1.0.0
30
- * @param string $url URL for making a request.
31
- * @return string GET response body.
32
- */
33
- public function load($url) {
34
- $response = $this->fetch($url);
35
- return $this->verify($response);
36
- }
37
 
38
- /**
39
- * Load the information by making a POST request.
40
- *
41
- * @since 1.0.0
42
- * @param string $url URL for making a request.
43
- * @param string $body Body of the POST request.
44
- * @return string POST response body.
45
- */
46
- public function post($url, $body) {
47
- $response = wp_remote_post($url, array('body' => $body));
48
- return $this->verify($response);
49
- }
50
-
51
- /**
52
- * Make a GET request and return the response.
53
- *
54
- * @since 1.0.0
55
- * @param string $url URL for making a request.
56
- * @return string GET Response.
57
- */
58
- private function fetch($url) {
59
- return wp_remote_get($url);
60
- }
61
 
62
- /**
63
- * Verify the response the throw exceptions accordingly.
64
- * Return only the response body.
65
- *
66
- * @since 1.0.0
67
- * @param string $response Whole response including headers,body and footers.
68
- * @return string Response body.
69
- */
70
- private function verify($response) {
71
- if(is_wp_error($response)) {
72
- $error_message = $response->get_error_message();
73
- throw new Exception('HTTP Request failed! ' . $error_message);
74
  }
75
- $code = $response['response']['code'];
76
- if($code != HTTP_SUCCESS) {
77
- throw new Exception($code);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  }
79
- $response_body = wp_remote_retrieve_body($response);
80
- if(!isset($response_body) || trim($response_body)==='') {
81
- throw new Exception('Response body is empty');
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
-
84
- return $response_body;
85
- }
86
-
87
  }
88
 
89
  ?>
23
  */
24
  class Aalb_Remote_Loader {
25
 
26
+ /**
27
+ * Load the information by making a GET request.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param string $url URL for making a request.
32
+ *
33
+ * @return string GET response body.
34
+ */
35
+ public function load( $url ) {
36
+ $response = $this->fetch( $url );
37
 
38
+ return $this->verify( $response );
39
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ /**
42
+ * Make a GET request and return the response.
43
+ *
44
+ * @since 1.0.0
45
+ *
46
+ * @param string $url URL for making a request.
47
+ *
48
+ * @return string GET Response.
49
+ */
50
+ private function fetch( $url ) {
51
+ return wp_remote_get( $url );
 
52
  }
53
+
54
+ /**
55
+ * Verify the response the throw exceptions accordingly.
56
+ * Return only the response body.
57
+ *
58
+ * @since 1.0.0
59
+ *
60
+ * @param string $response Whole response including headers,body and footers.
61
+ *
62
+ * @return string Response body.
63
+ */
64
+ private function verify( $response ) {
65
+ if ( is_wp_error( $response ) ) {
66
+ $error_message = $response->get_error_message();
67
+ throw new Exception( 'HTTP Request failed! ' . $error_message );
68
+ }
69
+ $code = $response['response']['code'];
70
+ if ( $code != HTTP_SUCCESS ) {
71
+ throw new Exception( $code );
72
+ }
73
+ $response_body = wp_remote_retrieve_body( $response );
74
+ if ( ! isset( $response_body ) || trim( $response_body ) === '' ) {
75
+ throw new Exception( 'Response body is empty' );
76
+ }
77
+
78
+ return $response_body;
79
  }
80
+
81
+ /**
82
+ * Load the information by making a POST request.
83
+ *
84
+ * @since 1.0.0
85
+ *
86
+ * @param string $url URL for making a request.
87
+ * @param string $body Body of the POST request.
88
+ *
89
+ * @return string POST response body.
90
+ */
91
+ public function post( $url, $body ) {
92
+ $response = wp_remote_post( $url, array( 'body' => $body ) );
93
+
94
+ return $this->verify( $response );
95
  }
96
+
 
 
 
97
  }
98
 
99
  ?>
includes/aalb_template_engine.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  /*
4
  Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@@ -21,114 +21,126 @@ and limitations under the License.
21
  */
22
  class Aalb_Template_Engine {
23
 
24
- protected $xml_loader;
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
-
39
- /**
40
- * Render the products into the display unit.
41
- * If the display unit exists in the cache return the display unit.
42
- * Else get the xml and render the product.
43
- *
44
- * @since 1.0.0
45
- * @param string $display_key Key of the display unit.
46
- * @param string $products_key Key of the combined products.
47
- * @param string $template Template to render the display unit.
48
- * @param string $url Url to get the product from if not present in cache.
49
- * @return string HTML of the disply unit.
50
- */
51
- public function render($display_key, $products_key, $template, $url, $marketplace) {
52
- if(false === ($display_unit = $this->cache_template_loader->get_display_unit($display_key) ) ) {
53
- $products = $this->get_products($products_key, $url);
54
- $xml = $this->parse($products);
55
- $items = $this->get_items($xml);
56
-
57
- //Add custom nodes to the XML
58
- $custom_items = $this->xml_helper->add_custom_nodes($items, $marketplace);
59
-
60
- $display_unit = $this->render_xml($custom_items, $template);
61
- $this->cache_template_loader->save_display_unit($display_key, $display_unit);
62
  }
63
- return $display_unit;
64
- }
65
-
66
- /**
67
- * Get the products information.
68
- *
69
- * @since 1.0.0
70
- * @param string $key Unique identification of the product.
71
- * @param string $url Signed URL for the PAAPI request.
72
- * @return string Xml response from PAAPI.
73
- */
74
- private function get_products($key, $url) {
75
- return $this->xml_loader->load($key, $url);
76
- }
77
-
78
- /**
79
- * Convert the well-formed xml string into a SimpleXMLElement object.
80
- *
81
- * @since 1.0.0
82
- * @param string $xml_string Well-formed XML string
83
- * @return SimpleXMLElement Php xml object.
84
- */
85
- private function parse($xml_string) {
86
- libxml_use_internal_errors(true);
87
- $xml = simplexml_load_string($xml_string);
88
-
89
- if($xml === false) {
90
- throw new Exception('Failed Loading XML');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  }
92
 
93
- if(isset($xml->Items->Request->Errors->Error)) {
94
- throw new Exception($xml->Items->Request->Errors->Error->Code);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
 
97
- return $xml;
98
- }
99
-
100
- /**
101
- * Return the Item attribute contained in the xml.
102
- *
103
- * @since 1.0.0
104
- * @param SimpleXMLElement $xml Well-formed XML string
105
- * @return SimpleXMLElement Php xml object of the Items attribute.
106
- */
107
- private function get_items($xml) {
108
- return $xml->Items;
109
- }
110
-
111
- /**
112
- * Render the xml with a specific template.
113
- *
114
- * @since 1.0.0
115
- * @param array $items Each key consists of an item information object.
116
- * @param string $template Template in which the content has to be rendered.
117
- * @return string HTML of the display unit.
118
- */
119
- private function render_xml($items, $template) {
120
- $aalb_default_templates = explode(",", AALB_AMAZON_TEMPLATE_NAMES);
121
- try {
122
- if(in_array($template, $aalb_default_templates)) {
123
- $template = $this->mustache->loadTemplate($template);
124
- } else {
125
- $template = $this->mustache_custom->loadTemplate($template);
126
- }
127
- } catch (Mustache_Exception_UnknownTemplateException $e) {
128
- $template = $this->mustache->loadTemplate(get_option(AALB_DEFAULT_TEMPLATE,AALB_DEFAULT_TEMPLATE_NAME));
129
  }
130
 
131
- return $template->render(array('StoreId' => get_option(AALB_DEFAULT_STORE_ID),'Items' => $items));
132
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  }
 
134
  ?>
1
+ <?php
2
 
3
  /*
4
  Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
21
  */
22
  class Aalb_Template_Engine {
23
 
24
+ protected $xml_loader;
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
+
39
+ /**
40
+ * Render the products into the display unit.
41
+ * If the display unit exists in the cache return the display unit.
42
+ * Else get the xml and render the product.
43
+ *
44
+ * @since 1.0.0
45
+ *
46
+ * @param string $display_key Key of the display unit.
47
+ * @param string $products_key Key of the combined products.
48
+ * @param string $template Template to render the display unit.
49
+ * @param string $url Url to get the product from if not present in cache.
50
+ *
51
+ * @return string HTML of the disply unit.
52
+ */
53
+ public function render( $display_key, $products_key, $template, $url, $marketplace ) {
54
+ if ( false === ( $display_unit = $this->cache_template_loader->get_display_unit( $display_key ) ) ) {
55
+ $products = $this->get_products( $products_key, $url );
56
+ $xml = $this->parse( $products );
57
+ $items = $this->get_items( $xml );
58
+
59
+ //Add custom nodes to the XML
60
+ $custom_items = $this->xml_helper->add_custom_nodes( $items, $marketplace );
61
+
62
+ $display_unit = $this->render_xml( $custom_items, $template );
63
+ $this->cache_template_loader->save_display_unit( $display_key, $display_unit );
64
+ }
65
+
66
+ return $display_unit;
67
+ }
68
+
69
+ /**
70
+ * Get the products information.
71
+ *
72
+ * @since 1.0.0
73
+ *
74
+ * @param string $key Unique identification of the product.
75
+ * @param string $url Signed URL for the PAAPI request.
76
+ *
77
+ * @return string Xml response from PAAPI.
78
+ */
79
+ private function get_products( $key, $url ) {
80
+ return $this->xml_loader->load( $key, $url );
81
  }
82
 
83
+ /**
84
+ * Convert the well-formed xml string into a SimpleXMLElement object.
85
+ *
86
+ * @since 1.0.0
87
+ *
88
+ * @param string $xml_string Well-formed XML string
89
+ *
90
+ * @return SimpleXMLElement Php xml object.
91
+ */
92
+ private function parse( $xml_string ) {
93
+ libxml_use_internal_errors( true );
94
+ $xml = simplexml_load_string( $xml_string );
95
+
96
+ if ( $xml === false ) {
97
+ throw new Exception( 'Failed Loading XML' );
98
+ }
99
+
100
+ if ( isset( $xml->Items->Request->Errors->Error ) ) {
101
+ throw new Exception( $xml->Items->Request->Errors->Error->Code );
102
+ }
103
+
104
+ return $xml;
105
  }
106
 
107
+ /**
108
+ * Return the Item attribute contained in the xml.
109
+ *
110
+ * @since 1.0.0
111
+ *
112
+ * @param SimpleXMLElement $xml Well-formed XML string
113
+ *
114
+ * @return SimpleXMLElement Php xml object of the Items attribute.
115
+ */
116
+ private function get_items( $xml ) {
117
+ return $xml->Items;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  }
119
 
120
+ /**
121
+ * Render the xml with a specific template.
122
+ *
123
+ * @since 1.0.0
124
+ *
125
+ * @param array $items Each key consists of an item information object.
126
+ * @param string $template Template in which the content has to be rendered.
127
+ *
128
+ * @return string HTML of the display unit.
129
+ */
130
+ private function render_xml( $items, $template ) {
131
+ $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
132
+ try {
133
+ if ( in_array( $template, $aalb_default_templates ) ) {
134
+ $template = $this->mustache->loadTemplate( $template );
135
+ } else {
136
+ $template = $this->mustache_custom->loadTemplate( $template );
137
+ }
138
+ } catch ( Mustache_Exception_UnknownTemplateException $e ) {
139
+ $template = $this->mustache->loadTemplate( get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ) );
140
+ }
141
+
142
+ return $template->render( array( 'StoreId' => get_option( AALB_DEFAULT_STORE_ID ), 'Items' => $items ) );
143
+ }
144
  }
145
+
146
  ?>
lib/php/Paapi/aalb_paapi_helper.php CHANGED
@@ -21,109 +21,108 @@ and limitations under the License.
21
  */
22
  class Aalb_Paapi_Helper {
23
 
24
- /**
25
- * Returns signed URL for Paapi request
26
- *
27
- * @since 1.0.0
28
- * @param array $params Paapi parameters.
29
- * @param string $marketplace Marketplace to search the product.
30
- * @return string Signed URL.
31
- */
32
- function aws_signed_url($params,$marketplace) {
33
- $access_key_id = openssl_decrypt(base64_decode(get_option(AALB_AWS_ACCESS_KEY)), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV);
34
- $secret_key = openssl_decrypt(base64_decode(get_option(AALB_AWS_SECRET_KEY)), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV);
35
- $host = $marketplace;
36
-
37
- $method = 'GET';
38
- $uri = PAAPI_URI;
39
-
40
- $params["Service"] = PAAPI_SERVICE;
41
- $params["AWSAccessKeyId"] = $access_key_id;
42
- $params["Timestamp"] = gmdate('Y-m-d\TH:i:s\Z');
43
- $params["Version"] = PAAPI_VERSION;
44
-
45
- ksort($params);
46
-
47
- $canonicalized_query = array();
48
- foreach ($params as $param => $value) {
49
- $param = str_replace("%7E", "~", rawurlencode($param));
50
- $value = str_replace("%7E", "~", rawurlencode($value));
51
- $canonicalized_query[] = $param . "=" . $value;
52
  }
53
 
54
- $canonicalized_query = implode("&", $canonicalized_query);
55
-
56
- $string_to_sign = $method . "\n" . $host . "\n" . $uri . "\n" . $canonicalized_query;
57
- $signature = base64_encode(hash_hmac("sha256", $string_to_sign, $secret_key, true));
58
- $signature = str_replace("%7E", "~", rawurlencode($signature));
59
-
60
- $signed_url = PAAPI_TRANSFER_PROTOCOL . $host . $uri . PAAPI_URL_QUERY_SEPARATOR . $canonicalized_query . "&Signature=" . $signature;
61
-
62
- return $signed_url;
63
- }
64
-
65
- /**
66
- * Returns the item lookup URL for asins
67
- *
68
- * @param string $asin Asin value.
69
- * @param string $marketplaces Marketplace to search the products.
70
- * @param string $tracking_id Associate tag.
71
- * @return string Signed URL for item lookup.
72
- */
73
- function get_item_lookup_url($asin,$marketplace,$tracking_id) {
74
- $params = array(
75
- "Operation" => "ItemLookup",
76
- "ItemId" => "$asin",
77
- "IdType" => "ASIN",
78
- "ResponseGroup" => "Images,ItemAttributes,OfferFull",
79
- "AssociateTag" => "$tracking_id",
80
- );
81
- $url = $this->aws_signed_url ($params,$marketplace);
82
- return $url;
83
- }
84
-
85
- /**
86
- * Returns the item search URL for search keywords
87
- *
88
- * @param string $search_keywords Search keywords of the products.
89
- * @param string $marketplaces Marketplace to search the products.
90
- * @param string $tracking_id Associate tag.
91
- * @return string Signed URL for item search.
92
- */
93
- function get_item_search_url($search_keywords, $marketplace, $tracking_id) {
94
- $params = array(
95
- "Operation" => "ItemSearch",
96
- "SearchIndex" => "All",
97
- "Keywords" => "$search_keywords",
98
- "ResponseGroup" => "Images,ItemAttributes,Offers",
99
- "AssociateTag" => "$tracking_id",
100
- );
101
- $url = $this->aws_signed_url ($params, $marketplace);
102
- return $url;
103
- }
104
-
105
- /**
106
- * PA-API error messages to display in case of request errors
107
- *
108
- * @param string $error code Error code of the request.
109
- * @return string PA-API error message.
110
- */
111
- function get_error_message($error) {
112
- switch($error){
113
- case HTTP_BAD_REQUEST:
114
- return HTTP_BAD_REQUEST_MESSAGE;
115
- case HTTP_FORBIDDEN:
116
- return HTTP_FORBIDDEN_MESSAGE;
117
- case HTTP_REQUEST_URI_TOO_LONG:
118
- return HTTP_REQUEST_URI_TOO_LONG_MESSAGE;
119
- case HTTP_INTERNAL_SERVER_ERROR:
120
- return HTTP_INTERNAL_SERVER_ERROR_MESSAGE;
121
- case HTTP_THROTTLE:
122
- return HTTP_THROTTLE_MESSAGE;
123
- default:
124
- return $error;
 
 
 
 
 
 
 
 
 
 
 
 
125
  }
126
- }
127
 
128
  }
129
 
21
  */
22
  class Aalb_Paapi_Helper {
23
 
24
+ /**
25
+ * Returns the item lookup URL for asins
26
+ *
27
+ * @param string $asin Asin value.
28
+ * @param string $marketplaces Marketplace to search the products.
29
+ * @param string $tracking_id Associate tag.
30
+ *
31
+ * @return string Signed URL for item lookup.
32
+ */
33
+ function get_item_lookup_url( $asin, $marketplace, $tracking_id ) {
34
+ $params = array(
35
+ "Operation" => "ItemLookup", "ItemId" => "$asin", "IdType" => "ASIN", "ResponseGroup" => "Images,ItemAttributes,OfferFull", "AssociateTag" => "$tracking_id",
36
+ );
37
+ $url = $this->aws_signed_url( $params, $marketplace );
38
+
39
+ return $url;
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
41
 
42
+ /**
43
+ * Returns signed URL for Paapi request
44
+ *
45
+ * @since 1.0.0
46
+ *
47
+ * @param array $params Paapi parameters.
48
+ * @param string $marketplace Marketplace to search the product.
49
+ *
50
+ * @return string Signed URL.
51
+ */
52
+ function aws_signed_url( $params, $marketplace ) {
53
+ $access_key_id = openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
54
+ $secret_key = openssl_decrypt( base64_decode( get_option( AALB_AWS_SECRET_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
55
+ $host = $marketplace;
56
+
57
+ $method = 'GET';
58
+ $uri = PAAPI_URI;
59
+
60
+ $params["Service"] = PAAPI_SERVICE;
61
+ $params["AWSAccessKeyId"] = $access_key_id;
62
+ $params["Timestamp"] = gmdate( 'Y-m-d\TH:i:s\Z' );
63
+ $params["Version"] = PAAPI_VERSION;
64
+
65
+ ksort( $params );
66
+
67
+ $canonicalized_query = array();
68
+ foreach ( $params as $param => $value ) {
69
+ $param = str_replace( "%7E", "~", rawurlencode( $param ) );
70
+ $value = str_replace( "%7E", "~", rawurlencode( $value ) );
71
+ $canonicalized_query[] = $param . "=" . $value;
72
+ }
73
+
74
+ $canonicalized_query = implode( "&", $canonicalized_query );
75
+
76
+ $string_to_sign = $method . "\n" . $host . "\n" . $uri . "\n" . $canonicalized_query;
77
+ $signature = base64_encode( hash_hmac( "sha256", $string_to_sign, $secret_key, true ) );
78
+ $signature = str_replace( "%7E", "~", rawurlencode( $signature ) );
79
+
80
+ $signed_url = PAAPI_TRANSFER_PROTOCOL . $host . $uri . PAAPI_URL_QUERY_SEPARATOR . $canonicalized_query . "&Signature=" . $signature;
81
+
82
+ return $signed_url;
83
+ }
84
+
85
+ /**
86
+ * Returns the item search URL for search keywords
87
+ *
88
+ * @param string $search_keywords Search keywords of the products.
89
+ * @param string $marketplaces Marketplace to search the products.
90
+ * @param string $tracking_id Associate tag.
91
+ *
92
+ * @return string Signed URL for item search.
93
+ */
94
+ function get_item_search_url( $search_keywords, $marketplace, $tracking_id ) {
95
+ $params = array(
96
+ "Operation" => "ItemSearch", "SearchIndex" => "All", "Keywords" => "$search_keywords", "ResponseGroup" => "Images,ItemAttributes,Offers", "AssociateTag" => "$tracking_id",
97
+ );
98
+ $url = $this->aws_signed_url( $params, $marketplace );
99
+
100
+ return $url;
101
+ }
102
+
103
+ /**
104
+ * PA-API error messages to display in case of request errors
105
+ *
106
+ * @param string $error code Error code of the request.
107
+ *
108
+ * @return string PA-API error message.
109
+ */
110
+ function get_error_message( $error ) {
111
+ switch ( $error ) {
112
+ case HTTP_BAD_REQUEST:
113
+ return HTTP_BAD_REQUEST_MESSAGE;
114
+ case HTTP_FORBIDDEN:
115
+ return HTTP_FORBIDDEN_MESSAGE;
116
+ case HTTP_REQUEST_URI_TOO_LONG:
117
+ return HTTP_REQUEST_URI_TOO_LONG_MESSAGE;
118
+ case HTTP_INTERNAL_SERVER_ERROR:
119
+ return HTTP_INTERNAL_SERVER_ERROR_MESSAGE;
120
+ case HTTP_THROTTLE:
121
+ return HTTP_THROTTLE_MESSAGE;
122
+ default:
123
+ return $error;
124
+ }
125
  }
 
126
 
127
  }
128
 
lib/php/aalb_internationalization_helper.php CHANGED
@@ -21,64 +21,68 @@ and limitations under the License.
21
  */
22
  class Aalb_Internationalization_Helper {
23
 
24
- /**
25
- * Array that defines the translations for various marketplaces
26
- */
27
- protected $translation_array;
28
 
29
- public function __construct() {
30
- $this->translation_array = array(
31
- CHECK_ON_AMAZON => array(
32
- US => "Check on Amazon",
33
- FR => "Consulter sur Amazon.fr",
34
- IT => "Vedi su Amazon.it",
35
- DE => "Hier auf Amazon.de",
36
- ES => "Consultar en Amazon.es",
37
- BR => "Check on Amazon",
38
- CA => "Check on Amazon",
39
- CN => "Check on Amazon",
40
- IN => "Check on Amazon",
41
- JP => "Check on Amazon",
42
- MX => "Check on Amazon",
43
- UK => "Check on Amazon",
44
- ),
45
- OUT_OF_STOCK => array(
46
- US => "Out of stock",
47
- FR => "Rupture de stock",
48
- IT => "Non disponibile",
49
- DE => "Derzeit nicht verfügbar",
50
- ES => "Producto no disponible",
51
- BR => "Out of stock",
52
- CA => "Out of stock",
53
- CN => "Out of stock",
54
- IN => "Out of stock",
55
- JP => "Out of stock",
56
- MX => "Out of stock",
57
- UK => "Out of stock",
58
- ),
59
- );
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- /**
63
- * Internationalize stings by marketplace
64
- *
65
- * @since 1.0.0
66
- * @param String $key Identifier of string to be translated
67
- * @return String $marketplace The target marketplace name
68
- */
69
- public function internationalize_by_marketplace($key, $marketplace) {
70
- $translated_string = $this->translation_array[$key][$marketplace];
71
 
72
- if($translated_string == null) {
73
- //use english if transation is not available
74
- $translated_string = $this->translation_array[$key][AALB_DEFAULT_MARKETPLACE_NAME];
75
- if($translated_string == null) {
76
- //use key name if english is also not available
77
- $translated_string = $key;
78
- }
79
  }
80
- return $translated_string;
81
- }
82
  }
83
 
84
  ?>
21
  */
22
  class Aalb_Internationalization_Helper {
23
 
24
+ /**
25
+ * Array that defines the translations for various marketplaces
26
+ */
27
+ protected $translation_array;
28
 
29
+ public function __construct() {
30
+ $this->translation_array = array(
31
+ CHECK_ON_AMAZON => array(
32
+ US => "Check on Amazon",
33
+ FR => "Consulter sur Amazon.fr",
34
+ IT => "Vedi su Amazon.it",
35
+ DE => "Hier auf Amazon.de",
36
+ ES => "Consultar en Amazon.es",
37
+ BR => "Check on Amazon",
38
+ CA => "Check on Amazon",
39
+ CN => "Check on Amazon",
40
+ IN => "Check on Amazon",
41
+ JP => "Check on Amazon",
42
+ MX => "Check on Amazon",
43
+ UK => "Check on Amazon",
44
+ ),
45
+ OUT_OF_STOCK => array(
46
+ US => "Out of stock",
47
+ FR => "Rupture de stock",
48
+ IT => "Non disponibile",
49
+ DE => "Derzeit nicht verfügbar",
50
+ ES => "Producto no disponible",
51
+ BR => "Out of stock",
52
+ CA => "Out of stock",
53
+ CN => "Out of stock",
54
+ IN => "Out of stock",
55
+ JP => "Out of stock",
56
+ MX => "Out of stock",
57
+ UK => "Out of stock",
58
+ ),
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Internationalize stings by marketplace
64
+ *
65
+ * @since 1.0.0
66
+ *
67
+ * @param string $key Identifier of string to be translated
68
+ * @param string $marketplace The target marketplace name
69
+ *
70
+ * @return string
71
+ */
72
+ public function internationalize_by_marketplace( $key, $marketplace ) {
73
+ $translated_string = $this->translation_array[ $key ][ $marketplace ];
74
 
75
+ if ( $translated_string == null ) {
76
+ //use english if transation is not available
77
+ $translated_string = $this->translation_array[ $key ][ AALB_DEFAULT_MARKETPLACE_NAME ];
78
+ if ( $translated_string == null ) {
79
+ //use key name if english is also not available
80
+ $translated_string = $key;
81
+ }
82
+ }
 
83
 
84
+ return $translated_string;
 
 
 
 
 
 
85
  }
 
 
86
  }
87
 
88
  ?>
lib/php/aalb_tracking_api_helper.php CHANGED
@@ -21,106 +21,115 @@ and limitations under the License.
21
  */
22
  class Aalb_Tracking_Api_Helper {
23
 
24
- protected $remote_loader;
25
- protected $helper;
26
- protected $version_info;
27
-
28
- public function __construct() {
29
- $this->remote_loader = new Aalb_Remote_Loader();
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,
37
- 'plugin' => $plugin_version
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  );
39
- }
40
-
41
- /**
42
- * Builds the base url for each tracking api request. Adds common parameters
43
- *
44
- * @since 1.0.0
45
- * @param string $method_path Relative path of the api method to be called.
46
- * @return string The base url with common query parameters
47
- */
48
- private function get_base_url($method_path) {
49
- $access_key_id = openssl_decrypt(base64_decode(get_option(AALB_AWS_ACCESS_KEY)), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV);
50
- return (AALB_TRACKING_API_ENDPOINT . $method_path . '?' . AALB_TRACKING_API_SOURCE_TOOL_QUERY_PARAM . '&' . AALB_TRACKING_API_ACCESS_KEY_QUERY_PARAM . $access_key_id);
51
- }
52
-
53
- /**
54
- * Returns the response of the link-id API.
55
- * The GET request returns a unique link-id everytime a shortcode is added
56
- *
57
- * @since 1.0.0
58
- * @param string $shortcode_name Name of the shortcode used
59
- * @param string $shortcode_params Array of all shortcode parameter key-value pairs
60
- * @return string Response of the get link-id API for the given link-id
61
- */
62
- public function get_link_id($shortcode_name, $shortcode_params) {
63
- $link_info = array(
64
- 'shortcode_name' => $shortcode_name,
65
- 'shortcode_params' => $shortcode_params,
66
- 'version' => $this->version_info
67
- );
68
- $request_body = wp_json_encode($link_info);
69
- $base_url = $this->get_base_url('link-id');
70
- $response = $this->remote_loader->post($base_url, $request_body);
71
- $response_body = json_decode($response, true);
72
- return $response_body["link-id"];
73
- }
74
-
75
- /**
76
- * Returns the response of the impressions API for a given link-id
77
- * TODO: Not used post v1.4. Impression tracking plugged out for re-vamping purposes.
78
- *
79
- * @since 1.0.0
80
- * @param string $link_id Link ID for which impression parameters are required
81
- * @param string $shortcode_name Name of the shortcode used
82
- * @param string $shortcode_params Array of all shortcode parameter key-value pairs
83
- * @return string Response of the get impression API for the given link-id
84
- */
85
- public function get_impression_params($link_id, $shortcode_name, $shortcode_params) {
86
- $link_info = array(
87
- 'shortcode_name' => $shortcode_name,
88
- 'shortcode_params' => $shortcode_params,
89
- 'version' => $this->version_info
90
- );
91
- $request_body = wp_json_encode($link_info);
92
- $base_url = $this->get_base_url('impression');
93
- $url = $base_url . '&link-id=' . $link_id;
94
- return $this->remote_loader->post($url, $request_body);
95
- }
96
-
97
- /**
98
- * Returns the click URL by parsing the recieved getImpressions API Response
99
- * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
100
- *
101
- * @since 1.0.0
102
- * @param json string $impression_params JSON Response from the get impressions API for a link-id
103
- * @return string $click_url Click URL for an impression ID
104
- */
105
- public function get_click_url($impression_params) {
106
- $body = json_decode($impression_params,true);
107
- return $body["click-url"];
108
- }
109
-
110
- /**
111
- * Echoes an invisible img with src=pixel-url to fire the pixels
112
- * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
113
- *
114
- * @since 1.0.0
115
- * @param json string $impression_params JSON Response from the get impressions API for a link-id
116
- */
117
- public function insert_pixel($impression_params) {
118
- $body = json_decode($impression_params,true);
119
- $pixel_url = $body["pixel-url"];
120
- if(!is_amp_endpoint()) {
121
- echo '<img src="' . $pixel_url . '" style="display:none"></img>';
122
  }
123
- }
124
  }
125
 
126
  ?>
21
  */
22
  class Aalb_Tracking_Api_Helper {
23
 
24
+ protected $remote_loader;
25
+ protected $helper;
26
+ protected $version_info;
27
+
28
+ public function __construct() {
29
+ $this->remote_loader = new Aalb_Remote_Loader();
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,
37
+ 'plugin' => $plugin_version
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Returns the response of the link-id API.
43
+ * The GET request returns a unique link-id everytime a shortcode is added
44
+ *
45
+ * @since 1.0.0
46
+ *
47
+ * @param string $shortcode_name Name of the shortcode used
48
+ * @param string $shortcode_params Array of all shortcode parameter key-value pairs
49
+ *
50
+ * @return string Response of the get link-id API for the given link-id
51
+ */
52
+ public function get_link_id( $shortcode_name, $shortcode_params ) {
53
+ $link_info = array(
54
+ 'shortcode_name' => $shortcode_name, 'shortcode_params' => $shortcode_params, 'version' => $this->version_info
55
+ );
56
+ $request_body = wp_json_encode( $link_info );
57
+ $base_url = $this->get_base_url( 'link-id' );
58
+ $response = $this->remote_loader->post( $base_url, $request_body );
59
+ $response_body = json_decode( $response, true );
60
+
61
+ return $response_body["link-id"];
62
+ }
63
+
64
+ /**
65
+ * Builds the base url for each tracking api request. Adds common parameters
66
+ *
67
+ * @since 1.0.0
68
+ *
69
+ * @param string $method_path Relative path of the api method to be called.
70
+ *
71
+ * @return string The base url with common query parameters
72
+ */
73
+ private function get_base_url( $method_path ) {
74
+ $access_key_id = openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
75
+
76
+ return ( AALB_TRACKING_API_ENDPOINT . $method_path . '?' . AALB_TRACKING_API_SOURCE_TOOL_QUERY_PARAM . '&' . AALB_TRACKING_API_ACCESS_KEY_QUERY_PARAM . $access_key_id );
77
+ }
78
+
79
+ /**
80
+ * Returns the response of the impressions API for a given link-id
81
+ * TODO: Not used post v1.4. Impression tracking plugged out for re-vamping purposes.
82
+ *
83
+ * @since 1.0.0
84
+ *
85
+ * @param string $link_id Link ID for which impression parameters are required
86
+ * @param string $shortcode_name Name of the shortcode used
87
+ * @param string $shortcode_params Array of all shortcode parameter key-value pairs
88
+ *
89
+ * @return string Response of the get impression API for the given link-id
90
+ */
91
+ public function get_impression_params( $link_id, $shortcode_name, $shortcode_params ) {
92
+ $link_info = array(
93
+ 'shortcode_name' => $shortcode_name, 'shortcode_params' => $shortcode_params, 'version' => $this->version_info
94
  );
95
+ $request_body = wp_json_encode( $link_info );
96
+ $base_url = $this->get_base_url( 'impression' );
97
+ $url = $base_url . '&link-id=' . $link_id;
98
+
99
+ return $this->remote_loader->post( $url, $request_body );
100
+ }
101
+
102
+ /**
103
+ * Returns the click URL by parsing the recieved getImpressions API Response
104
+ * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
105
+ *
106
+ * @since 1.0.0
107
+ *
108
+ * @param string $impression_params JSON Response from the get impressions API for a link-id
109
+ *
110
+ * @return string $click_url Click URL for an impression ID
111
+ */
112
+ public function get_click_url( $impression_params ) {
113
+ $body = json_decode( $impression_params, true );
114
+
115
+ return $body["click-url"];
116
+ }
117
+
118
+ /**
119
+ * Echoes an invisible img with src=pixel-url to fire the pixels
120
+ * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
121
+ *
122
+ * @since 1.0.0
123
+ *
124
+ * @param string $impression_params JSON Response from the get impressions API for a link-id
125
+ */
126
+ public function insert_pixel( $impression_params ) {
127
+ $body = json_decode( $impression_params, true );
128
+ $pixel_url = $body["pixel-url"];
129
+ if ( ! is_amp_endpoint() ) {
130
+ echo '<img src="' . $pixel_url . '" style="display:none"></img>';
131
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
 
133
  }
134
 
135
  ?>
lib/php/aalb_validation_helper.php CHANGED
@@ -19,79 +19,94 @@ and limitations under the License.
19
  * @package AmazonAssociatesLinkBuilder
20
  * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
  */
22
- class Aalb_Validation_Helper{
23
-
24
- protected $config_loader;
25
- protected $helper;
26
-
27
- public function __construct() {
28
- $this->config_loader = new Aalb_Config_Loader();
29
- $this->helper = new Aalb_Helper();
30
- }
31
-
32
- /**
33
- * Validate ASIN
34
- *
35
- * @since 1.0.0
36
- * @param string $asins ASIN
37
- * @return bool TRUE if the asin is valid, FALSE otherwise
38
- */
39
- public function validate_asin($asin) {
40
- return preg_match('/^([0-9][0-9]{8}[0-9X]|[A-Z][A-Z0-9]{9})$/', trim($asin));
41
- }
42
-
43
- /**
44
- * Validate Template Name
45
- *
46
- * @since 1.0.0
47
- * @param string $template template name
48
- * @return bool TRUE if the template name is valid, FALSE otherwise
49
- */
50
- public function validate_template_name($template) {
51
- $aalb_template_names = get_option(AALB_TEMPLATE_NAMES);
52
- return in_array($template, $aalb_template_names);
53
- }
54
-
55
- /**
56
- * Validate Link ID
57
- * The link id should be alphanumeric inlcude hyphens (-) to be valid
58
- *
59
- * @since 1.0.0
60
- * @param string $link_id Link ID from shortcode
61
- * @return bool TRUE if the link id is valid, FALSE otherwise
62
- */
63
- public function validate_link_id($link_id) {
64
- return ctype_alnum(str_replace(array('-'), '', $link_id));
65
- }
66
-
67
- /**
68
- * Validate Marketplace
69
- *
70
- * @since 1.0.0
71
- * @param string $marketplace Marketplace Abbreviation from shortcode
72
- * @return bool TRUE if the marketplace is valid, FALSE otherwise
73
- */
74
- public function validate_marketplace($marketplace) {
75
- $aalb_marketplace_names = $this->config_loader->fetch_marketplaces();
76
- return in_array($marketplace, $aalb_marketplace_names);
77
- }
78
-
79
- /**
80
- * Validate Store ID
81
- *
82
- * @since 1.0.0
83
- * @param string $store_id Associate Tag from Shortcode
84
- * @return bool TRUE if the Associate Tag is valid, FALSE otherwise
85
- */
86
- public function validate_store_id($store_id) {
87
- $aalb_store_id_names = explode("\r\n", get_option(AALB_STORE_ID_NAMES));
88
- //If the store id used is "not-specified".
89
- if($store_id === AALB_DEFAULT_STORE_ID_NAME) {
90
- $this->helper->show_error_in_preview("Associate Tag was not found. The sales will not be attributed to any store and you will not earn the associate fees for it. Please provide a valid Associate Tag if you wish to earn the referral fees. Assocaite Tags can be configured from the 'Settings' tab in the WordPress administration panel");
91
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
- return in_array($store_id, $aalb_store_id_names);
94
- }
95
 
96
  }
 
97
  ?>
19
  * @package AmazonAssociatesLinkBuilder
20
  * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
  */
22
+ class Aalb_Validation_Helper {
23
+
24
+ protected $config_loader;
25
+ protected $helper;
26
+
27
+ public function __construct() {
28
+ $this->config_loader = new Aalb_Config_Loader();
29
+ $this->helper = new Aalb_Helper();
30
+ }
31
+
32
+ /**
33
+ * Validate ASIN
34
+ *
35
+ * @since 1.0.0
36
+ *
37
+ * @param string $asins ASIN
38
+ *
39
+ * @return bool TRUE if the asin is valid, FALSE otherwise
40
+ */
41
+ public function validate_asin( $asin ) {
42
+ return preg_match( '/^([0-9][0-9]{8}[0-9X]|[A-Z][A-Z0-9]{9})$/', trim( $asin ) );
43
+ }
44
+
45
+ /**
46
+ * Validate Template Name
47
+ *
48
+ * @since 1.0.0
49
+ *
50
+ * @param string $template template name
51
+ *
52
+ * @return bool TRUE if the template name is valid, FALSE otherwise
53
+ */
54
+ public function validate_template_name( $template ) {
55
+ $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
56
+
57
+ return in_array( $template, $aalb_template_names );
58
+ }
59
+
60
+ /**
61
+ * Validate Link ID
62
+ * The link id should be alphanumeric inlcude hyphens (-) to be valid
63
+ *
64
+ * @since 1.0.0
65
+ *
66
+ * @param string $link_id Link ID from shortcode
67
+ *
68
+ * @return bool TRUE if the link id is valid, FALSE otherwise
69
+ */
70
+ public function validate_link_id( $link_id ) {
71
+ return ctype_alnum( str_replace( array( '-' ), '', $link_id ) );
72
+ }
73
+
74
+ /**
75
+ * Validate Marketplace
76
+ *
77
+ * @since 1.0.0
78
+ *
79
+ * @param string $marketplace Marketplace Abbreviation from shortcode
80
+ *
81
+ * @return bool TRUE if the marketplace is valid, FALSE otherwise
82
+ */
83
+ public function validate_marketplace( $marketplace ) {
84
+ $aalb_marketplace_names = $this->config_loader->fetch_marketplaces();
85
+
86
+ return in_array( $marketplace, $aalb_marketplace_names );
87
+ }
88
+
89
+ /**
90
+ * Validate Store ID
91
+ *
92
+ * @since 1.0.0
93
+ *
94
+ * @param string $store_id Associate Tag from Shortcode
95
+ *
96
+ * @return bool TRUE if the Associate Tag is valid, FALSE otherwise
97
+ */
98
+ public function validate_store_id( $store_id ) {
99
+ $aalb_store_id_names = explode( "\r\n", get_option( AALB_STORE_ID_NAMES ) );
100
+ //If the store id used is "not-specified".
101
+ if ( $store_id === AALB_DEFAULT_STORE_ID_NAME ) {
102
+ $this->helper->show_error_in_preview( "Associate Tag was not found. The sales will not be attributed to any store and you will not earn the associate fees for it. Please provide a valid Associate Tag if you wish to earn the referral fees. Assocaite Tags can be configured from the 'Settings' tab in the WordPress administration panel" );
103
+
104
+ return true;
105
+ }
106
+
107
+ return in_array( $store_id, $aalb_store_id_names );
108
  }
 
 
109
 
110
  }
111
+
112
  ?>
lib/php/aalb_xml_helper.php CHANGED
@@ -21,263 +21,301 @@ and limitations under the License.
21
  */
22
  class Aalb_Xml_Helper {
23
 
24
- protected $internationalization_helper;
25
 
26
- public function __construct() {
27
- $this->internationalization_helper = new Aalb_Internationalization_Helper();
28
- }
29
 
30
- /**
31
- * Add custom nodes to xml response
32
- *
33
- * @since 1.0.0
34
- * @param SimpleXMLElement $items Well-formed XML string
35
- * @return SimpleXMLElement $items XML String with custom nodes added
36
- */
37
- public function add_custom_nodes($items, $marketplace) {
38
- $common_marketplace_node_name = 'Marketplace' . $marketplace;
39
- $items->ID = "[[UNIQUE_ID]]";
 
 
40
 
41
- //add aalb nodes needed for each item
42
- foreach ($items->Item as $item) {
43
- $aalb_node = $item->addChild('aalb');
44
 
45
- $aalb_node->ASIN = isset($item->ASIN)?$item->ASIN:NULL;
46
- $aalb_node->Title = isset($item->ItemAttributes->Title)?$item->ItemAttributes->Title:NULL;
47
- $aalb_node->DetailPageURL = isset($item->DetailPageURL)?$item->DetailPageURL:NULL;
48
- $aalb_node->LargeImageURL = isset($item->LargeImage->URL)?$item->LargeImage->URL:NULL;
49
- $aalb_node->MediumImageURL = isset($item->MediumImage->URL)?$item->MediumImage->URL:NULL;
50
- $aalb_node->SmallImageURL = isset($item->MediumImage->URL)?$item->SmallImage->URL:NULL;
51
 
52
- //Marketplace
53
- $marketplace_node_name = $common_marketplace_node_name;
54
- $aalb_node = $this->add_xml_node($aalb_node, $marketplace_node_name , 'true');
55
 
56
- //By Information
57
- $aalb_node = $this->add_by_information_node($item, $aalb_node);
58
 
59
- //Savings
60
- $aalb_node = $this->add_savings_node($item, $aalb_node);
61
 
62
- //MinimumPrice
63
- $aalb_node = $this->add_min_price_node($item, $aalb_node);
64
 
65
- //Prime
66
- $aalb_node = $this->add_prime_node($item, $aalb_node);
67
 
68
- //Merchant Name
69
- $aalb_node = $this->add_merchant_node($item, $aalb_node);
70
 
71
- //Current and Strike Price
72
- $aalb_node = $this->add_price_nodes($item, $aalb_node);
73
 
74
 
75
- //Node to check "out of stock" items
76
- $aalb_node = $this->add_out_of_stock_node($item, $aalb_node, $marketplace);
77
 
78
 
79
- //If the Buying Price is empty or if is is Too Low to Display
80
- if(empty($aalb_node->CurrentPrice) or strtolower($aalb_node->CurrentPrice) == 'too low to display') {
81
- $aalb_node->CurrentPrice = $this->internationalization_helper->internationalize_by_marketplace(CHECK_ON_AMAZON, $marketplace);
82
- }
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;
90
- }
91
-
92
- /**
93
- * Adds By Information Node
94
- * And separated list of all artists, brands and authors
95
- *
96
- * @since 1.0.0
97
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
98
- * @return SimpleXMLElement $aalb_node Node to which values are to be added
99
- */
100
- public function add_by_information_node($item, $aalb_node) {
101
- $author_array = array();
102
- $brand_array = array();
103
- $artist_array = array();
104
- $by_information = array();
105
- foreach ($item->ItemAttributes->Author as $author) {
106
- array_push($author_array, $author);
107
- }
108
- foreach ($item->ItemAttributes->Brand as $brand) {
109
- array_push($brand_array, $brand);
110
- }
111
- foreach ($item->ItemAttributes->Artist as $artist) {
112
- array_push($artist_array, $artist);
113
- }
114
- if(!empty($author_array)) {
115
- array_push($by_information, implode(', ', $author_array));
116
- }
117
- if(!empty($brand_array)) {
118
- array_push($by_information, implode(', ', $brand_array));
119
- }
120
- if(!empty($artist_array)) {
121
- array_push($by_information, implode(', ', $artist_array));
122
- }
123
- $aalb_node->By = implode(' and ', $by_information);
124
- return $aalb_node;
125
- }
126
-
127
- /**
128
- * Adds Savings related nodes
129
- * Adds Amount saved in both raw and formatted way and the percentage saved.
130
- * Savings node are added only if we get saving nodes in the XML response from PAAPI.
131
- *
132
- * @since 1.0.0
133
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
134
- * @return SimpleXMLElement $aalb_node Node to which values are to be added
135
- */
136
- public function add_savings_node($item, $aalb_node) {
137
- if(!empty($item->Offers->Offer->OfferListing->AmountSaved->FormattedPrice)) {
138
- $aalb_node = $this->add_xml_node($aalb_node, 'Saving', $item->Offers->Offer->OfferListing->AmountSaved->FormattedPrice);
139
- }
140
- if(!empty($item->Offers->Offer->OfferListing->AmountSaved->Amount)) {
141
- $aalb_node = $this->add_xml_node($aalb_node, 'SavingValue', $item->Offers->Offer->OfferListing->AmountSaved->Amount);
142
  }
143
- if(!empty($item->Offers->Offer->OfferListing->PercentageSaved)) {
144
- $aalb_node = $this->add_xml_node($aalb_node, 'SavingPercent', $item->Offers->Offer->OfferListing->PercentageSaved);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  }
146
- return $aalb_node;
147
- }
148
-
149
- /**
150
- * Adds Minimum Price related nodes
151
- * Adds raw and formatted values of minimum price
152
- *
153
- * @since 1.0.0
154
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
155
- * @return SimpleXMLElement $aalb_node Node to which values are to be added
156
- */
157
- public function add_min_price_node($item, $aalb_node) {
158
- if(!empty($item->OfferSummary->LowestNewPrice->FormattedPrice)) {
159
- $aalb_node = $this->add_xml_node($aalb_node, 'MinimumPrice', $item->OfferSummary->LowestNewPrice->FormattedPrice);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  }
161
- if(!empty($item->OfferSummary->LowestNewPrice->Amount)) {
162
- $aalb_node = $this->add_xml_node($aalb_node, 'MinimumPriceValue', $item->OfferSummary->LowestNewPrice->Amount);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  }
164
- return $aalb_node;
165
- }
166
-
167
- /**
168
- * Adds Current Price and Strike Price Nodes after applying logic
169
- * Logic for Current Price and Strike Price
170
- *
171
- * @since 1.0.0
172
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
173
- * @return SimpleXMLElement $aalb_node Node to which values are to be added
174
- */
175
- public function add_price_nodes($item, $aalb_node) {
176
- $list_price = isset($item->ItemAttributes->ListPrice->FormattedPrice)?$item->ItemAttributes->ListPrice->FormattedPrice:NULL;
177
- $price = isset($item->Offers->Offer->OfferListing->Price->FormattedPrice)?$item->Offers->Offer->OfferListing->Price->FormattedPrice:NULL;
178
- $sale_price = isset($item->Offers->Offer->OfferListing->SalePrice->FormattedPrice)?$item->Offers->Offer->OfferListing->SalePrice->FormattedPrice:NULL;
179
- $list_price_amount = isset($item->ItemAttributes->ListPrice->Amount)?$item->ItemAttributes->ListPrice->Amount:NULL;
180
- $price_amount = isset($item->Offers->Offer->OfferListing->Price->Amount)?$item->Offers->Offer->OfferListing->Price->Amount:NULL;
181
- $sale_price_amount = isset($item->Offers->Offer->OfferListing->SalePrice->Amount)?$item->Offers->Offer->OfferListing->SalePrice->Amount:NULL;
182
- if(!empty($sale_price_amount)) {
183
- //If Sale Price is returned
184
- $aalb_node->CurrentPrice = $sale_price;
185
- $aalb_node->CurrentPriceValue = $sale_price_amount;
186
- if ((int)$aalb_node->SavingPercent > 1) {
187
- $aalb_node->StrikePrice = $price;
188
- $aalb_node->StrikePriceValue = $price_amount;
189
- }
190
- } else {
191
- $aalb_node->CurrentPrice = $price;
192
- $aalb_node->CurrentPriceValue = $price_amount;
193
- if ((int)$aalb_node->SavingPercent > 1) {
194
- $aalb_node->StrikePrice = $list_price;
195
- $aalb_node->StrikePriceValue = $list_price_amount;
196
- }
197
  }
198
- return $aalb_node;
199
- }
200
-
201
- /**
202
- * Adds Prime node
203
- * Adds Prime node if the item is eligible for prime
204
- *
205
- * @since 1.4.1
206
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
207
- * @return SimpleXMLElement $aalb_node Node to which values are to be added
208
- */
209
- public function add_prime_node($item, $aalb_node) {
210
- if(!empty($item->Offers->Offer->OfferListing->IsEligibleForPrime)) {
211
- $aalb_node = $this->add_xml_node($aalb_node, 'Prime', $item->Offers->Offer->OfferListing->IsEligibleForPrime);
 
 
 
 
212
  }
213
- return $aalb_node;
214
- }
215
-
216
- /**
217
- * Adds Merchant node
218
- * Adds Merchant information inside the Merchant node
219
- *
220
- * @since 1.4.1
221
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
222
- * @return SimpleXMLElement $aalb_node Node to which values are to be added
223
- */
224
- public function add_merchant_node($item, $aalb_node) {
225
- if(!empty($item->Offers->Offer->Merchant->Name)) {
226
- $aalb_node = $this->add_xml_node($aalb_node, 'Merchant', $item->Offers->Offer->Merchant->Name);
 
 
 
 
227
  }
228
- return $aalb_node;
229
- }
230
-
231
- /**
232
- * Adds InStock node if the item is in stock; Updates Current Price otherwise
233
- *
234
- * @since 1.0.0
235
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
236
- * @return SimpleXMLElement $aalb_node Node to which values are to be added
237
- */
238
- public function add_out_of_stock_node($item, $aalb_node, $marketplace) {
239
- $total_new = isset($item->OfferSummary->TotalNew)?$item->OfferSummary->TotalNew:NULL;
240
- $availability = isset($item->Offers->Offer->OfferListing->Availability)?$item->Offers->Offer->OfferListing->Availability:NULL;
241
- if(($total_new == '0' or $availability == "Out of Stock")) {
242
- //If the item is out of stock, update Buying Price
243
- $aalb_node->CurrentPrice = $this->internationalization_helper->internationalize_by_marketplace(OUT_OF_STOCK, $marketplace);;
244
- } else {
245
- //If the item is in stock; add a xml node to identify values in stock
246
- $aalb_node->InStock = 'Yes True';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
248
- return $aalb_node;
249
- }
250
-
251
- /**
252
- * Adds a child xml node to a given parent node if the value is not empty.
253
- *
254
- * @since 1.0.0
255
- * @param SimpleXMLElement $parent_node PHP XML Object of parent node
256
- * @param string $node_name Name of the new node to be added
257
- * @param string $node_value Value of the new node to be added
258
- * @return SimpleXMLElement $parent_node Parent node with added child node
259
- */
260
- public function add_xml_node($parent_node, $node_name, $node_value) {
261
- if(!empty($node_value)) {
262
- $parent_node->$node_name = $node_value;
 
 
 
 
 
 
 
 
 
 
263
  }
264
- return $parent_node;
265
- }
266
-
267
- /**
268
- * Adds Click URL Prefix to requierd hyperlinks
269
- * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
270
- *
271
- * @since 1.0.0
272
- * @param SimpleXMLElement $items Well formed XML String
273
- * @return SimpleXMLElement $items XML String with hyperlinks prefixed with click URL
274
- */
275
- public function prefix_click_URL($items) {
276
- foreach ($items->Item as $item) {
277
- $item->DetailPageURL = '[[CLICK_URL_PREFIX]]' . $item->DetailPageURL;
 
 
 
278
  }
279
- return $items;
280
- }
281
  }
282
 
283
  ?>
21
  */
22
  class Aalb_Xml_Helper {
23
 
24
+ protected $internationalization_helper;
25
 
26
+ public function __construct() {
27
+ $this->internationalization_helper = new Aalb_Internationalization_Helper();
28
+ }
29
 
30
+ /**
31
+ * Add custom nodes to xml response
32
+ *
33
+ * @since 1.0.0
34
+ *
35
+ * @param SimpleXMLElement $items Well-formed XML string
36
+ *
37
+ * @return SimpleXMLElement $items XML String with custom nodes added
38
+ */
39
+ public function add_custom_nodes( $items, $marketplace ) {
40
+ $common_marketplace_node_name = 'Marketplace' . $marketplace;
41
+ $items->ID = "[[UNIQUE_ID]]";
42
 
43
+ //add aalb nodes needed for each item
44
+ foreach ( $items->Item as $item ) {
45
+ $aalb_node = $item->addChild( 'aalb' );
46
 
47
+ $aalb_node->ASIN = isset( $item->ASIN ) ? $item->ASIN : null;
48
+ $aalb_node->Title = isset( $item->ItemAttributes->Title ) ? $item->ItemAttributes->Title : null;
49
+ $aalb_node->DetailPageURL = isset( $item->DetailPageURL ) ? $item->DetailPageURL : null;
50
+ $aalb_node->LargeImageURL = isset( $item->LargeImage->URL ) ? $item->LargeImage->URL : null;
51
+ $aalb_node->MediumImageURL = isset( $item->MediumImage->URL ) ? $item->MediumImage->URL : null;
52
+ $aalb_node->SmallImageURL = isset( $item->MediumImage->URL ) ? $item->SmallImage->URL : null;
53
 
54
+ //Marketplace
55
+ $marketplace_node_name = $common_marketplace_node_name;
56
+ $aalb_node = $this->add_xml_node( $aalb_node, $marketplace_node_name, 'true' );
57
 
58
+ //By Information
59
+ $aalb_node = $this->add_by_information_node( $item, $aalb_node );
60
 
61
+ //Savings
62
+ $aalb_node = $this->add_savings_node( $item, $aalb_node );
63
 
64
+ //MinimumPrice
65
+ $aalb_node = $this->add_min_price_node( $item, $aalb_node );
66
 
67
+ //Prime
68
+ $aalb_node = $this->add_prime_node( $item, $aalb_node );
69
 
70
+ //Merchant Name
71
+ $aalb_node = $this->add_merchant_node( $item, $aalb_node );
72
 
73
+ //Current and Strike Price
74
+ $aalb_node = $this->add_price_nodes( $item, $aalb_node );
75
 
76
 
77
+ //Node to check "out of stock" items
78
+ $aalb_node = $this->add_out_of_stock_node( $item, $aalb_node, $marketplace );
79
 
80
 
81
+ //If the Buying Price is empty or if is is Too Low to Display
82
+ if ( empty( $aalb_node->CurrentPrice ) or strtolower( $aalb_node->CurrentPrice ) == 'too low to display' ) {
83
+ $aalb_node->CurrentPrice = $this->internationalization_helper->internationalize_by_marketplace( CHECK_ON_AMAZON, $marketplace );
84
+ }
85
+ }
86
 
87
+ //add common aalb nodes
88
+ $aalb_common_node = $items->addChild( 'AalbHeader' );
89
+ $aalb_common_node = $this->add_xml_node( $aalb_common_node, $common_marketplace_node_name, 'true' );
90
+
91
+ return $items;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
+
94
+ /**
95
+ * Adds a child xml node to a given parent node if the value is not empty.
96
+ *
97
+ * @since 1.0.0
98
+ *
99
+ * @param SimpleXMLElement $parent_node PHP XML Object of parent node
100
+ * @param string $node_name Name of the new node to be added
101
+ * @param string $node_value Value of the new node to be added
102
+ *
103
+ * @return SimpleXMLElement $parent_node Parent node with added child node
104
+ */
105
+ public function add_xml_node( $parent_node, $node_name, $node_value ) {
106
+ if ( ! empty( $node_value ) ) {
107
+ $parent_node->$node_name = $node_value;
108
+ }
109
+
110
+ return $parent_node;
111
  }
112
+
113
+ /**
114
+ * Adds By Information Node
115
+ * And separated list of all artists, brands and authors
116
+ *
117
+ * @since 1.0.0
118
+ *
119
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
120
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
121
+ *
122
+ * @return SimpleXMLElement Modified aalb_node
123
+ */
124
+ public function add_by_information_node( $item, $aalb_node ) {
125
+ $author_array = array();
126
+ $brand_array = array();
127
+ $artist_array = array();
128
+ $by_information = array();
129
+ foreach ( $item->ItemAttributes->Author as $author ) {
130
+ array_push( $author_array, $author );
131
+ }
132
+ foreach ( $item->ItemAttributes->Brand as $brand ) {
133
+ array_push( $brand_array, $brand );
134
+ }
135
+ foreach ( $item->ItemAttributes->Artist as $artist ) {
136
+ array_push( $artist_array, $artist );
137
+ }
138
+ if ( ! empty( $author_array ) ) {
139
+ array_push( $by_information, implode( ', ', $author_array ) );
140
+ }
141
+ if ( ! empty( $brand_array ) ) {
142
+ array_push( $by_information, implode( ', ', $brand_array ) );
143
+ }
144
+ if ( ! empty( $artist_array ) ) {
145
+ array_push( $by_information, implode( ', ', $artist_array ) );
146
+ }
147
+ $aalb_node->By = implode( ' and ', $by_information );
148
+
149
+ return $aalb_node;
150
  }
151
+
152
+ /**
153
+ * Adds Savings related nodes
154
+ * Adds Amount saved in both raw and formatted way and the percentage saved.
155
+ * Savings node are added only if we get saving nodes in the XML response from PAAPI.
156
+ *
157
+ * @since 1.0.0
158
+ *
159
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
160
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
161
+ *
162
+ * @return SimpleXMLElement Node to which values are added
163
+ */
164
+ public function add_savings_node( $item, $aalb_node ) {
165
+ if ( ! empty( $item->Offers->Offer->OfferListing->AmountSaved->FormattedPrice ) ) {
166
+ $aalb_node = $this->add_xml_node( $aalb_node, 'Saving', $item->Offers->Offer->OfferListing->AmountSaved->FormattedPrice );
167
+ }
168
+ if ( ! empty( $item->Offers->Offer->OfferListing->AmountSaved->Amount ) ) {
169
+ $aalb_node = $this->add_xml_node( $aalb_node, 'SavingValue', $item->Offers->Offer->OfferListing->AmountSaved->Amount );
170
+ }
171
+ if ( ! empty( $item->Offers->Offer->OfferListing->PercentageSaved ) ) {
172
+ $aalb_node = $this->add_xml_node( $aalb_node, 'SavingPercent', $item->Offers->Offer->OfferListing->PercentageSaved );
173
+ }
174
+
175
+ return $aalb_node;
176
  }
177
+
178
+ /**
179
+ * Adds Minimum Price related nodes
180
+ * Adds raw and formatted values of minimum price
181
+ *
182
+ * @since 1.0.0
183
+ *
184
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
185
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
186
+ *
187
+ * @return SimpleXMLElement Node to which values are added
188
+ */
189
+ public function add_min_price_node( $item, $aalb_node ) {
190
+ if ( ! empty( $item->OfferSummary->LowestNewPrice->FormattedPrice ) ) {
191
+ $aalb_node = $this->add_xml_node( $aalb_node, 'MinimumPrice', $item->OfferSummary->LowestNewPrice->FormattedPrice );
192
+ }
193
+ if ( ! empty( $item->OfferSummary->LowestNewPrice->Amount ) ) {
194
+ $aalb_node = $this->add_xml_node( $aalb_node, 'MinimumPriceValue', $item->OfferSummary->LowestNewPrice->Amount );
195
+ }
196
+
197
+ return $aalb_node;
 
 
 
 
 
 
 
 
 
 
 
 
198
  }
199
+
200
+ /**
201
+ * Adds Prime node
202
+ * Adds Prime node if the item is eligible for prime
203
+ *
204
+ * @since 1.4.1
205
+ *
206
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
207
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
208
+ *
209
+ * @return SimpleXMLElement Node to which values are added
210
+ */
211
+ public function add_prime_node( $item, $aalb_node ) {
212
+ if ( ! empty( $item->Offers->Offer->OfferListing->IsEligibleForPrime ) ) {
213
+ $aalb_node = $this->add_xml_node( $aalb_node, 'Prime', $item->Offers->Offer->OfferListing->IsEligibleForPrime );
214
+ }
215
+
216
+ return $aalb_node;
217
  }
218
+
219
+ /**
220
+ * Adds Merchant node
221
+ * Adds Merchant information inside the Merchant node
222
+ *
223
+ * @since 1.4.1
224
+ *
225
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
226
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
227
+ *
228
+ * @return SimpleXMLElement Node to which values are added
229
+ */
230
+ public function add_merchant_node( $item, $aalb_node ) {
231
+ if ( ! empty( $item->Offers->Offer->Merchant->Name ) ) {
232
+ $aalb_node = $this->add_xml_node( $aalb_node, 'Merchant', $item->Offers->Offer->Merchant->Name );
233
+ }
234
+
235
+ return $aalb_node;
236
  }
237
+
238
+ /**
239
+ * Adds Current Price and Strike Price Nodes after applying logic
240
+ * Logic for Current Price and Strike Price
241
+ *
242
+ * @since 1.0.0
243
+ *
244
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
245
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
246
+ *
247
+ * @return SimpleXMLElement Node to which values are added
248
+ */
249
+ public function add_price_nodes( $item, $aalb_node ) {
250
+ $list_price = isset( $item->ItemAttributes->ListPrice->FormattedPrice ) ? $item->ItemAttributes->ListPrice->FormattedPrice : null;
251
+ $price = isset( $item->Offers->Offer->OfferListing->Price->FormattedPrice ) ? $item->Offers->Offer->OfferListing->Price->FormattedPrice : null;
252
+ $sale_price = isset( $item->Offers->Offer->OfferListing->SalePrice->FormattedPrice ) ? $item->Offers->Offer->OfferListing->SalePrice->FormattedPrice : null;
253
+ $list_price_amount = isset( $item->ItemAttributes->ListPrice->Amount ) ? $item->ItemAttributes->ListPrice->Amount : null;
254
+ $price_amount = isset( $item->Offers->Offer->OfferListing->Price->Amount ) ? $item->Offers->Offer->OfferListing->Price->Amount : null;
255
+ $sale_price_amount = isset( $item->Offers->Offer->OfferListing->SalePrice->Amount ) ? $item->Offers->Offer->OfferListing->SalePrice->Amount : null;
256
+ if ( ! empty( $sale_price_amount ) ) {
257
+ //If Sale Price is returned
258
+ $aalb_node->CurrentPrice = $sale_price;
259
+ $aalb_node->CurrentPriceValue = $sale_price_amount;
260
+ if ( (int) $aalb_node->SavingPercent > 1 ) {
261
+ $aalb_node->StrikePrice = $price;
262
+ $aalb_node->StrikePriceValue = $price_amount;
263
+ }
264
+ } else {
265
+ $aalb_node->CurrentPrice = $price;
266
+ $aalb_node->CurrentPriceValue = $price_amount;
267
+ if ( (int) $aalb_node->SavingPercent > 1 ) {
268
+ $aalb_node->StrikePrice = $list_price;
269
+ $aalb_node->StrikePriceValue = $list_price_amount;
270
+ }
271
+ }
272
+
273
+ return $aalb_node;
274
  }
275
+
276
+ /**
277
+ * Adds InStock node if the item is in stock; Updates Current Price otherwise
278
+ *
279
+ * @since 1.0.0
280
+ *
281
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
282
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
283
+ *
284
+ * @oaram string $marketplace
285
+ *
286
+ * @return SimpleXMLElement Node to which values are added
287
+ */
288
+ public function add_out_of_stock_node( $item, $aalb_node, $marketplace ) {
289
+ $total_new = isset( $item->OfferSummary->TotalNew ) ? $item->OfferSummary->TotalNew : null;
290
+ $availability = isset( $item->Offers->Offer->OfferListing->Availability ) ? $item->Offers->Offer->OfferListing->Availability : null;
291
+ if ( ( $total_new == '0' or $availability == "Out of Stock" ) ) {
292
+ //If the item is out of stock, update Buying Price
293
+ $aalb_node->CurrentPrice = $this->internationalization_helper->internationalize_by_marketplace( OUT_OF_STOCK, $marketplace );;
294
+ } else {
295
+ //If the item is in stock; add a xml node to identify values in stock
296
+ $aalb_node->InStock = 'Yes True';
297
+ }
298
+
299
+ return $aalb_node;
300
  }
301
+
302
+ /**
303
+ * Adds Click URL Prefix to requierd hyperlinks
304
+ * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
305
+ *
306
+ * @since 1.0.0
307
+ *
308
+ * @param SimpleXMLElement $items Well formed XML String
309
+ *
310
+ * @return SimpleXMLElement $items XML String with hyperlinks prefixed with click URL
311
+ */
312
+ public function prefix_click_URL( $items ) {
313
+ foreach ( $items->Item as $item ) {
314
+ $item->DetailPageURL = '[[CLICK_URL_PREFIX]]' . $item->DetailPageURL;
315
+ }
316
+
317
+ return $items;
318
  }
 
 
319
  }
320
 
321
  ?>
readme.txt CHANGED
@@ -1,141 +1,154 @@
1
- === Amazon Associates Link Builder ===
2
- 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.2
6
- Stable tag: 1.4.1
7
- License: GPLv2
8
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
-
10
- The official plugin from the Amazon Associates Program.
11
-
12
- == Description ==
13
- = About Amazon Associates Program =
14
- The Amazon Associates Program is one of the original affiliate marketing programs. Available in geographies across the globe, the Amazon Associates Program has been partnering with content creators to help them monetize their passions since 1996. To learn more about the Amazon Associates Program, please click [here](https://affiliate-program.amazon.com/).
15
-
16
- = About Amazon Associates Link Builder =
17
- 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.
18
-
19
- = Note =
20
- * You must review and accept the Amazon Associates Link Builder [Conditions of Use](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf).
21
- * The plugin is currently in beta form. We intend to regularly add new features and enhancements throughout the beta period and beyond, and welcome your feedback and input.
22
-
23
- == Installation ==
24
-
25
- = Pre-requisites =
26
- __Become an Associate__ <br />
27
- To become an Associate, create an Amazon Associates account using URL for your country: [Brazil](https://associados.amazon.com.br/), [Canada](https://associates.amazon.ca/), [China](https://associates.amazon.cn/), [France](https://partenaires.amazon.fr/), [Germany](http://partnernet.amazon.de/), [India](https://affiliate-program.amazon.in/), [Italy](https://programma-affiliazione.amazon.it/), [Japan](https://affiliate.amazon.co.jp/), [Mexico](https://afiliados.amazon.com.mx/), [Spain](https://afiliados.amazon.es/), [United Kingdom](https://affiliate-program.amazon.co.uk/), [United States](http://affiliate-program.amazon.com/)
28
- <br />
29
- Your Associate ID works only in the country in which you register. If you'd like to be an Associate in more than one country, please register separately for each country.
30
- <br />
31
-
32
- __Sign up for Product Advertising API__ <br />
33
- Sign up for the Amazon Product Advertising API by following the instructions listed [here](http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html). The Amazon Product Advertising API is a popular e-commerce service, powering Amazon-integrated experiences around the world, serving tens of thousands of applications and more than 1 billion API requests every day. It exposes a web-service, which allows Associates to programmatically search and look up items in the Amazon product catalog. The Link Builder plugin integrates the Product Advertising API, allowing you to access Amazon.com product catalog data without requiring additional software development.
34
-
35
- = Installing =
36
- To install the Amazon Associates Link Builder plugin: <br />
37
- 1. Log in to your WordPress dashboard, navigate to the Plugins menu and click Add New. <br />
38
- 2. In the search field type **Amazon Associates Link Builder** and click Search Plugins. You can install it by simply clicking **Install Now**.
39
-
40
- = Updating =
41
- Automatic updates should work like a charm. That said, it's always good practice to back up your templates just in case.
42
-
43
- = User Guide =
44
- You can review the **About** section under the Associates Link Builder menu bar or [Link Builder User Guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf) for more information on getting started and key features of the plugin.
45
-
46
- = Configure plugin for first use =
47
- Use the Associates Link Builder->Settings screen to configure the plugin. <br />
48
- 1. Set Access Key ID and Secret Access Key in the Settings section. These credentials are used to invoke requests to the Amazon Product Advertising API for fetching information on an item. <br />
49
- 2. Set default Associate ID. Associate ID is used to monitor traffic and sales from your links to Amazon. You can also define a list of valid Associate IDs (store ids or tracking ids). You should create a new tracking ID in your Amazon Associates account for using it as Associate ID in the plugin. <br />
50
- 3. Set the default Amazon marketplace based on the Amazon Associates Program for which you are registered (for example, if you've signed up for the Amazon Associates Program in UK, then your default marketplace selection should be UK) and select an appropriate template for rendering your ads.
51
-
52
- <br />
53
- That's it! You're all set to start adding Amazon affiliate links to your posts using the Amazon Associates Link Builder plugin!
54
-
55
- = Support =
56
- If you get stuck, or have any questions, you can ask for help in the [Amazon Associates Link Builder plugin forum](https://wordpress.org/support/plugin/amazon-link-builder).
57
-
58
- == Screenshots ==
59
- 1. Amazon Associates Link Builder settings console
60
- 2. Search for products in Amazon catalog directly from the WordPress toolbar while creating a new post or a page
61
- 3. Select the products you would like to advertise
62
- 4. Associate a template and Associates Id to your links
63
- 5. Product Carousel Template: Stylishly designed and responsive ad unit that automatically adapts for different device types and screen resolutions that can be placed within or at the end of your content
64
- 6. Product Ad Template: A variation of the product carousel template for advertising one product at a time
65
- 7. Product Grid Template: Another variation of the product carousel template that can be used to display a grid of products alongside your content
66
- 8. Price Link Template: Dynamic hyperlink containing the current price offered for buying the item on Amazon
67
- 9. Create custom ad templates native to your site' styling
68
-
69
- == Frequently Asked Questions ==
70
-
71
- = Where can I find more information on the Amazon Associates Program? =
72
- You can find more information on the Amazon Associates Program at [Amazon Associates Help](https://affiliate-program.amazon.com/help/node).
73
-
74
- = How does the plugin work? =
75
- The plugin makes real-time calls to the Amazon Product Advertising API to search for, and look up information on, items in Amazon.com's product catalog. Security credentials provided in the Settings console are used for signing API requests. The plugin also contains an in-build caching mechanism to cache the API results for optimizing the API usage and reducing the loading time of the link content.
76
-
77
- = Can I track the performance of the ad units created using the plugin? =
78
- Yes. You can track the performance of the ad unit by placement or section of your website by using tracking ids. You are recommended to use different tracking ids for different ad templates. This will allow you to track orders and earnings information for each type of ad using the reports section in Associates Central. You can create tracking ids [here](https://affiliate-program.amazon.com/home/account/tag/manage).
79
-
80
- = What information is shared with Amazon? =
81
- Information we learn from Amazon Associates Link Builder users helps us to evaluate performance of the plugin, troubleshoot technical issues, and generally improve the plugin. We only capture information on impressions, clicks, and sales for Amazon affiliate links in accordance with the [Amazon.com Privacy Notice](https://www.amazon.com/gp/help/customer/display.html?nodeId=468496).
82
-
83
- = Where can I find support? =
84
- You can review the **About** section under the Associates Link Builder menu bar or [Link Builder User Guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf) for more information on getting started and key features of the plugin. If you get stuck, or have any questions, you can ask for help in the [Amazon Associates Link Builder Plugin Forum](https://wordpress.org/support/plugin/amazon-associates-link-builder).
85
-
86
- = How can I add links to different Amazon sites in my blog? =
87
- You can search products using keywords in any supported country, but you have to join the Associates Program in those countries separately to be able to do this. For example - If you are a blogger in UK interested in linking to Amazon.com (US) site, then you will first need to join the Amazon Associates Program in US to be able to search for products on Amazon.com site.
88
-
89
- == Changelog ==
90
-
91
- = 1.4.1 - February 23, 2017 =
92
- * Updated error messages to provide more detailed information on how to troubleshoot errors
93
- * Fix: Amazon search button not working in text mode.
94
- * Fix: Amazon logo size with other plugin editors
95
- * Fix: Problem with shortcode creation modal dialog hanging in some cases.
96
- * Fix: General fixes to remove PHP notices.
97
-
98
- = 1.4 - January 18, 2017 =
99
- * Conditions of Use have been updated with a worldwide version. Please review the updated [Conditions of Use](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf) for the terms which are applicable to your use.
100
- * Enhancement: Now, you can create text links to Amazon products using amazon_textlink short code. Check [reference guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToCreateTextLinks.pdf) for more details.
101
- * Fix: Display Amazon [buy box](https://www.amazon.com/gp/help/customer/display.html?nodeId=200401830) price.
102
- * General improvements to reduce the loading time of the links/ ad units created via the plugin.
103
- * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
104
-
105
- = 1.3.2 - December 30, 2016 =
106
- * If you are coming from any version other than v1.3 and are using custom templates, be sure to backup your custom 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 or if you are coming from v1.3, you can simply update the plugin using the update now link.
107
- * Fix: Problems with rendering ads when using custom templates.
108
-
109
- = 1.3 - December 27, 2016 =
110
- * 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.
111
- * Fix: Preserve custom templates with plugin updates. You will no longer need to back up your custom templates when updating the plugin in future.
112
- * Fix: Update tracking pixel to display:none.
113
- * Fix: Remove ! from PriceLink template.
114
- * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
115
-
116
-
117
- = 1.2 - December 19, 2016 =
118
- * 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.
119
- * Fix: Array dereference issue with PHP version 5.3. You will no longer get PHP syntax issues while activating the plugin.
120
- * Administration of the plugin over a secured network (HTTPS) is recommended and not required.
121
- * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
122
-
123
- = 1.1 - December 13, 2016 =
124
- * Fix: Rendering of search results in Apple Safari browser.
125
-
126
- = 1.0 - December 6, 2016 =
127
- * Plugin released for beta testing
128
-
129
- == Upgrade Notice ==
130
-
131
- = 1.4.1 =
132
- This update includes minor bug fixes.
133
-
134
- = 1.4 =
135
- This update includes general performance improvements, and support for text links.
136
-
137
- = 1.3.2 =
138
- This update fixes the issue with improper rendering of ads using custom templates. If you are coming from v1.3, you don't need to take a backup of your templates before updating to v1.3.2.
139
-
140
- = 1.3 =
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  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.
1
+ === Amazon Associates Link Builder ===
2
+ 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.3
6
+ Stable tag: 1.4.2
7
+ License: GPLv2
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+
10
+ The official plugin from the Amazon Associates Program.
11
+
12
+ == Description ==
13
+ = About Amazon Associates Program =
14
+ The Amazon Associates Program is one of the original affiliate marketing programs. Available in geographies across the globe, the Amazon Associates Program has been partnering with content creators to help them monetize their passions since 1996. To learn more about the Amazon Associates Program, please click [here](https://affiliate-program.amazon.com/).
15
+
16
+ = About Amazon Associates Link Builder =
17
+ 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.
18
+
19
+ = Note =
20
+ * You must review and accept the Amazon Associates Link Builder [Conditions of Use](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf).
21
+ * The plugin is currently in beta form. We intend to regularly add new features and enhancements throughout the beta period and beyond, and welcome your feedback and input.
22
+
23
+ == Installation ==
24
+
25
+ = Pre-requisites =
26
+ __Requires PHP Version:__ 5.3 or higher
27
+ <br />
28
+
29
+ __Requires WordPress Version:__ 3.0.1 or higher
30
+ <br />
31
+
32
+ __Become an Associate__ <br />
33
+ To become an Associate, create an Amazon Associates account using URL for your country: [Brazil](https://associados.amazon.com.br/), [Canada](https://associates.amazon.ca/), [China](https://associates.amazon.cn/), [France](https://partenaires.amazon.fr/), [Germany](http://partnernet.amazon.de/), [India](https://affiliate-program.amazon.in/), [Italy](https://programma-affiliazione.amazon.it/), [Japan](https://affiliate.amazon.co.jp/), [Mexico](https://afiliados.amazon.com.mx/), [Spain](https://afiliados.amazon.es/), [United Kingdom](https://affiliate-program.amazon.co.uk/), [United States](http://affiliate-program.amazon.com/)
34
+ <br />
35
+ Your Associate ID works only in the country in which you register. If you'd like to be an Associate in more than one country, please register separately for each country.
36
+ <br />
37
+
38
+ __Sign up for Product Advertising API__ <br />
39
+ Sign up for the Amazon Product Advertising API by following the instructions listed [here](http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html). The Amazon Product Advertising API is a popular e-commerce service, powering Amazon-integrated experiences around the world, serving tens of thousands of applications and more than 1 billion API requests every day. It exposes a web-service, which allows Associates to programmatically search and look up items in the Amazon product catalog. The Link Builder plugin integrates the Product Advertising API, allowing you to access Amazon.com product catalog data without requiring additional software development.
40
+
41
+ = Installing =
42
+ To install the Amazon Associates Link Builder plugin: <br />
43
+ 1. Log in to your WordPress dashboard, navigate to the Plugins menu and click Add New. <br />
44
+ 2. In the search field type **Amazon Associates Link Builder** and click Search Plugins. You can install it by simply clicking **Install Now**.
45
+
46
+ = Updating =
47
+ Automatic updates should work like a charm. That said, it's always good practice to back up your templates just in case.
48
+
49
+ = User Guide =
50
+ You can review the **About** section under the Associates Link Builder menu bar or [Link Builder User Guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf) for more information on getting started and key features of the plugin.
51
+
52
+ = Configure plugin for first use =
53
+ Use the Associates Link Builder->Settings screen to configure the plugin. <br />
54
+ 1. Set Access Key ID and Secret Access Key in the Settings section. These credentials are used to invoke requests to the Amazon Product Advertising API for fetching information on an item. <br />
55
+ 2. Set default Associate ID. Associate ID is used to monitor traffic and sales from your links to Amazon. You can also define a list of valid Associate IDs (store ids or tracking ids). You should create a new tracking ID in your Amazon Associates account for using it as Associate ID in the plugin. <br />
56
+ 3. Set the default Amazon marketplace based on the Amazon Associates Program for which you are registered (for example, if you've signed up for the Amazon Associates Program in UK, then your default marketplace selection should be UK) and select an appropriate template for rendering your ads.
57
+
58
+ <br />
59
+ That's it! You're all set to start adding Amazon affiliate links to your posts using the Amazon Associates Link Builder plugin!
60
+
61
+ = Support =
62
+ If you get stuck, or have any questions, you can ask for help in the [Amazon Associates Link Builder plugin forum](https://wordpress.org/support/plugin/amazon-link-builder).
63
+
64
+ == Screenshots ==
65
+ 1. Amazon Associates Link Builder settings console
66
+ 2. Search for products in Amazon catalog directly from the WordPress toolbar while creating a new post or a page
67
+ 3. Select the products you would like to advertise
68
+ 4. Associate a template and Associates Id to your links
69
+ 5. Product Carousel Template: Stylishly designed and responsive ad unit that automatically adapts for different device types and screen resolutions that can be placed within or at the end of your content
70
+ 6. Product Ad Template: A variation of the product carousel template for advertising one product at a time
71
+ 7. Product Grid Template: Another variation of the product carousel template that can be used to display a grid of products alongside your content
72
+ 8. Price Link Template: Dynamic hyperlink containing the current price offered for buying the item on Amazon
73
+ 9. Create custom ad templates native to your site' styling
74
+
75
+ == Frequently Asked Questions ==
76
+
77
+ = Where can I find more information on the Amazon Associates Program? =
78
+ You can find more information on the Amazon Associates Program at [Amazon Associates Help](https://affiliate-program.amazon.com/help/node).
79
+
80
+ = How does the plugin work? =
81
+ The plugin makes real-time calls to the Amazon Product Advertising API to search for, and look up information on, items in Amazon.com's product catalog. Security credentials provided in the Settings console are used for signing API requests. The plugin also contains an in-build caching mechanism to cache the API results for optimizing the API usage and reducing the loading time of the link content.
82
+
83
+ = Can I track the performance of the ad units created using the plugin? =
84
+ Yes. You can track the performance of the ad unit by placement or section of your website by using tracking ids. You are recommended to use different tracking ids for different ad templates. This will allow you to track orders and earnings information for each type of ad using the reports section in Associates Central. You can create tracking ids [here](https://affiliate-program.amazon.com/home/account/tag/manage).
85
+
86
+ = What information is shared with Amazon? =
87
+ Information we learn from Amazon Associates Link Builder users helps us to evaluate performance of the plugin, troubleshoot technical issues, and generally improve the plugin. We only capture information on impressions, clicks, and sales for Amazon affiliate links in accordance with the [Amazon.com Privacy Notice](https://www.amazon.com/gp/help/customer/display.html?nodeId=468496).
88
+
89
+ = Where can I find support? =
90
+ You can review the **About** section under the Associates Link Builder menu bar or [Link Builder User Guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf) for more information on getting started and key features of the plugin. If you get stuck, or have any questions, you can ask for help in the [Amazon Associates Link Builder Plugin Forum](https://wordpress.org/support/plugin/amazon-associates-link-builder).
91
+
92
+ = How can I add links to different Amazon sites in my blog? =
93
+ You can search products using keywords in any supported country, but you have to join the Associates Program in those countries separately to be able to do this. For example - If you are a blogger in UK interested in linking to Amazon.com (US) site, then you will first need to join the Amazon Associates Program in US to be able to search for products on Amazon.com site.
94
+
95
+ == Changelog ==
96
+
97
+ = 1.4.2 - March 30, 2017 =
98
+ * Changes to ensure minimum PHP version requirements are met before plugin activation.
99
+ * Fix: Amazon search text box and button not showing for editors like Site Origin Page Builder and Advanced Custom Fields.
100
+
101
+ = 1.4.1 - February 23, 2017 =
102
+ * Updated error messages to provide more detailed information on how to troubleshoot errors
103
+ * Fix: Amazon search button not working in text mode.
104
+ * Fix: Amazon logo size with other plugin editors
105
+ * Fix: Problem with shortcode creation modal dialog hanging in some cases.
106
+ * Fix: General fixes to remove PHP notices.
107
+
108
+ = 1.4 - January 18, 2017 =
109
+ * Conditions of Use have been updated with a worldwide version. Please review the updated [Conditions of Use](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf) for the terms which are applicable to your use.
110
+ * Enhancement: Now, you can create text links to Amazon products using amazon_textlink short code. Check [reference guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToCreateTextLinks.pdf) for more details.
111
+ * Fix: Display Amazon [buy box](https://www.amazon.com/gp/help/customer/display.html?nodeId=200401830) price.
112
+ * General improvements to reduce the loading time of the links/ ad units created via the plugin.
113
+ * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
114
+
115
+ = 1.3.2 - December 30, 2016 =
116
+ * If you are coming from any version other than v1.3 and are using custom templates, be sure to backup your custom 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 or if you are coming from v1.3, you can simply update the plugin using the update now link.
117
+ * Fix: Problems with rendering ads when using custom templates.
118
+
119
+ = 1.3 - December 27, 2016 =
120
+ * 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.
121
+ * Fix: Preserve custom templates with plugin updates. You will no longer need to back up your custom templates when updating the plugin in future.
122
+ * Fix: Update tracking pixel to display:none.
123
+ * Fix: Remove ! from PriceLink template.
124
+ * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
125
+
126
+
127
+ = 1.2 - December 19, 2016 =
128
+ * 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.
129
+ * Fix: Array dereference issue with PHP version 5.3. You will no longer get PHP syntax issues while activating the plugin.
130
+ * Administration of the plugin over a secured network (HTTPS) is recommended and not required.
131
+ * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
132
+
133
+ = 1.1 - December 13, 2016 =
134
+ * Fix: Rendering of search results in Apple Safari browser.
135
+
136
+ = 1.0 - December 6, 2016 =
137
+ * Plugin released for beta testing
138
+
139
+ == Upgrade Notice ==
140
+
141
+ = 1.4.2 =
142
+ This update restricts plugin activation to supported PHP versions, and fixes bug of plugin not working with other editors.
143
+
144
+ = 1.4.1 =
145
+ This update includes minor bug fixes.
146
+
147
+ = 1.4 =
148
+ This update includes general performance improvements, and support for text links.
149
+
150
+ = 1.3.2 =
151
+ This update fixes the issue with improper rendering of ads using custom templates. If you are coming from v1.3, you don't need to take a backup of your templates before updating to v1.3.2.
152
+
153
+ = 1.3 =
154
  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.
shortcode/aalb_shortcode.php CHANGED
@@ -21,81 +21,84 @@ and limitations under the License.
21
  * @package AmazonAssociatesLinkBuilder
22
  * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
  */
24
-
25
  class Aalb_Shortcode {
 
 
 
 
 
26
 
27
- protected $paapi_helper;
28
- protected $template_engine;
29
- protected $helper;
30
- protected $tracking_api_helper;
31
- protected $shortcode_helper;
32
-
33
- public function __construct() {
34
- $this->template_engine = new Aalb_Template_Engine();
35
- $this->paapi_helper = new Aalb_Paapi_Helper();
36
- $this->helper = new Aalb_Helper();
37
- $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
38
- $this->shortcode_helper = new Aalb_Shortcode_Helper();
39
- }
40
 
41
- /**
42
- * Add basic styles
43
- *
44
- * @since 1.0.0
45
- */
46
- public function enqueue_styles() {
47
- wp_enqueue_style('aalb_basics_css', AALB_BASICS_CSS );
48
- }
49
 
50
- /**
51
- * The function responsible for rendering the shortcode.
52
- * Makes a GET request and calls the render_xml to render the response.
53
- *
54
- * @since 1.0.0
55
- * @param array $atts Shortcode attribute and values.
56
- * @return HTML Rendered html to display.
57
- */
58
- public function render($atts) {
59
- try {
60
- $shortcode_attributes = $this->get_shortcode_attributes($atts);
 
 
61
 
62
- $validated_link_id = $this->shortcode_helper->get_validated_link_id($shortcode_attributes['link_id']);
63
- $validated_marketplace = $this->shortcode_helper->get_validated_marketplace($shortcode_attributes['marketplace']);
64
- $validated_asins = $this->shortcode_helper->get_validated_asins($shortcode_attributes['asins']);
65
- $validated_template = $this->shortcode_helper->get_validated_template($shortcode_attributes['template']);
66
- $validated_store_id = $this->shortcode_helper->get_validated_store_id($shortcode_attributes['store']);
67
 
68
- $marketplace = $this->shortcode_helper->get_marketplace_endpoint($validated_marketplace);
69
- $url = $this->paapi_helper->get_item_lookup_url($validated_asins, $marketplace, $validated_store_id);
70
- $asins = $this->shortcode_helper->format_asins($validated_asins);
71
- $products_key = $this->helper->build_products_cache_key($asins, $marketplace, $validated_store_id);
72
- $products_template_key = $this->helper->build_template_cache_key($asins, $marketplace, $validated_store_id, $validated_template );
73
 
74
- $this->shortcode_helper->enqueue_template_styles($validated_template);
75
 
76
- return str_replace(array('[[UNIQUE_ID]]'), array(str_replace('.','-',$products_template_key)), $this->template_engine->render($products_template_key, $products_key, $validated_template, $url, $validated_marketplace));
77
- } catch (Exception $e) {
78
- error_log($this->paapi_helper->get_error_message($e->getMessage()));
 
79
  }
80
- }
81
 
82
- /**
83
- * Returns default shortcode attributes if not mentioned
84
- *
85
- * @since 1.0.0
86
- * @param array $atts Shortcode attributes.
87
- * @return array Default shortcode attributes if not mentioned.
88
- */
89
- private function get_shortcode_attributes($atts) {
90
- $shortcode_attributes=shortcode_atts(array(
91
- 'asins' => null,
92
- 'marketplace' => get_option(AALB_DEFAULT_MARKETPLACE),
93
- 'store' => get_option(AALB_DEFAULT_STORE_ID),
94
- 'template' => get_option(AALB_DEFAULT_TEMPLATE),
95
- 'link_id' => null
96
- ),$atts);
97
- return $shortcode_attributes;
98
- }
 
 
 
99
  }
100
 
101
  ?>
21
  * @package AmazonAssociatesLinkBuilder
22
  * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
  */
 
24
  class Aalb_Shortcode {
25
+ protected $paapi_helper;
26
+ protected $template_engine;
27
+ protected $helper;
28
+ protected $tracking_api_helper;
29
+ protected $shortcode_helper;
30
 
31
+ public function __construct() {
32
+ $this->template_engine = new Aalb_Template_Engine();
33
+ $this->paapi_helper = new Aalb_Paapi_Helper();
34
+ $this->helper = new Aalb_Helper();
35
+ $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
36
+ $this->shortcode_helper = new Aalb_Shortcode_Helper();
37
+ }
 
 
 
 
 
 
38
 
39
+ /**
40
+ * Add basic styles
41
+ *
42
+ * @since 1.0.0
43
+ */
44
+ public function enqueue_styles() {
45
+ wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
46
+ }
47
 
48
+ /**
49
+ * The function responsible for rendering the shortcode.
50
+ * Makes a GET request and calls the render_xml to render the response.
51
+ *
52
+ * @since 1.0.0
53
+ *
54
+ * @param array $atts Shortcode attribute and values.
55
+ *
56
+ * @return HTML Rendered html to display.
57
+ */
58
+ public function render( $atts ) {
59
+ try {
60
+ $shortcode_attributes = $this->get_shortcode_attributes( $atts );
61
 
62
+ $validated_link_id = $this->shortcode_helper->get_validated_link_id( $shortcode_attributes['link_id'] );
63
+ $validated_marketplace = $this->shortcode_helper->get_validated_marketplace( $shortcode_attributes['marketplace'] );
64
+ $validated_asins = $this->shortcode_helper->get_validated_asins( $shortcode_attributes['asins'] );
65
+ $validated_template = $this->shortcode_helper->get_validated_template( $shortcode_attributes['template'] );
66
+ $validated_store_id = $this->shortcode_helper->get_validated_store_id( $shortcode_attributes['store'] );
67
 
68
+ $marketplace = $this->shortcode_helper->get_marketplace_endpoint( $validated_marketplace );
69
+ $url = $this->paapi_helper->get_item_lookup_url( $validated_asins, $marketplace, $validated_store_id );
70
+ $asins = $this->shortcode_helper->format_asins( $validated_asins );
71
+ $products_key = $this->helper->build_products_cache_key( $asins, $marketplace, $validated_store_id );
72
+ $products_template_key = $this->helper->build_template_cache_key( $asins, $marketplace, $validated_store_id, $validated_template );
73
 
74
+ $this->shortcode_helper->enqueue_template_styles( $validated_template );
75
 
76
+ return str_replace( array( '[[UNIQUE_ID]]' ), array( str_replace( '.', '-', $products_template_key ) ), $this->template_engine->render( $products_template_key, $products_key, $validated_template, $url, $validated_marketplace ) );
77
+ } catch ( Exception $e ) {
78
+ error_log( $this->paapi_helper->get_error_message( $e->getMessage() ) );
79
+ }
80
  }
 
81
 
82
+ /**
83
+ * Returns default shortcode attributes if not mentioned
84
+ *
85
+ * @since 1.0.0
86
+ *
87
+ * @param array $atts Shortcode attributes.
88
+ *
89
+ * @return array Default shortcode attributes if not mentioned.
90
+ */
91
+ private function get_shortcode_attributes( $atts ) {
92
+ $shortcode_attributes = shortcode_atts( array(
93
+ 'asins' => null,
94
+ 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ),
95
+ 'store' => get_option( AALB_DEFAULT_STORE_ID ),
96
+ 'template' => get_option( AALB_DEFAULT_TEMPLATE ),
97
+ 'link_id' => null
98
+ ), $atts );
99
+
100
+ return $shortcode_attributes;
101
+ }
102
  }
103
 
104
  ?>
shortcode/aalb_shortcode_helper.php CHANGED
@@ -21,156 +21,175 @@ and limitations under the License.
21
  * @package AmazonAssociatesLinkBuilder
22
  * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
  */
24
-
25
  class Aalb_Shortcode_Helper {
26
 
27
- protected $helper;
28
- protected $config_loader;
29
- protected $validation_helper;
30
-
31
- public function __construct() {
32
- $this->helper = new Aalb_Helper();
33
- $this->config_loader = new Aalb_Config_Loader();
34
- $this->validation_helper = new Aalb_Validation_Helper();
35
- }
36
-
37
- /**
38
- * Add CSS for the template
39
- *
40
- * @since 1.0.0
41
- */
42
- public function enqueue_template_styles($template_name) {
43
- $aalb_default_templates = explode(",", AALB_AMAZON_TEMPLATE_NAMES);
44
- if(in_array($template_name, $aalb_default_templates)) {
45
- wp_enqueue_style('aalb_template' . $template_name . '_css', AALB_TEMPLATE_URL . $template_name . '.css' );
46
- } else {
47
- $aalb_template_upload_url = $this->helper->get_template_upload_directory_url();
48
- wp_enqueue_style('aalb_template' . $template_name . '_css', $aalb_template_upload_url . $template_name . '.css' );
49
  }
50
- }
51
-
52
- /**
53
- * Format comma separated asins into hypen separated asins for building key.
54
- * Checks for more spaces and trims it.
55
- *
56
- * @since 1.0.0
57
- * @param string $asins Comma separated asins.
58
- * @return string Hyphen separated asins.
59
- */
60
- public function format_asins($asins) {
61
- return preg_replace('/[ ,]+/', '-', trim($asins));
62
- }
63
-
64
- /**
65
- * Get marketplace endpoint for marketplace abbreviation
66
- *
67
- * @since 1.0.0
68
- * @param string $marketplace_abbr Marketplace Abbreviation from shortcode
69
- * @return string $marketplace_endpoint Marketplace endpoint
70
- */
71
- public function get_marketplace_endpoint($marketplace_abbr) {
72
- $marketplace_endpoint = "";
73
- $aalb_marketplace_names = $this->config_loader->fetch_marketplaces();
74
- $marketplace_endpoint = array_search($marketplace_abbr, $aalb_marketplace_names);
75
- return $marketplace_endpoint;
76
- }
77
-
78
- /**
79
- * Get validated link-id
80
- * Checks if the link id we got from the api is valid or not and returns
81
- * validated link-id. In case of invalid marketplace, it returns empty string.
82
- *
83
- * @since 1.0.0
84
- * @param string $marketplace Marketplace from shortcode
85
- * @return string $validated_template Validated marketplace
86
- */
87
- public function get_validated_link_id($link_id) {
88
- $validated_link_id = $link_id;
89
- if(!$this->validation_helper->validate_link_id($link_id)) {
90
- //If the link id is not valid, return empty string
91
- $validated_link_id = '';
92
  }
93
- return $validated_link_id;
94
- }
95
-
96
- /**
97
- * Get validated marketplace.
98
- * Checks if a marketplace abbreviation from shortcode is valid and returns
99
- * validated marketplace. In case of invalid marketplace, it returns default marketplace.
100
- *
101
- * @since 1.0.0
102
- * @param string $marketplace Marketplace from shortcode
103
- * @return string $validated_template Validated marketplace
104
- */
105
- public function get_validated_marketplace($marketplace) {
106
- //Changing case of the marketplace to upper. Ensures case insensitivity
107
- $validated_marketplace = strtoupper($marketplace);
108
- if(!$this->validation_helper->validate_marketplace($marketplace)) {
109
- //If the marketplace is not valid, return default marketplace
110
- $validated_marketplace = get_option(AALB_DEFAULT_MARKETPLACE);
111
  }
112
- return $validated_marketplace;
113
- }
114
-
115
- /**
116
- * Get validated asin list
117
- * Drops invalid asin from the list
118
- *
119
- * @since 1.0.0
120
- * @param string $asins List of asins from shortcode
121
- * @return string List of validated asins
122
- */
123
- public function get_validated_asins($asins) {
124
- //Creates array of asins in the shortcode
125
- $asins_array = explode(',', $asins);
126
- foreach ($asins_array as $asin) {
127
- if (!$this->validation_helper->validate_asin($asin)) {
128
- //Drop Invalid ASIN out of list of asins
129
- $asins_array = array_diff($asins_array, array($asin));
130
- //Show error message regarding incorrect asin in preview mode only
131
- $this->helper->show_error_in_preview("The ASIN: '" . $asin . "' is invalid.");
132
- }
133
  }
134
- return implode(',',$asins_array);
135
- }
136
-
137
- /**
138
- * Get validated template.
139
- * Checks if a template is valid, returns default template otherwise
140
- *
141
- * @since 1.0.0
142
- * @param string $template Template name from shortcode
143
- * @return string $validated_template Validated template name
144
- */
145
- public function get_validated_template($template) {
146
- $validated_template = $template;
147
- if (!$this->validation_helper->validate_template_name($template)) {
148
- //Return Default template in case of invalid template name
149
- $validated_template = get_option(AALB_DEFAULT_TEMPLATE);
150
- //Show error message regarding incorrect asin in preview mode only
151
- $this->helper->show_error_in_preview("The template: '" . $template . "' is invalid. Using default template '" . $validated_template . "'.");
 
 
152
  }
153
- return $validated_template;
154
- }
155
-
156
- /**
157
- * Get validated store id.
158
- * Checks if a store id is valid, returns default store id otherwise
159
- *
160
- * @since 1.0.0
161
- * @param string $store_id Store ID from shortcode
162
- * @return string $validated_store_id Validated Store ID
163
- */
164
- public function get_validated_store_id($store_id) {
165
- $validated_store_id = $store_id;
166
- if (!$this->validation_helper->validate_store_id($store_id)) {
167
- //Return Default store id in case of invalid store id
168
- $validated_store_id = get_option(AALB_DEFAULT_STORE_ID,AALB_DEFAULT_STORE_ID_NAME);
169
- //Show error message regarding incorrect asin in preview mode only
170
- $this->helper->show_error_in_preview("The Associate tag '" . $store_id . "' is not present in the list of valid tags. Associate tag has been updated to '" . $validated_store_id . "'. Please check your Associate tag selection or contact the administrator to add a new tag.");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  }
172
- return $validated_store_id;
173
- }
174
  }
175
 
176
  ?>
21
  * @package AmazonAssociatesLinkBuilder
22
  * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
  */
 
24
  class Aalb_Shortcode_Helper {
25
 
26
+ protected $helper;
27
+ protected $config_loader;
28
+ protected $validation_helper;
29
+
30
+ public function __construct() {
31
+ $this->helper = new Aalb_Helper();
32
+ $this->config_loader = new Aalb_Config_Loader();
33
+ $this->validation_helper = new Aalb_Validation_Helper();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
+
36
+ /**
37
+ * Add CSS for the template
38
+ *
39
+ * @since 1.0.0
40
+ */
41
+ public function enqueue_template_styles( $template_name ) {
42
+ $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
43
+ if ( in_array( $template_name, $aalb_default_templates ) ) {
44
+ wp_enqueue_style( 'aalb_template' . $template_name . '_css', AALB_TEMPLATE_URL . $template_name . '.css' );
45
+ } else {
46
+ $aalb_template_upload_url = $this->helper->get_template_upload_directory_url();
47
+ wp_enqueue_style( 'aalb_template' . $template_name . '_css', $aalb_template_upload_url . $template_name . '.css' );
48
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
+
51
+ /**
52
+ * Format comma separated asins into hypen separated asins for building key.
53
+ * Checks for more spaces and trims it.
54
+ *
55
+ * @since 1.0.0
56
+ *
57
+ * @param string $asins Comma separated asins.
58
+ *
59
+ * @return string Hyphen separated asins.
60
+ */
61
+ public function format_asins( $asins ) {
62
+ return preg_replace( '/[ ,]+/', '-', trim( $asins ) );
 
 
 
 
 
63
  }
64
+
65
+ /**
66
+ * Get marketplace endpoint for marketplace abbreviation
67
+ *
68
+ * @since 1.0.0
69
+ *
70
+ * @param string $marketplace_abbr Marketplace Abbreviation from shortcode
71
+ *
72
+ * @return string $marketplace_endpoint Marketplace endpoint
73
+ */
74
+ public function get_marketplace_endpoint( $marketplace_abbr ) {
75
+ $marketplace_endpoint = "";
76
+ $aalb_marketplace_names = $this->config_loader->fetch_marketplaces();
77
+ $marketplace_endpoint = array_search( $marketplace_abbr, $aalb_marketplace_names );
78
+
79
+ return $marketplace_endpoint;
 
 
 
 
 
80
  }
81
+
82
+ /**
83
+ * Get validated link-id
84
+ * Checks if the link id we got from the api is valid or not and returns
85
+ * validated link-id. In case of invalid marketplace, it returns empty string.
86
+ *
87
+ * @since 1.0.0
88
+ *
89
+ * @param string $marketplace Marketplace from shortcode
90
+ *
91
+ * @return string $validated_template Validated marketplace
92
+ */
93
+ public function get_validated_link_id( $link_id ) {
94
+ $validated_link_id = $link_id;
95
+ if ( ! $this->validation_helper->validate_link_id( $link_id ) ) {
96
+ //If the link id is not valid, return empty string
97
+ $validated_link_id = '';
98
+ }
99
+
100
+ return $validated_link_id;
101
  }
102
+
103
+ /**
104
+ * Get validated marketplace.
105
+ * Checks if a marketplace abbreviation from shortcode is valid and returns
106
+ * validated marketplace. In case of invalid marketplace, it returns default marketplace.
107
+ *
108
+ * @since 1.0.0
109
+ *
110
+ * @param string $marketplace Marketplace from shortcode
111
+ *
112
+ * @return string $validated_template Validated marketplace
113
+ */
114
+ public function get_validated_marketplace( $marketplace ) {
115
+ //Changing case of the marketplace to upper. Ensures case insensitivity
116
+ $validated_marketplace = strtoupper( $marketplace );
117
+ if ( ! $this->validation_helper->validate_marketplace( $marketplace ) ) {
118
+ //If the marketplace is not valid, return default marketplace
119
+ $validated_marketplace = get_option( AALB_DEFAULT_MARKETPLACE );
120
+ }
121
+
122
+ return $validated_marketplace;
123
+ }
124
+
125
+ /**
126
+ * Get validated asin list
127
+ * Drops invalid asin from the list
128
+ *
129
+ * @since 1.0.0
130
+ *
131
+ * @param string $asins List of asins from shortcode
132
+ *
133
+ * @return string List of validated asins
134
+ */
135
+ public function get_validated_asins( $asins ) {
136
+ //Creates array of asins in the shortcode
137
+ $asins_array = explode( ',', $asins );
138
+ foreach ( $asins_array as $asin ) {
139
+ if ( ! $this->validation_helper->validate_asin( $asin ) ) {
140
+ //Drop Invalid ASIN out of list of asins
141
+ $asins_array = array_diff( $asins_array, array( $asin ) );
142
+ //Show error message regarding incorrect asin in preview mode only
143
+ $this->helper->show_error_in_preview( "The ASIN: '" . $asin . "' is invalid." );
144
+ }
145
+ }
146
+
147
+ return implode( ',', $asins_array );
148
+ }
149
+
150
+ /**
151
+ * Get validated template.
152
+ * Checks if a template is valid, returns default template otherwise
153
+ *
154
+ * @since 1.0.0
155
+ *
156
+ * @param string $template Template name from shortcode
157
+ *
158
+ * @return string $validated_template Validated template name
159
+ */
160
+ public function get_validated_template( $template ) {
161
+ $validated_template = $template;
162
+ if ( ! $this->validation_helper->validate_template_name( $template ) ) {
163
+ //Return Default template in case of invalid template name
164
+ $validated_template = get_option( AALB_DEFAULT_TEMPLATE );
165
+ //Show error message regarding incorrect asin in preview mode only
166
+ $this->helper->show_error_in_preview( "The template: '" . $template . "' is invalid. Using default template '" . $validated_template . "'." );
167
+ }
168
+
169
+ return $validated_template;
170
+ }
171
+
172
+ /**
173
+ * Get validated store id.
174
+ * Checks if a store id is valid, returns default store id otherwise
175
+ *
176
+ * @since 1.0.0
177
+ *
178
+ * @param string $store_id Store ID from shortcode
179
+ *
180
+ * @return string $validated_store_id Validated Store ID
181
+ */
182
+ public function get_validated_store_id( $store_id ) {
183
+ $validated_store_id = $store_id;
184
+ if ( ! $this->validation_helper->validate_store_id( $store_id ) ) {
185
+ //Return Default store id in case of invalid store id
186
+ $validated_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME );
187
+ //Show error message regarding incorrect asin in preview mode only
188
+ $this->helper->show_error_in_preview( "The Associate tag '" . $store_id . "' is not present in the list of valid tags. Associate tag has been updated to '" . $validated_store_id . "'. Please check your Associate tag selection or contact the administrator to add a new tag." );
189
+ }
190
+
191
+ return $validated_store_id;
192
  }
 
 
193
  }
194
 
195
  ?>
shortcode/aalb_shortcode_loader.php CHANGED
@@ -23,80 +23,86 @@ and limitations under the License.
23
  */
24
  class Aalb_Shortcode_Loader {
25
 
26
- public $shortcode_link = null;
27
- public $shortcode_textlink = null;
28
 
29
- /**
30
- * Create only a single instance of the Aalb Shortcode.
31
- * No need to create an instance for rendering each shortcode.
32
- *
33
- * @since 1.0.0
34
- * @return Aalb_Shortcode The instance of Aalb_Shortcode.
35
- */
36
- public function get_amazon_link_shortcode() {
37
- if(is_null($this->shortcode_link)) {
38
- return new Aalb_Shortcode();
39
  }
40
- return $this->shortcode_link;
41
- }
42
 
43
- /**
44
- * Create only a single instance of the Aalb TextLink Shortcode.
45
- * No need to create an instance for rendering each shortcode.
46
- *
47
- * @since 1.4
48
- * @return Aalb_Shortcode_Text The instance of Aalb_Shortcode_Text.
49
- */
50
- public function get_amazon_textlink_shortcode() {
51
- if(is_null($this->shortcode_textlink)) {
52
- return new Aalb_Shortcode_Text();
53
  }
54
- return $this->shortcode_textlink;
55
- }
56
 
57
- /**
58
- * Register shortcode with Wordpress
59
- *
60
- * @since 1.0.0
61
- */
62
- public function add_shortcode() {
63
- add_shortcode(AALB_SHORTCODE_AMAZON_LINK, array($this, 'amazon_link_shortcode_callback'));
64
- add_shortcode(AALB_SHORTCODE_AMAZON_TEXT, array($this, 'amazon_textlink_shortcode_callback'));
65
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
- /**
68
- * Disable shortcode
69
- *
70
- * @since 1.0.0
71
- */
72
- public function remove_shortcode() {
73
- remove_shortcode(AALB_SHORTCODE_AMAZON_LINK);
74
- remove_shortcode(AALB_SHORTCODE_AMAZON_TEXT);
75
- }
 
 
 
 
76
 
77
- /**
78
- * Callback function for rendering amazon_link shortcode
79
- *
80
- *
81
- * @since 1.0.0
82
- * @param array $atts Shortcode attributes and values.
83
- * @return HTML HTML for displaying the templates.
84
- */
85
- public function amazon_link_shortcode_callback($atts) {
86
- return $this->get_amazon_link_shortcode()->render($atts);
87
- }
88
 
89
- /**
90
- * Callback function for rendering amazon_textlink shortcode
91
- *
92
- *
93
- * @since 1.4
94
- * @param array $atts Shortcode attributes and values.
95
- * @return HTML HTML for displaying the templates.
96
- */
97
- public function amazon_textlink_shortcode_callback($atts) {
98
- return $this->get_amazon_textlink_shortcode()->render($atts);
99
- }
100
 
101
  }
102
 
23
  */
24
  class Aalb_Shortcode_Loader {
25
 
26
+ public $shortcode_link = null;
27
+ public $shortcode_textlink = null;
28
 
29
+ /**
30
+ * Register shortcode with Wordpress
31
+ *
32
+ * @since 1.0.0
33
+ */
34
+ public function add_shortcode() {
35
+ add_shortcode( AALB_SHORTCODE_AMAZON_LINK, array( $this, 'amazon_link_shortcode_callback' ) );
36
+ add_shortcode( AALB_SHORTCODE_AMAZON_TEXT, array( $this, 'amazon_textlink_shortcode_callback' ) );
 
 
37
  }
 
 
38
 
39
+ /**
40
+ * Disable shortcode
41
+ *
42
+ * @since 1.0.0
43
+ */
44
+ public function remove_shortcode() {
45
+ remove_shortcode( AALB_SHORTCODE_AMAZON_LINK );
46
+ remove_shortcode( AALB_SHORTCODE_AMAZON_TEXT );
 
 
47
  }
 
 
48
 
49
+ /**
50
+ * Callback function for rendering amazon_link shortcode
51
+ *
52
+ *
53
+ * @since 1.0.0
54
+ *
55
+ * @param array $atts Shortcode attributes and values.
56
+ *
57
+ * @return HTML HTML for displaying the templates.
58
+ */
59
+ public function amazon_link_shortcode_callback( $atts ) {
60
+ return $this->get_amazon_link_shortcode()->render( $atts );
61
+ }
62
+
63
+ /**
64
+ * Create only a single instance of the Aalb Shortcode.
65
+ * No need to create an instance for rendering each shortcode.
66
+ *
67
+ * @since 1.0.0
68
+ * @return Aalb_Shortcode The instance of Aalb_Shortcode.
69
+ */
70
+ public function get_amazon_link_shortcode() {
71
+ if ( is_null( $this->shortcode_link ) ) {
72
+ return new Aalb_Shortcode();
73
+ }
74
+
75
+ return $this->shortcode_link;
76
+ }
77
 
78
+ /**
79
+ * Callback function for rendering amazon_textlink shortcode
80
+ *
81
+ *
82
+ * @since 1.4
83
+ *
84
+ * @param array $atts Shortcode attributes and values.
85
+ *
86
+ * @return HTML HTML for displaying the templates.
87
+ */
88
+ public function amazon_textlink_shortcode_callback( $atts ) {
89
+ return $this->get_amazon_textlink_shortcode()->render( $atts );
90
+ }
91
 
92
+ /**
93
+ * Create only a single instance of the Aalb TextLink Shortcode.
94
+ * No need to create an instance for rendering each shortcode.
95
+ *
96
+ * @since 1.4
97
+ * @return Aalb_Shortcode_Text The instance of Aalb_Shortcode_Text.
98
+ */
99
+ public function get_amazon_textlink_shortcode() {
100
+ if ( is_null( $this->shortcode_textlink ) ) {
101
+ return new Aalb_Shortcode_Text();
102
+ }
103
 
104
+ return $this->shortcode_textlink;
105
+ }
 
 
 
 
 
 
 
 
 
106
 
107
  }
108
 
shortcode/aalb_shortcode_text.php CHANGED
@@ -21,82 +21,83 @@ and limitations under the License.
21
  * @package AmazonAssociatesLinkBuilder
22
  * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
  */
24
-
25
  class Aalb_Shortcode_Text {
26
 
27
- protected $paapi_helper;
28
- protected $template_engine;
29
- protected $helper;
30
- protected $tracking_api_helper;
31
- protected $shortcode_helper;
32
-
33
- public function __construct() {
34
- $this->template_engine = new Aalb_Template_Engine();
35
- $this->paapi_helper = new Aalb_Paapi_Helper();
36
- $this->helper = new Aalb_Helper();
37
- $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
38
- $this->shortcode_helper = new Aalb_Shortcode_Helper();
39
- }
40
-
41
- /**
42
- * Add basic styles
43
- *
44
- * @since 1.4
45
- */
46
- public function enqueue_styles() {
47
- wp_enqueue_style('aalb_basics_css', AALB_BASICS_CSS );
48
- }
49
-
50
- /**
51
- * The function responsible for rendering the shortcode.
52
- * Makes a GET request and calls the render_xml to render the response.
53
- *
54
- * @since 1.4
55
- * @param array $atts Shortcode attribute and values.
56
- * @return HTML Rendered html to display.
57
- */
58
- public function render($atts) {
59
- try {
60
- $shortcode_attributes = $this->get_shortcode_attributes($atts);
61
-
62
- $validated_link_id = $this->shortcode_helper->get_validated_link_id($shortcode_attributes['link_id']);
63
- $validated_marketplace = $this->shortcode_helper->get_validated_marketplace($shortcode_attributes['marketplace']);
64
- $validated_asins = $this->shortcode_helper->get_validated_asins($shortcode_attributes['asin']);
65
- $validated_template = $this->shortcode_helper->get_validated_template($shortcode_attributes['template']);
66
- $validated_store_id = $this->shortcode_helper->get_validated_store_id($shortcode_attributes['store']);
67
- $link_text = $shortcode_attributes['text'];
68
-
69
- $marketplace = $this->shortcode_helper->get_marketplace_endpoint($validated_marketplace);
70
- $url = $this->paapi_helper->get_item_lookup_url($validated_asins, $marketplace, $validated_store_id);
71
- $asins = $this->shortcode_helper->format_asins($validated_asins);
72
- $products_key = $this->helper->build_products_cache_key($asins, $marketplace, $validated_store_id);
73
- $products_template_key = $this->helper->build_template_cache_key($asins, $marketplace, $validated_store_id, $validated_template );
74
-
75
- $this->shortcode_helper->enqueue_template_styles($validated_template);
76
- return str_replace(array('[[UNIQUE_ID]]', '[[Amazon_Link_Text]]'), array(str_replace('.','-',$products_template_key), $link_text), $this->template_engine->render($products_template_key, $products_key, $validated_template, $url, $validated_marketplace));
77
- } catch (Exception $e) {
78
- error_log($this->paapi_helper->get_error_message($e->getMessage()));
79
- }
80
- }
81
-
82
- /**
83
- * Returns default shortcode attributes if not mentioned
84
- *
85
- * @since 1.4
86
- * @param array $atts Shortcode attributes.
87
- * @return array Default shortcode attributes if not mentioned.
88
- */
89
- private function get_shortcode_attributes($atts) {
90
- $shortcode_attributes=shortcode_atts(array(
91
- 'asin' => null,
92
- 'marketplace' => get_option(AALB_DEFAULT_MARKETPLACE),
93
- 'store' => get_option(AALB_DEFAULT_STORE_ID),
94
- 'template' => get_option(AALB_DEFAULT_TEMPLATE),
95
- 'link_id' => null,
96
- 'text' => null
97
- ),$atts);
98
- return $shortcode_attributes;
99
- }
 
 
100
  }
101
 
102
  ?>
21
  * @package AmazonAssociatesLinkBuilder
22
  * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
  */
 
24
  class Aalb_Shortcode_Text {
25
 
26
+ protected $paapi_helper;
27
+ protected $template_engine;
28
+ protected $helper;
29
+ protected $tracking_api_helper;
30
+ protected $shortcode_helper;
31
+
32
+ public function __construct() {
33
+ $this->template_engine = new Aalb_Template_Engine();
34
+ $this->paapi_helper = new Aalb_Paapi_Helper();
35
+ $this->helper = new Aalb_Helper();
36
+ $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
37
+ $this->shortcode_helper = new Aalb_Shortcode_Helper();
38
+ }
39
+
40
+ /**
41
+ * Add basic styles
42
+ *
43
+ * @since 1.4
44
+ */
45
+ public function enqueue_styles() {
46
+ wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
47
+ }
48
+
49
+ /**
50
+ * The function responsible for rendering the shortcode.
51
+ * Makes a GET request and calls the render_xml to render the response.
52
+ *
53
+ * @since 1.4
54
+ *
55
+ * @param array $atts Shortcode attribute and values.
56
+ *
57
+ * @return HTML Rendered html to display.
58
+ */
59
+
60
+ public function render( $atts ) {
61
+ try {
62
+ $shortcode_attributes = $this->get_shortcode_attributes( $atts );
63
+
64
+ $validated_link_id = $this->shortcode_helper->get_validated_link_id( $shortcode_attributes['link_id'] );
65
+ $validated_marketplace = $this->shortcode_helper->get_validated_marketplace( $shortcode_attributes['marketplace'] );
66
+ $validated_asins = $this->shortcode_helper->get_validated_asins( $shortcode_attributes['asin'] );
67
+ $validated_template = $this->shortcode_helper->get_validated_template( $shortcode_attributes['template'] );
68
+ $validated_store_id = $this->shortcode_helper->get_validated_store_id( $shortcode_attributes['store'] );
69
+ $link_text = $shortcode_attributes['text'];
70
+
71
+ $marketplace = $this->shortcode_helper->get_marketplace_endpoint( $validated_marketplace );
72
+ $url = $this->paapi_helper->get_item_lookup_url( $validated_asins, $marketplace, $validated_store_id );
73
+ $asins = $this->shortcode_helper->format_asins( $validated_asins );
74
+ $products_key = $this->helper->build_products_cache_key( $asins, $marketplace, $validated_store_id );
75
+ $products_template_key = $this->helper->build_template_cache_key( $asins, $marketplace, $validated_store_id, $validated_template );
76
+
77
+ $this->shortcode_helper->enqueue_template_styles( $validated_template );
78
+
79
+ return str_replace( array( '[[UNIQUE_ID]]', '[[Amazon_Link_Text]]' ), array( str_replace( '.', '-', $products_template_key ), $link_text ), $this->template_engine->render( $products_template_key, $products_key, $validated_template, $url, $validated_marketplace ) );
80
+ } catch ( Exception $e ) {
81
+ error_log( $this->paapi_helper->get_error_message( $e->getMessage() ) );
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Returns default shortcode attributes if not mentioned
87
+ *w
88
+ * @since 1.4
89
+ *
90
+ * @param array $atts Shortcode attributes.
91
+ *
92
+ * @return array Default shortcode attributes if not mentioned.
93
+ */
94
+ private function get_shortcode_attributes( $atts ) {
95
+ $shortcode_attributes = shortcode_atts( array(
96
+ 'asin' => null, 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ), 'store' => get_option( AALB_DEFAULT_STORE_ID ), 'template' => get_option( AALB_DEFAULT_TEMPLATE ), 'link_id' => null, 'text' => null
97
+ ), $atts );
98
+
99
+ return $shortcode_attributes;
100
+ }
101
  }
102
 
103
  ?>
template/ProductAd.css CHANGED
@@ -1,229 +1,259 @@
1
  .aalb-pa-ad-unit {
2
- /*Enable this border property to have a border around the ad unit*/
3
- /*border: 1px solid #d4d4c4;*/
4
- background: #ffffff;
5
  }
 
6
  /* Actual styles start below */
7
  .aalb-pa-ad-unit {
8
- position: relative;
9
- overflow: hidden;
10
- padding: 22px 40px;
11
  }
 
12
  .aalb-pa-ad-unit * {
13
- box-sizing: content-box;
14
- box-shadow: none;
15
- font-family: Arial, Helvetica, sans-serif;
16
- margin: 0;
17
- margin-bottom: 0;
18
- margin-left: 0;
19
- margin-right: 0;
20
- margin-top: 0;
21
- outline: 0;
22
- padding: 0;
23
- padding-bottom: 0;
24
- padding-left: 0;
25
- padding-right: 0;
26
- padding-top: 0;
27
  }
 
28
  .aalb-pa-ad-unit.pull-left {
29
- float: left;
30
  }
 
31
  .aalb-pa-ad-unit.pull-right {
32
- float: right;
33
  }
 
34
  .aalb-pa-ad-unit.pull-left .aalb-pa-product, .aalb-pa-ad-unit.pull-right .aalb-pa-product {
35
- width: 185px !important;
36
  }
 
37
  .aalb-pa-ad-unit a {
38
- box-shadow: none !important;
39
  }
 
40
  .aalb-pa-ad-unit a:hover {
41
- color: #c45500;
42
  }
 
43
  .aalb-pa-ad-unit .aalb-pa-ad-header {
44
- padding-left: 3px;
45
- padding-bottom: 9px;
46
- font-size: 17px;
47
- font-weight: normal;
48
- color: #111111;
49
  }
 
50
  .aalb-pa-ad-unit .aalb-pa-product-list {
51
- overflow: hidden;
52
  }
 
53
  .aalb-pa-ad-unit .aalb-pa-product {
54
- min-width: 185px;
55
- max-width: 385px;
56
- height: auto !important;
57
- padding-top: 22px;
58
- padding-bottom: 22px;
59
- margin-left: 10px;
60
- margin-right: 10px;
61
- float: left;
62
- list-style: none;
63
- text-align: center;
64
  }
 
65
  .aalb-pa-ad-unit .aalb-pa-product-image {
66
- display: table;
67
- width: 150px;
68
- height: 150px;
69
- margin: 0 auto;
70
- text-align: center;
71
  }
 
72
  .aalb-pa-ad-unit .aalb-pa-product-image-wrapper {
73
- display: table-cell;
74
- vertical-align: middle;
75
  }
 
76
  .aalb-pa-ad-unit .aalb-pa-product-image a {
77
- position: relative;
78
- display: inline-block;
79
- vertical-align: middle;
80
  }
 
81
  .aalb-pa-ad-unit .aalb-pa-product-image img {
82
- max-width: 150px;
83
- max-height: 150px;
84
- vertical-align: bottom;
85
  }
 
86
  .aalb-pa-ad-unit .aalb-pa-percent-off {
87
- display: block;
88
- width: 32px;
89
- height: 27px;
90
- padding-top: 5px;
91
- position: absolute;
92
- top: -16px;
93
- right: -16px;
94
- color: #ffffff;
95
- font-size: 12px;
96
- text-align: center;
97
- -webkit-border-radius: 50%;
98
- -moz-border-radius: 50%;
99
- -ms-border-radius: 50%;
100
- border-radius: 50%;
101
- background-color: #a50200;
102
- background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
103
- background-image: linear-gradient(to bottom, #cb0400, #a50200);
104
  }
 
105
  .aalb-pa-ad-unit.hide-percent-off-badge .aalb-pa-percent-off {
106
- display: none;
107
  }
 
108
  .aalb-pa-ad-unit .aalb-pa-product-details {
109
- display: inline-block;
110
- max-width: 100%;
111
- margin-top: 11px;
112
- text-align: left;
113
  }
 
114
  .aalb-pa-ad-unit .aalb-pa-product-title a {
115
- display: block;
116
- width: 100%;
117
- overflow: hidden;
118
- white-space: nowrap;
119
- text-overflow: ellipsis;
120
- font-size: 13px;
121
- color: #111111;
122
- text-decoration: none;
123
  }
 
124
  .aalb-pa-ad-unit.no-truncate .aalb-pa-product-title a {
125
- text-overflow: initial;
126
- white-space: initial;
127
  }
 
128
  .aalb-pa-ad-unit .aalb-pa-product-offer-price {
129
- font-size: 13px;
130
- color: #111111;
131
  }
 
132
  .aalb-pa-ad-unit .aalb-pa-product-offer-price-value {
133
- color: #AB1700;
134
- font-weight: bold;
135
  }
 
136
  .aalb-pa-ad-unit .aalb-pa-product-list-price {
137
- font-size: 13px;
138
- color: #565656;
139
  }
 
140
  .aalb-pa-ad-unit .aalb-pa-product-list-price-value {
141
- text-decoration: line-through;
142
  }
 
143
  .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-all {
144
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
145
- display: inline-block;
146
- margin-top: -1px;
147
- vertical-align: middle;
148
- background-position: -205px -246px;
149
- width: 47px;
150
- height: 15px;
151
  }
152
 
153
  .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-es {
154
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
155
- display: inline-block;
156
- margin-top: -1px;
157
- vertical-align: middle;
158
- background-position: -205px -274px;
159
- width: 62px;
160
- height: 16px;
161
  }
162
 
163
  .aalb-pa-ad-unit .aalb-pa-product-offer-price,
164
  .aalb-pa-ad-unit .aalb-pa-product-list-price,
165
  .aalb-pa-ad-unit .aalb-pa-product-prime-icon {
166
- display: inline-block;
167
- margin-right: 2px;
168
  }
 
169
  .aalb-pa-ad-unit .aalb-pa-btn-prev,
170
  .aalb-pa-ad-unit .aalb-pa-btn-next {
171
- position: absolute;
172
- top: 50%;
173
- margin-top: -52px;
174
- display: block;
175
- visibility: hidden;
176
- width: 43px;
177
- height: 105px;
178
- z-index: 2;
179
- line-height: 105px;
180
- background: #ffffff;
181
- color: #D0D0D0;
182
- font-size: 35px;
183
- text-align: center;
184
- text-decoration: none;
185
- border: 1px solid #e9e9e9;
186
- -webkit-box-shadow: 0 0 4px #e9e9e9;
187
- box-shadow: 0 0 4px #e9e9e9;
188
  }
 
189
  .aalb-pa-ad-unit .aalb-pa-btn-prev:hover,
190
  .aalb-pa-ad-unit .aalb-pa-btn-next:hover {
191
- color: #999999;
192
  }
 
193
  .aalb-pa-ad-unit .aalb-pa-btn-prev:focus,
194
  .aalb-pa-ad-unit .aalb-pa-btn-next:focus {
195
- outline: none;
196
  }
 
197
  .aalb-pa-ad-unit .aalb-pa-btn-prev {
198
- left: 0;
199
- border-left: 0;
200
- border-top-right-radius: 20px;
201
- border-bottom-right-radius: 20px;
202
  }
 
203
  .aalb-pa-ad-unit .aalb-pa-btn-next {
204
- right: 0;
205
- border-right: 0;
206
- border-top-left-radius: 20px;
207
- border-bottom-left-radius: 20px;
208
  }
 
209
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
210
- .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-all {
211
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
212
- display: inline-block;
213
- margin-top: -1px;
214
- vertical-align: middle;
215
- background-position: -205px -246px;
216
- width: 47px;
217
- height: 15px;
218
- }
219
 
220
- .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-es {
221
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
222
- display: inline-block;
223
- margin-top: -1px;
224
- vertical-align: middle;
225
- background-position: -205px -274px;
226
- width: 62px;
227
- height: 16px;
228
- }
229
  }
1
  .aalb-pa-ad-unit {
2
+ /*Enable this border property to have a border around the ad unit*/
3
+ /*border: 1px solid #d4d4c4;*/
4
+ background: #ffffff;
5
  }
6
+
7
  /* Actual styles start below */
8
  .aalb-pa-ad-unit {
9
+ position: relative;
10
+ overflow: hidden;
11
+ padding: 22px 40px;
12
  }
13
+
14
  .aalb-pa-ad-unit * {
15
+ box-sizing: content-box;
16
+ box-shadow: none;
17
+ font-family: Arial, Helvetica, sans-serif;
18
+ margin: 0;
19
+ margin-bottom: 0;
20
+ margin-left: 0;
21
+ margin-right: 0;
22
+ margin-top: 0;
23
+ outline: 0;
24
+ padding: 0;
25
+ padding-bottom: 0;
26
+ padding-left: 0;
27
+ padding-right: 0;
28
+ padding-top: 0;
29
  }
30
+
31
  .aalb-pa-ad-unit.pull-left {
32
+ float: left;
33
  }
34
+
35
  .aalb-pa-ad-unit.pull-right {
36
+ float: right;
37
  }
38
+
39
  .aalb-pa-ad-unit.pull-left .aalb-pa-product, .aalb-pa-ad-unit.pull-right .aalb-pa-product {
40
+ width: 185px !important;
41
  }
42
+
43
  .aalb-pa-ad-unit a {
44
+ box-shadow: none !important;
45
  }
46
+
47
  .aalb-pa-ad-unit a:hover {
48
+ color: #c45500;
49
  }
50
+
51
  .aalb-pa-ad-unit .aalb-pa-ad-header {
52
+ padding-left: 3px;
53
+ padding-bottom: 9px;
54
+ font-size: 17px;
55
+ font-weight: normal;
56
+ color: #111111;
57
  }
58
+
59
  .aalb-pa-ad-unit .aalb-pa-product-list {
60
+ overflow: hidden;
61
  }
62
+
63
  .aalb-pa-ad-unit .aalb-pa-product {
64
+ min-width: 185px;
65
+ max-width: 385px;
66
+ height: auto !important;
67
+ padding-top: 22px;
68
+ padding-bottom: 22px;
69
+ margin-left: 10px;
70
+ margin-right: 10px;
71
+ float: left;
72
+ list-style: none;
73
+ text-align: center;
74
  }
75
+
76
  .aalb-pa-ad-unit .aalb-pa-product-image {
77
+ display: table;
78
+ width: 150px;
79
+ height: 150px;
80
+ margin: 0 auto;
81
+ text-align: center;
82
  }
83
+
84
  .aalb-pa-ad-unit .aalb-pa-product-image-wrapper {
85
+ display: table-cell;
86
+ vertical-align: middle;
87
  }
88
+
89
  .aalb-pa-ad-unit .aalb-pa-product-image a {
90
+ position: relative;
91
+ display: inline-block;
92
+ vertical-align: middle;
93
  }
94
+
95
  .aalb-pa-ad-unit .aalb-pa-product-image img {
96
+ max-width: 150px;
97
+ max-height: 150px;
98
+ vertical-align: bottom;
99
  }
100
+
101
  .aalb-pa-ad-unit .aalb-pa-percent-off {
102
+ display: block;
103
+ width: 32px;
104
+ height: 27px;
105
+ padding-top: 5px;
106
+ position: absolute;
107
+ top: -16px;
108
+ right: -16px;
109
+ color: #ffffff;
110
+ font-size: 12px;
111
+ text-align: center;
112
+ -webkit-border-radius: 50%;
113
+ -moz-border-radius: 50%;
114
+ -ms-border-radius: 50%;
115
+ border-radius: 50%;
116
+ background-color: #a50200;
117
+ background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
118
+ background-image: linear-gradient(to bottom, #cb0400, #a50200);
119
  }
120
+
121
  .aalb-pa-ad-unit.hide-percent-off-badge .aalb-pa-percent-off {
122
+ display: none;
123
  }
124
+
125
  .aalb-pa-ad-unit .aalb-pa-product-details {
126
+ display: inline-block;
127
+ max-width: 100%;
128
+ margin-top: 11px;
129
+ text-align: left;
130
  }
131
+
132
  .aalb-pa-ad-unit .aalb-pa-product-title a {
133
+ display: block;
134
+ width: 100%;
135
+ overflow: hidden;
136
+ white-space: nowrap;
137
+ text-overflow: ellipsis;
138
+ font-size: 13px;
139
+ color: #111111;
140
+ text-decoration: none;
141
  }
142
+
143
  .aalb-pa-ad-unit.no-truncate .aalb-pa-product-title a {
144
+ text-overflow: initial;
145
+ white-space: initial;
146
  }
147
+
148
  .aalb-pa-ad-unit .aalb-pa-product-offer-price {
149
+ font-size: 13px;
150
+ color: #111111;
151
  }
152
+
153
  .aalb-pa-ad-unit .aalb-pa-product-offer-price-value {
154
+ color: #AB1700;
155
+ font-weight: bold;
156
  }
157
+
158
  .aalb-pa-ad-unit .aalb-pa-product-list-price {
159
+ font-size: 13px;
160
+ color: #565656;
161
  }
162
+
163
  .aalb-pa-ad-unit .aalb-pa-product-list-price-value {
164
+ text-decoration: line-through;
165
  }
166
+
167
  .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-all {
168
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
169
+ display: inline-block;
170
+ margin-top: -1px;
171
+ vertical-align: middle;
172
+ background-position: -205px -246px;
173
+ width: 47px;
174
+ height: 15px;
175
  }
176
 
177
  .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-es {
178
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
179
+ display: inline-block;
180
+ margin-top: -1px;
181
+ vertical-align: middle;
182
+ background-position: -205px -274px;
183
+ width: 62px;
184
+ height: 16px;
185
  }
186
 
187
  .aalb-pa-ad-unit .aalb-pa-product-offer-price,
188
  .aalb-pa-ad-unit .aalb-pa-product-list-price,
189
  .aalb-pa-ad-unit .aalb-pa-product-prime-icon {
190
+ display: inline-block;
191
+ margin-right: 2px;
192
  }
193
+
194
  .aalb-pa-ad-unit .aalb-pa-btn-prev,
195
  .aalb-pa-ad-unit .aalb-pa-btn-next {
196
+ position: absolute;
197
+ top: 50%;
198
+ margin-top: -52px;
199
+ display: block;
200
+ visibility: hidden;
201
+ width: 43px;
202
+ height: 105px;
203
+ z-index: 2;
204
+ line-height: 105px;
205
+ background: #ffffff;
206
+ color: #D0D0D0;
207
+ font-size: 35px;
208
+ text-align: center;
209
+ text-decoration: none;
210
+ border: 1px solid #e9e9e9;
211
+ -webkit-box-shadow: 0 0 4px #e9e9e9;
212
+ box-shadow: 0 0 4px #e9e9e9;
213
  }
214
+
215
  .aalb-pa-ad-unit .aalb-pa-btn-prev:hover,
216
  .aalb-pa-ad-unit .aalb-pa-btn-next:hover {
217
+ color: #999999;
218
  }
219
+
220
  .aalb-pa-ad-unit .aalb-pa-btn-prev:focus,
221
  .aalb-pa-ad-unit .aalb-pa-btn-next:focus {
222
+ outline: none;
223
  }
224
+
225
  .aalb-pa-ad-unit .aalb-pa-btn-prev {
226
+ left: 0;
227
+ border-left: 0;
228
+ border-top-right-radius: 20px;
229
+ border-bottom-right-radius: 20px;
230
  }
231
+
232
  .aalb-pa-ad-unit .aalb-pa-btn-next {
233
+ right: 0;
234
+ border-right: 0;
235
+ border-top-left-radius: 20px;
236
+ border-bottom-left-radius: 20px;
237
  }
238
+
239
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
240
+ .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-all {
241
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
242
+ display: inline-block;
243
+ margin-top: -1px;
244
+ vertical-align: middle;
245
+ background-position: -205px -246px;
246
+ width: 47px;
247
+ height: 15px;
248
+ }
249
 
250
+ .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-es {
251
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
252
+ display: inline-block;
253
+ margin-top: -1px;
254
+ vertical-align: middle;
255
+ background-position: -205px -274px;
256
+ width: 62px;
257
+ height: 16px;
258
+ }
259
  }
template/ProductCarousel.css CHANGED
@@ -1,230 +1,261 @@
1
  .aalb-pc-ad-unit {
2
- /*Enable this border property to have a border around the ad unit*/
3
- /*border: 1px solid #d4d4c4;*/
4
- background: #ffffff;
5
  }
 
6
  /* Actual styles start below */
7
  .aalb-pc-ad-unit {
8
- position: relative;
9
- overflow: hidden;
10
- padding: 22px 40px;
11
  }
 
12
  .aalb-pc-ad-unit * {
13
- box-sizing: content-box;
14
- box-shadow: none;
15
- font-family: Arial, Helvetica, sans-serif;
16
- margin: 0;
17
- margin-bottom: 0;
18
- margin-left: 0;
19
- margin-right: 0;
20
- margin-top: 0;
21
- outline: 0;
22
- padding: 0;
23
- padding-bottom: 0;
24
- padding-left: 0;
25
- padding-right: 0;
26
- padding-top: 0;
27
  }
 
28
  .aalb-pc-ad-unit.pull-left {
29
- float: left;
30
  }
 
31
  .aalb-pc-ad-unit.pull-right {
32
- float: right;
33
  }
 
34
  .aalb-pc-ad-unit.pull-left .aalb-pc-product, .aalb-pc-ad-unit.pull-right .aalb-pc-product {
35
- width: 185px !important;
36
  }
 
37
  .aalb-pc-ad-unit a {
38
- box-shadow: none !important;
39
  }
 
40
  .aalb-pc-ad-unit a:hover {
41
- color: #c45500;
42
  }
 
43
  .aalb-pc-ad-unit .aalb-pc-ad-header {
44
- padding-left: 3px;
45
- padding-bottom: 9px;
46
- font-size: 17px;
47
- font-weight: normal;
48
- color: #111111;
49
  }
 
50
  .aalb-pc-ad-unit .aalb-pc-product-list {
51
- /* Remove the border-top to remove the horizontal line after the Ad Header*/
52
- border-top: 2px solid #f7f7f7;
53
- overflow: hidden;
54
  }
 
55
  .aalb-pc-ad-unit .aalb-pc-product {
56
- min-width: 185px;
57
- max-width: 385px;
58
- height: auto !important;
59
- padding-top: 22px;
60
- padding-bottom: 22px;
61
- margin-left: 10px;
62
- margin-right: 10px;
63
- float: left;
64
- list-style: none;
65
- text-align: center;
66
  }
 
67
  .aalb-pc-ad-unit .aalb-pc-product-image {
68
- display: table;
69
- width: 150px;
70
- height: 150px;
71
- margin: 0 auto;
72
- text-align: center;
73
  }
 
74
  .aalb-pc-ad-unit .aalb-pc-product-image-wrapper {
75
- display: table-cell;
76
- vertical-align: middle;
77
  }
 
78
  .aalb-pc-ad-unit .aalb-pc-product-image a {
79
- position: relative;
80
- display: inline-block;
81
- vertical-align: middle;
82
  }
 
83
  .aalb-pc-ad-unit .aalb-pc-product-image img {
84
- max-width: 150px;
85
- max-height: 150px;
86
- vertical-align: bottom;
87
  }
 
88
  .aalb-pc-ad-unit .aalb-pc-percent-off {
89
- display: block;
90
- width: 32px;
91
- height: 27px;
92
- padding-top: 5px;
93
- position: absolute;
94
- top: -16px;
95
- right: -16px;
96
- color: #ffffff;
97
- font-size: 12px;
98
- text-align: center;
99
- -webkit-border-radius: 50%;
100
- -moz-border-radius: 50%;
101
- -ms-border-radius: 50%;
102
- border-radius: 50%;
103
- background-color: #a50200;
104
- background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
105
- background-image: linear-gradient(to bottom, #cb0400, #a50200);
106
  }
 
107
  .aalb-pc-ad-unit.hide-percent-off-badge .aalb-pc-percent-off {
108
- display: none;
109
  }
 
110
  .aalb-pc-ad-unit .aalb-pc-product-details {
111
- display: inline-block;
112
- max-width: 100%;
113
- margin-top: 11px;
114
- text-align: left;
115
  }
 
116
  .aalb-pc-ad-unit .aalb-pc-product-title a {
117
- display: block;
118
- width: 100%;
119
- overflow: hidden;
120
- white-space: nowrap;
121
- text-overflow: ellipsis;
122
- font-size: 13px;
123
- color: #111111;
124
- text-decoration: none;
125
  }
 
126
  .aalb-pc-ad-unit.no-truncate .aalb-pc-product-title a {
127
- text-overflow: initial;
128
- white-space: initial;
129
  }
 
130
  .aalb-pc-ad-unit .aalb-pc-product-offer-price {
131
- font-size: 13px;
132
- color: #111111;
133
  }
 
134
  .aalb-pc-ad-unit .aalb-pc-product-offer-price-value {
135
- color: #AB1700;
136
- font-weight: bold;
137
  }
 
138
  .aalb-pc-ad-unit .aalb-pc-product-list-price {
139
- font-size: 13px;
140
- color: #565656;
141
  }
 
142
  .aalb-pc-ad-unit .aalb-pc-product-list-price-value {
143
- text-decoration: line-through;
144
  }
 
145
  .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-all {
146
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
147
- display: inline-block;
148
- margin-top: -1px;
149
- vertical-align: middle;
150
- background-position: -205px -246px;
151
- width: 47px;
152
- height: 15px;
153
  }
154
 
155
  .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-es {
156
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
157
- display: inline-block;
158
- margin-top: -1px;
159
- vertical-align: middle;
160
- background-position: -205px -274px;
161
- width: 62px;
162
- height: 16px;
163
  }
 
164
  .aalb-pc-ad-unit .aalb-pc-product-offer-price,
165
  .aalb-pc-ad-unit .aalb-pc-product-list-price,
166
  .aalb-pc-ad-unit .aalb-pc-product-prime-icon {
167
- display: inline-block;
168
- margin-right: 2px;
169
  }
 
170
  .aalb-pc-ad-unit .aalb-pc-btn-prev,
171
  .aalb-pc-ad-unit .aalb-pc-btn-next {
172
- position: absolute;
173
- top: 50%;
174
- margin-top: -52px;
175
- display: block;
176
- visibility: hidden;
177
- width: 43px;
178
- height: 105px;
179
- z-index: 2;
180
- line-height: 105px;
181
- background: #ffffff;
182
- color: #D0D0D0;
183
- font-size: 35px;
184
- text-align: center;
185
- text-decoration: none;
186
- border: 1px solid #e9e9e9;
187
- -webkit-box-shadow: 0 0 4px #e9e9e9;
188
- box-shadow: 0 0 4px #e9e9e9;
189
  }
 
190
  .aalb-pc-ad-unit .aalb-pc-btn-prev:hover,
191
  .aalb-pc-ad-unit .aalb-pc-btn-next:hover {
192
- color: #999999;
193
  }
 
194
  .aalb-pc-ad-unit .aalb-pc-btn-prev:focus,
195
  .aalb-pc-ad-unit .aalb-pc-btn-next:focus {
196
- outline: none;
197
  }
 
198
  .aalb-pc-ad-unit .aalb-pc-btn-prev {
199
- left: 0;
200
- border-left: 0;
201
- border-top-right-radius: 20px;
202
- border-bottom-right-radius: 20px;
203
  }
 
204
  .aalb-pc-ad-unit .aalb-pc-btn-next {
205
- right: 0;
206
- border-right: 0;
207
- border-top-left-radius: 20px;
208
- border-bottom-left-radius: 20px;
209
  }
 
210
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
211
- .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-all {
212
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
213
- display: inline-block;
214
- margin-top: -1px;
215
- vertical-align: middle;
216
- background-position: -205px -246px;
217
- width: 47px;
218
- height: 15px;
219
- }
220
 
221
- .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-es {
222
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
223
- display: inline-block;
224
- margin-top: -1px;
225
- vertical-align: middle;
226
- background-position: -205px -274px;
227
- width: 62px;
228
- height: 16px;
229
- }
230
  }
1
  .aalb-pc-ad-unit {
2
+ /*Enable this border property to have a border around the ad unit*/
3
+ /*border: 1px solid #d4d4c4;*/
4
+ background: #ffffff;
5
  }
6
+
7
  /* Actual styles start below */
8
  .aalb-pc-ad-unit {
9
+ position: relative;
10
+ overflow: hidden;
11
+ padding: 22px 40px;
12
  }
13
+
14
  .aalb-pc-ad-unit * {
15
+ box-sizing: content-box;
16
+ box-shadow: none;
17
+ font-family: Arial, Helvetica, sans-serif;
18
+ margin: 0;
19
+ margin-bottom: 0;
20
+ margin-left: 0;
21
+ margin-right: 0;
22
+ margin-top: 0;
23
+ outline: 0;
24
+ padding: 0;
25
+ padding-bottom: 0;
26
+ padding-left: 0;
27
+ padding-right: 0;
28
+ padding-top: 0;
29
  }
30
+
31
  .aalb-pc-ad-unit.pull-left {
32
+ float: left;
33
  }
34
+
35
  .aalb-pc-ad-unit.pull-right {
36
+ float: right;
37
  }
38
+
39
  .aalb-pc-ad-unit.pull-left .aalb-pc-product, .aalb-pc-ad-unit.pull-right .aalb-pc-product {
40
+ width: 185px !important;
41
  }
42
+
43
  .aalb-pc-ad-unit a {
44
+ box-shadow: none !important;
45
  }
46
+
47
  .aalb-pc-ad-unit a:hover {
48
+ color: #c45500;
49
  }
50
+
51
  .aalb-pc-ad-unit .aalb-pc-ad-header {
52
+ padding-left: 3px;
53
+ padding-bottom: 9px;
54
+ font-size: 17px;
55
+ font-weight: normal;
56
+ color: #111111;
57
  }
58
+
59
  .aalb-pc-ad-unit .aalb-pc-product-list {
60
+ /* Remove the border-top to remove the horizontal line after the Ad Header*/
61
+ border-top: 2px solid #f7f7f7;
62
+ overflow: hidden;
63
  }
64
+
65
  .aalb-pc-ad-unit .aalb-pc-product {
66
+ min-width: 185px;
67
+ max-width: 385px;
68
+ height: auto !important;
69
+ padding-top: 22px;
70
+ padding-bottom: 22px;
71
+ margin-left: 10px;
72
+ margin-right: 10px;
73
+ float: left;
74
+ list-style: none;
75
+ text-align: center;
76
  }
77
+
78
  .aalb-pc-ad-unit .aalb-pc-product-image {
79
+ display: table;
80
+ width: 150px;
81
+ height: 150px;
82
+ margin: 0 auto;
83
+ text-align: center;
84
  }
85
+
86
  .aalb-pc-ad-unit .aalb-pc-product-image-wrapper {
87
+ display: table-cell;
88
+ vertical-align: middle;
89
  }
90
+
91
  .aalb-pc-ad-unit .aalb-pc-product-image a {
92
+ position: relative;
93
+ display: inline-block;
94
+ vertical-align: middle;
95
  }
96
+
97
  .aalb-pc-ad-unit .aalb-pc-product-image img {
98
+ max-width: 150px;
99
+ max-height: 150px;
100
+ vertical-align: bottom;
101
  }
102
+
103
  .aalb-pc-ad-unit .aalb-pc-percent-off {
104
+ display: block;
105
+ width: 32px;
106
+ height: 27px;
107
+ padding-top: 5px;
108
+ position: absolute;
109
+ top: -16px;
110
+ right: -16px;
111
+ color: #ffffff;
112
+ font-size: 12px;
113
+ text-align: center;
114
+ -webkit-border-radius: 50%;
115
+ -moz-border-radius: 50%;
116
+ -ms-border-radius: 50%;
117
+ border-radius: 50%;
118
+ background-color: #a50200;
119
+ background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
120
+ background-image: linear-gradient(to bottom, #cb0400, #a50200);
121
  }
122
+
123
  .aalb-pc-ad-unit.hide-percent-off-badge .aalb-pc-percent-off {
124
+ display: none;
125
  }
126
+
127
  .aalb-pc-ad-unit .aalb-pc-product-details {
128
+ display: inline-block;
129
+ max-width: 100%;
130
+ margin-top: 11px;
131
+ text-align: left;
132
  }
133
+
134
  .aalb-pc-ad-unit .aalb-pc-product-title a {
135
+ display: block;
136
+ width: 100%;
137
+ overflow: hidden;
138
+ white-space: nowrap;
139
+ text-overflow: ellipsis;
140
+ font-size: 13px;
141
+ color: #111111;
142
+ text-decoration: none;
143
  }
144
+
145
  .aalb-pc-ad-unit.no-truncate .aalb-pc-product-title a {
146
+ text-overflow: initial;
147
+ white-space: initial;
148
  }
149
+
150
  .aalb-pc-ad-unit .aalb-pc-product-offer-price {
151
+ font-size: 13px;
152
+ color: #111111;
153
  }
154
+
155
  .aalb-pc-ad-unit .aalb-pc-product-offer-price-value {
156
+ color: #AB1700;
157
+ font-weight: bold;
158
  }
159
+
160
  .aalb-pc-ad-unit .aalb-pc-product-list-price {
161
+ font-size: 13px;
162
+ color: #565656;
163
  }
164
+
165
  .aalb-pc-ad-unit .aalb-pc-product-list-price-value {
166
+ text-decoration: line-through;
167
  }
168
+
169
  .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-all {
170
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
171
+ display: inline-block;
172
+ margin-top: -1px;
173
+ vertical-align: middle;
174
+ background-position: -205px -246px;
175
+ width: 47px;
176
+ height: 15px;
177
  }
178
 
179
  .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-es {
180
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
181
+ display: inline-block;
182
+ margin-top: -1px;
183
+ vertical-align: middle;
184
+ background-position: -205px -274px;
185
+ width: 62px;
186
+ height: 16px;
187
  }
188
+
189
  .aalb-pc-ad-unit .aalb-pc-product-offer-price,
190
  .aalb-pc-ad-unit .aalb-pc-product-list-price,
191
  .aalb-pc-ad-unit .aalb-pc-product-prime-icon {
192
+ display: inline-block;
193
+ margin-right: 2px;
194
  }
195
+
196
  .aalb-pc-ad-unit .aalb-pc-btn-prev,
197
  .aalb-pc-ad-unit .aalb-pc-btn-next {
198
+ position: absolute;
199
+ top: 50%;
200
+ margin-top: -52px;
201
+ display: block;
202
+ visibility: hidden;
203
+ width: 43px;
204
+ height: 105px;
205
+ z-index: 2;
206
+ line-height: 105px;
207
+ background: #ffffff;
208
+ color: #D0D0D0;
209
+ font-size: 35px;
210
+ text-align: center;
211
+ text-decoration: none;
212
+ border: 1px solid #e9e9e9;
213
+ -webkit-box-shadow: 0 0 4px #e9e9e9;
214
+ box-shadow: 0 0 4px #e9e9e9;
215
  }
216
+
217
  .aalb-pc-ad-unit .aalb-pc-btn-prev:hover,
218
  .aalb-pc-ad-unit .aalb-pc-btn-next:hover {
219
+ color: #999999;
220
  }
221
+
222
  .aalb-pc-ad-unit .aalb-pc-btn-prev:focus,
223
  .aalb-pc-ad-unit .aalb-pc-btn-next:focus {
224
+ outline: none;
225
  }
226
+
227
  .aalb-pc-ad-unit .aalb-pc-btn-prev {
228
+ left: 0;
229
+ border-left: 0;
230
+ border-top-right-radius: 20px;
231
+ border-bottom-right-radius: 20px;
232
  }
233
+
234
  .aalb-pc-ad-unit .aalb-pc-btn-next {
235
+ right: 0;
236
+ border-right: 0;
237
+ border-top-left-radius: 20px;
238
+ border-bottom-left-radius: 20px;
239
  }
240
+
241
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
242
+ .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-all {
243
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
244
+ display: inline-block;
245
+ margin-top: -1px;
246
+ vertical-align: middle;
247
+ background-position: -205px -246px;
248
+ width: 47px;
249
+ height: 15px;
250
+ }
251
 
252
+ .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-es {
253
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
254
+ display: inline-block;
255
+ margin-top: -1px;
256
+ vertical-align: middle;
257
+ background-position: -205px -274px;
258
+ width: 62px;
259
+ height: 16px;
260
+ }
261
  }
template/ProductGrid.css CHANGED
@@ -1,230 +1,261 @@
1
  .aalb-pg-ad-unit {
2
- /*Enable this border property to have a border around the ad unit*/
3
- /*border: 1px solid #d4d4c4;*/
4
- background: #ffffff;
5
  }
 
6
  /* Actual styles start below */
7
  .aalb-pg-ad-unit {
8
- position: relative;
9
- overflow: hidden;
10
- padding: 22px 40px;
11
  }
 
12
  .aalb-pg-ad-unit * {
13
- box-sizing: content-box;
14
- box-shadow: none;
15
- font-family: Arial, Helvetica, sans-serif;
16
- margin: 0;
17
- margin-bottom: 0;
18
- margin-left: 0;
19
- margin-right: 0;
20
- margin-top: 0;
21
- outline: 0;
22
- padding: 0;
23
- padding-bottom: 0;
24
- padding-left: 0;
25
- padding-right: 0;
26
- padding-top: 0;
27
  }
 
28
  .aalb-pg-ad-unit.pull-left {
29
- float: left;
30
  }
 
31
  .aalb-pg-ad-unit.pull-right {
32
- float: right;
33
  }
 
34
  .aalb-pg-ad-unit.pull-left .aalb-pg-product, .aalb-pg-ad-unit.pull-right .aalb-pg-product {
35
- width: 185px !important;
36
  }
 
37
  .aalb-pg-ad-unit a {
38
- box-shadow: none !important;
39
  }
 
40
  .aalb-pg-ad-unit a:hover {
41
- color: #c45500;
42
  }
 
43
  .aalb-pg-ad-unit .aalb-pg-ad-header {
44
- padding-left: 3px;
45
- padding-bottom: 9px;
46
- font-size: 17px;
47
- font-weight: normal;
48
- color: #111111;
49
  }
 
50
  .aalb-pg-ad-unit .aalb-pg-product-list {
51
- /* Remove the border-top to remove the horizontal line after the Ad Header*/
52
- border-top: 2px solid #f7f7f7;
53
- overflow: hidden;
54
  }
 
55
  .aalb-pg-ad-unit .aalb-pg-product {
56
- min-width: 185px;
57
- max-width: 385px;
58
- height: auto !important;
59
- padding-top: 22px;
60
- padding-bottom: 22px;
61
- margin-left: 10px;
62
- margin-right: 10px;
63
- float: left;
64
- list-style: none;
65
- text-align: center;
66
  }
 
67
  .aalb-pg-ad-unit .aalb-pg-product-image {
68
- display: table;
69
- width: 150px;
70
- height: 150px;
71
- margin: 0 auto;
72
- text-align: center;
73
  }
 
74
  .aalb-pg-ad-unit .aalb-pg-product-image-wrapper {
75
- display: table-cell;
76
- vertical-align: middle;
77
  }
 
78
  .aalb-pg-ad-unit .aalb-pg-product-image a {
79
- position: relative;
80
- display: inline-block;
81
- vertical-align: middle;
82
  }
 
83
  .aalb-pg-ad-unit .aalb-pg-product-image img {
84
- max-width: 150px;
85
- max-height: 150px;
86
- vertical-align: bottom;
87
  }
 
88
  .aalb-pg-ad-unit .aalb-pg-percent-off {
89
- display: block;
90
- width: 32px;
91
- height: 27px;
92
- padding-top: 5px;
93
- position: absolute;
94
- top: -16px;
95
- right: -16px;
96
- color: #ffffff;
97
- font-size: 12px;
98
- text-align: center;
99
- -webkit-border-radius: 50%;
100
- -moz-border-radius: 50%;
101
- -ms-border-radius: 50%;
102
- border-radius: 50%;
103
- background-color: #a50200;
104
- background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
105
- background-image: linear-gradient(to bottom, #cb0400, #a50200);
106
  }
 
107
  .aalb-pg-ad-unit.hide-percent-off-badge .aalb-pg-percent-off {
108
- display: none;
109
  }
 
110
  .aalb-pg-ad-unit .aalb-pg-product-details {
111
- display: inline-block;
112
- max-width: 100%;
113
- margin-top: 11px;
114
- text-align: left;
115
  }
 
116
  .aalb-pg-ad-unit .aalb-pg-product-title a {
117
- display: block;
118
- width: 100%;
119
- overflow: hidden;
120
- white-space: nowrap;
121
- text-overflow: ellipsis;
122
- font-size: 13px;
123
- color: #111111;
124
- text-decoration: none;
125
  }
 
126
  .aalb-pg-ad-unit.no-truncate .aalb-pg-product-title a {
127
- text-overflow: initial;
128
- white-space: initial;
129
  }
 
130
  .aalb-pg-ad-unit .aalb-pg-product-offer-price {
131
- font-size: 13px;
132
- color: #111111;
133
  }
 
134
  .aalb-pg-ad-unit .aalb-pg-product-offer-price-value {
135
- color: #AB1700;
136
- font-weight: bold;
137
  }
 
138
  .aalb-pg-ad-unit .aalb-pg-product-list-price {
139
- font-size: 13px;
140
- color: #565656;
141
  }
 
142
  .aalb-pg-ad-unit .aalb-pg-product-list-price-value {
143
- text-decoration: line-through;
144
  }
 
145
  .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-all {
146
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
147
- display: inline-block;
148
- margin-top: -1px;
149
- vertical-align: middle;
150
- background-position: -205px -246px;
151
- width: 47px;
152
- height: 16px;
153
  }
154
 
155
  .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-es {
156
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
157
- display: inline-block;
158
- margin-top: -1px;
159
- vertical-align: middle;
160
- background-position: -205px -274px;
161
- width: 62px;
162
- height: 15px;
163
  }
 
164
  .aalb-pg-ad-unit .aalb-pg-product-offer-price,
165
  .aalb-pg-ad-unit .aalb-pg-product-list-price,
166
  .aalb-pg-ad-unit .aalb-pg-product-prime-icon {
167
- display: inline-block;
168
- margin-right: 2px;
169
  }
 
170
  .aalb-pg-ad-unit .aalb-pg-btn-prev,
171
  .aalb-pg-ad-unit .aalb-pg-btn-next {
172
- position: absolute;
173
- top: 50%;
174
- margin-top: -52px;
175
- display: block;
176
- visibility: hidden;
177
- width: 43px;
178
- height: 105px;
179
- z-index: 2;
180
- line-height: 105px;
181
- background: #ffffff;
182
- color: #D0D0D0;
183
- font-size: 35px;
184
- text-align: center;
185
- text-decoration: none;
186
- border: 1px solid #e9e9e9;
187
- -webkit-box-shadow: 0 0 4px #e9e9e9;
188
- box-shadow: 0 0 4px #e9e9e9;
189
  }
 
190
  .aalb-pg-ad-unit .aalb-pg-btn-prev:hover,
191
  .aalb-pg-ad-unit .aalb-pg-btn-next:hover {
192
- color: #999999;
193
  }
 
194
  .aalb-pg-ad-unit .aalb-pg-btn-prev:focus,
195
  .aalb-pg-ad-unit .aalb-pg-btn-next:focus {
196
- outline: none;
197
  }
 
198
  .aalb-pg-ad-unit .aalb-pg-btn-prev {
199
- left: 0;
200
- border-left: 0;
201
- border-top-right-radius: 20px;
202
- border-bottom-right-radius: 20px;
203
  }
 
204
  .aalb-pg-ad-unit .aalb-pg-btn-next {
205
- right: 0;
206
- border-right: 0;
207
- border-top-left-radius: 20px;
208
- border-bottom-left-radius: 20px;
209
  }
 
210
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
211
- .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-all {
212
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
213
- display: inline-block;
214
- margin-top: -1px;
215
- vertical-align: middle;
216
- background-position: -205px -246px;
217
- width: 47px;
218
- height: 15px;
219
- }
220
 
221
- .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-es {
222
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
223
- display: inline-block;
224
- margin-top: -1px;
225
- vertical-align: middle;
226
- background-position: -205px -274px;
227
- width: 62px;
228
- height: 16px;
229
- }
230
  }
1
  .aalb-pg-ad-unit {
2
+ /*Enable this border property to have a border around the ad unit*/
3
+ /*border: 1px solid #d4d4c4;*/
4
+ background: #ffffff;
5
  }
6
+
7
  /* Actual styles start below */
8
  .aalb-pg-ad-unit {
9
+ position: relative;
10
+ overflow: hidden;
11
+ padding: 22px 40px;
12
  }
13
+
14
  .aalb-pg-ad-unit * {
15
+ box-sizing: content-box;
16
+ box-shadow: none;
17
+ font-family: Arial, Helvetica, sans-serif;
18
+ margin: 0;
19
+ margin-bottom: 0;
20
+ margin-left: 0;
21
+ margin-right: 0;
22
+ margin-top: 0;
23
+ outline: 0;
24
+ padding: 0;
25
+ padding-bottom: 0;
26
+ padding-left: 0;
27
+ padding-right: 0;
28
+ padding-top: 0;
29
  }
30
+
31
  .aalb-pg-ad-unit.pull-left {
32
+ float: left;
33
  }
34
+
35
  .aalb-pg-ad-unit.pull-right {
36
+ float: right;
37
  }
38
+
39
  .aalb-pg-ad-unit.pull-left .aalb-pg-product, .aalb-pg-ad-unit.pull-right .aalb-pg-product {
40
+ width: 185px !important;
41
  }
42
+
43
  .aalb-pg-ad-unit a {
44
+ box-shadow: none !important;
45
  }
46
+
47
  .aalb-pg-ad-unit a:hover {
48
+ color: #c45500;
49
  }
50
+
51
  .aalb-pg-ad-unit .aalb-pg-ad-header {
52
+ padding-left: 3px;
53
+ padding-bottom: 9px;
54
+ font-size: 17px;
55
+ font-weight: normal;
56
+ color: #111111;
57
  }
58
+
59
  .aalb-pg-ad-unit .aalb-pg-product-list {
60
+ /* Remove the border-top to remove the horizontal line after the Ad Header*/
61
+ border-top: 2px solid #f7f7f7;
62
+ overflow: hidden;
63
  }
64
+
65
  .aalb-pg-ad-unit .aalb-pg-product {
66
+ min-width: 185px;
67
+ max-width: 385px;
68
+ height: auto !important;
69
+ padding-top: 22px;
70
+ padding-bottom: 22px;
71
+ margin-left: 10px;
72
+ margin-right: 10px;
73
+ float: left;
74
+ list-style: none;
75
+ text-align: center;
76
  }
77
+
78
  .aalb-pg-ad-unit .aalb-pg-product-image {
79
+ display: table;
80
+ width: 150px;
81
+ height: 150px;
82
+ margin: 0 auto;
83
+ text-align: center;
84
  }
85
+
86
  .aalb-pg-ad-unit .aalb-pg-product-image-wrapper {
87
+ display: table-cell;
88
+ vertical-align: middle;
89
  }
90
+
91
  .aalb-pg-ad-unit .aalb-pg-product-image a {
92
+ position: relative;
93
+ display: inline-block;
94
+ vertical-align: middle;
95
  }
96
+
97
  .aalb-pg-ad-unit .aalb-pg-product-image img {
98
+ max-width: 150px;
99
+ max-height: 150px;
100
+ vertical-align: bottom;
101
  }
102
+
103
  .aalb-pg-ad-unit .aalb-pg-percent-off {
104
+ display: block;
105
+ width: 32px;
106
+ height: 27px;
107
+ padding-top: 5px;
108
+ position: absolute;
109
+ top: -16px;
110
+ right: -16px;
111
+ color: #ffffff;
112
+ font-size: 12px;
113
+ text-align: center;
114
+ -webkit-border-radius: 50%;
115
+ -moz-border-radius: 50%;
116
+ -ms-border-radius: 50%;
117
+ border-radius: 50%;
118
+ background-color: #a50200;
119
+ background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
120
+ background-image: linear-gradient(to bottom, #cb0400, #a50200);
121
  }
122
+
123
  .aalb-pg-ad-unit.hide-percent-off-badge .aalb-pg-percent-off {
124
+ display: none;
125
  }
126
+
127
  .aalb-pg-ad-unit .aalb-pg-product-details {
128
+ display: inline-block;
129
+ max-width: 100%;
130
+ margin-top: 11px;
131
+ text-align: left;
132
  }
133
+
134
  .aalb-pg-ad-unit .aalb-pg-product-title a {
135
+ display: block;
136
+ width: 100%;
137
+ overflow: hidden;
138
+ white-space: nowrap;
139
+ text-overflow: ellipsis;
140
+ font-size: 13px;
141
+ color: #111111;
142
+ text-decoration: none;
143
  }
144
+
145
  .aalb-pg-ad-unit.no-truncate .aalb-pg-product-title a {
146
+ text-overflow: initial;
147
+ white-space: initial;
148
  }
149
+
150
  .aalb-pg-ad-unit .aalb-pg-product-offer-price {
151
+ font-size: 13px;
152
+ color: #111111;
153
  }
154
+
155
  .aalb-pg-ad-unit .aalb-pg-product-offer-price-value {
156
+ color: #AB1700;
157
+ font-weight: bold;
158
  }
159
+
160
  .aalb-pg-ad-unit .aalb-pg-product-list-price {
161
+ font-size: 13px;
162
+ color: #565656;
163
  }
164
+
165
  .aalb-pg-ad-unit .aalb-pg-product-list-price-value {
166
+ text-decoration: line-through;
167
  }
168
+
169
  .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-all {
170
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
171
+ display: inline-block;
172
+ margin-top: -1px;
173
+ vertical-align: middle;
174
+ background-position: -205px -246px;
175
+ width: 47px;
176
+ height: 16px;
177
  }
178
 
179
  .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-es {
180
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
181
+ display: inline-block;
182
+ margin-top: -1px;
183
+ vertical-align: middle;
184
+ background-position: -205px -274px;
185
+ width: 62px;
186
+ height: 15px;
187
  }
188
+
189
  .aalb-pg-ad-unit .aalb-pg-product-offer-price,
190
  .aalb-pg-ad-unit .aalb-pg-product-list-price,
191
  .aalb-pg-ad-unit .aalb-pg-product-prime-icon {
192
+ display: inline-block;
193
+ margin-right: 2px;
194
  }
195
+
196
  .aalb-pg-ad-unit .aalb-pg-btn-prev,
197
  .aalb-pg-ad-unit .aalb-pg-btn-next {
198
+ position: absolute;
199
+ top: 50%;
200
+ margin-top: -52px;
201
+ display: block;
202
+ visibility: hidden;
203
+ width: 43px;
204
+ height: 105px;
205
+ z-index: 2;
206
+ line-height: 105px;
207
+ background: #ffffff;
208
+ color: #D0D0D0;
209
+ font-size: 35px;
210
+ text-align: center;
211
+ text-decoration: none;
212
+ border: 1px solid #e9e9e9;
213
+ -webkit-box-shadow: 0 0 4px #e9e9e9;
214
+ box-shadow: 0 0 4px #e9e9e9;
215
  }
216
+
217
  .aalb-pg-ad-unit .aalb-pg-btn-prev:hover,
218
  .aalb-pg-ad-unit .aalb-pg-btn-next:hover {
219
+ color: #999999;
220
  }
221
+
222
  .aalb-pg-ad-unit .aalb-pg-btn-prev:focus,
223
  .aalb-pg-ad-unit .aalb-pg-btn-next:focus {
224
+ outline: none;
225
  }
226
+
227
  .aalb-pg-ad-unit .aalb-pg-btn-prev {
228
+ left: 0;
229
+ border-left: 0;
230
+ border-top-right-radius: 20px;
231
+ border-bottom-right-radius: 20px;
232
  }
233
+
234
  .aalb-pg-ad-unit .aalb-pg-btn-next {
235
+ right: 0;
236
+ border-right: 0;
237
+ border-top-left-radius: 20px;
238
+ border-bottom-left-radius: 20px;
239
  }
240
+
241
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
242
+ .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-all {
243
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
244
+ display: inline-block;
245
+ margin-top: -1px;
246
+ vertical-align: middle;
247
+ background-position: -205px -246px;
248
+ width: 47px;
249
+ height: 15px;
250
+ }
251
 
252
+ .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-es {
253
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
254
+ display: inline-block;
255
+ margin-top: -1px;
256
+ vertical-align: middle;
257
+ background-position: -205px -274px;
258
+ width: 62px;
259
+ height: 16px;
260
+ }
261
  }