Version Description
(2020-08-22) = * Fixed: FIle missing issue fixed.
Download this release
Release Info
Developer | wahid0003 |
Plugin | CTX Feed – WooCommerce Product Feed Manager Plugin |
Version | 3.7.4 |
Comparing to | |
See all releases |
Code changes from version 3.7.3 to 3.7.4
README.txt
CHANGED
@@ -5,7 +5,7 @@ Tags:product feed,woocommerce product feed,google shopping feed,google shopping,
|
|
5 |
Requires at least: 3.6
|
6 |
Tested Up To: 5.5
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag: 3.7.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -308,6 +308,9 @@ Using pro version:
|
|
308 |
|
309 |
== Changelog ==
|
310 |
|
|
|
|
|
|
|
311 |
= 3.7.3 (2020-08-22) =
|
312 |
* Added: Category mapping feature added. Option to map store category with merchant category
|
313 |
|
5 |
Requires at least: 3.6
|
6 |
Tested Up To: 5.5
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 3.7.4
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
308 |
|
309 |
== Changelog ==
|
310 |
|
311 |
+
= 3.7.4 (2020-08-22) =
|
312 |
+
* Fixed: FIle missing issue fixed.
|
313 |
+
|
314 |
= 3.7.3 (2020-08-22) =
|
315 |
* Added: Category mapping feature added. Option to map store category with merchant category
|
316 |
|
admin/class-woo-feed-category-list.php
ADDED
@@ -0,0 +1,498 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php ob_start();
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Category List
|
5 |
+
*
|
6 |
+
* @link https://webappick.com/
|
7 |
+
* @since 1.0.0
|
8 |
+
*
|
9 |
+
* @package Woo_Feed_List_Table
|
10 |
+
* @author Ohidul Islam <wahid@webappick.com>
|
11 |
+
*/
|
12 |
+
class Woo_Feed_Category_list extends Woo_Feed_List_Table {
|
13 |
+
|
14 |
+
/** ************************************************************************
|
15 |
+
* Normally we would be querying data from a database and manipulating that
|
16 |
+
* for use in your list table. For this example, we're going to simplify it
|
17 |
+
* slightly and create a pre-built array. Think of this as the data that might
|
18 |
+
* be returned by $wpdb->query()
|
19 |
+
*
|
20 |
+
* In a real-world scenario, you would make your own custom query inside
|
21 |
+
* this class' prepare_items() method.
|
22 |
+
*
|
23 |
+
* @var array
|
24 |
+
**************************************************************************/
|
25 |
+
|
26 |
+
|
27 |
+
/** ************************************************************************
|
28 |
+
* REQUIRED. Set up a constructor that references the parent constructor. We
|
29 |
+
* use the parent reference to set some default configs.
|
30 |
+
***************************************************************************/
|
31 |
+
function __construct() {
|
32 |
+
// Set parent defaults
|
33 |
+
parent::__construct(
|
34 |
+
array(
|
35 |
+
'singular' => __( 'mapping', 'woo-feed' ), // singular name of the listed records
|
36 |
+
'plural' => __( 'mappings', 'woo-feed' ), // plural name of the listed records
|
37 |
+
'ajax' => false, // does this table support ajax?
|
38 |
+
)
|
39 |
+
);
|
40 |
+
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
/** ************************************************************************
|
45 |
+
* Recommended. This method is called when the parent class can't find a method
|
46 |
+
* specifically build for a given column. Generally, it's recommended to include
|
47 |
+
* one method for each column you want to render, keeping your package class
|
48 |
+
* neat and organized. For example, if the class needs to process a column
|
49 |
+
* named 'title', it would first see if a method named $this->column_title()
|
50 |
+
* exists - if it does, that method will be used. If it doesn't, this one will
|
51 |
+
* be used. Generally, you should try to use custom column methods as much as
|
52 |
+
* possible.
|
53 |
+
*
|
54 |
+
* Since we have defined a column_title() method later on, this method doesn't
|
55 |
+
* need to concern itself with any column with a name of 'title'. Instead, it
|
56 |
+
* needs to handle everything else.
|
57 |
+
*
|
58 |
+
* For more detailed insight into how columns are handled, take a look at
|
59 |
+
* WP_List_Table::single_row_columns()
|
60 |
+
*
|
61 |
+
* @param array $item A singular item (one full row's worth of data)
|
62 |
+
* @param array $column_name The name/slug of the column to be processed
|
63 |
+
*
|
64 |
+
* @return string Text or HTML to be placed inside the column <td>
|
65 |
+
**************************************************************************/
|
66 |
+
function column_default( $item, $column_name ) {
|
67 |
+
// return $item[$column_name];
|
68 |
+
$getItem = $item['option_name'];
|
69 |
+
$itemInfo = maybe_unserialize( get_option( $getItem ) );
|
70 |
+
global $plugin_page;
|
71 |
+
switch ( $column_name ) {
|
72 |
+
case 'option_name':
|
73 |
+
return $itemInfo['mappingname'];
|
74 |
+
case 'provider':
|
75 |
+
return $itemInfo['mappingprovider'];
|
76 |
+
case 'view':
|
77 |
+
$edit_nonce = wp_create_nonce( 'wf_edit_mapping' );
|
78 |
+
$delete_nonce = wp_create_nonce( 'wf_delete_mapping' );
|
79 |
+
|
80 |
+
return sprintf(
|
81 |
+
'<a class="button button-primary" href="?page=%s&action=%s&cmapping=%s&_wpnonce=%s">' . __( 'Edit', 'woo-feed' ) . '</a>',
|
82 |
+
esc_attr( $plugin_page ),
|
83 |
+
'edit-mapping',
|
84 |
+
$item['option_name'],
|
85 |
+
$edit_nonce
|
86 |
+
) . ' ' .
|
87 |
+
sprintf(
|
88 |
+
'<a val="?page=%s&action=%s&cmapping=%s&_wpnonce=%s" class="button single-category-delete" style="cursor: pointer;">' . __( 'Delete', 'woo-feed' ) . '</a>',
|
89 |
+
esc_attr( $plugin_page ),
|
90 |
+
'delete-mapping',
|
91 |
+
absint( $item['option_id'] ),
|
92 |
+
$delete_nonce
|
93 |
+
);
|
94 |
+
default:
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/** ************************************************************************
|
101 |
+
* Recommended. This is a custom column method and is responsible for what
|
102 |
+
* is rendered in any column with a name/slug of 'title'. Every time the class
|
103 |
+
* needs to render a column, it first looks for a method named
|
104 |
+
* column_{$column_title} - if it exists, that method is run. If it doesn't
|
105 |
+
* exist, column_default() is called instead.
|
106 |
+
*
|
107 |
+
* This example also illustrates how to implement rollover actions. Actions
|
108 |
+
* should be an associative array formatted as 'slug'=>'link html' - and you
|
109 |
+
* will need to generate the URLs yourself. You could even ensure the links
|
110 |
+
*
|
111 |
+
*
|
112 |
+
* @param array $item A singular item (one full row's worth of data)
|
113 |
+
*
|
114 |
+
* @return string Text to be placed inside the column <td> (movie title only)
|
115 |
+
* *************************************************************************@see WP_List_Table::::single_row_columns()
|
116 |
+
*/
|
117 |
+
function column_option_name( $item ) {
|
118 |
+
global $plugin_page;
|
119 |
+
$edit_nonce = wp_create_nonce( 'wf_edit_mapping' );
|
120 |
+
$delete_nonce = wp_create_nonce( 'wf_delete_mapping' );
|
121 |
+
$actions = array(
|
122 |
+
'edit' => sprintf( '<a href="?page=%s&action=%s&cmapping=%s&_wpnonce=%s">' . __( 'Edit',
|
123 |
+
'woo-feed' ) . '</a>',
|
124 |
+
esc_attr( $plugin_page ),
|
125 |
+
'edit-mapping',
|
126 |
+
$item['option_name'],
|
127 |
+
$edit_nonce ),
|
128 |
+
'delete' => sprintf( '<a val="?page=%s&action=%s&cmapping=%s&_wpnonce=%s" class="single-category-delete" style="cursor: pointer;">' . __( 'Delete',
|
129 |
+
'woo-feed' ) . '</a>',
|
130 |
+
esc_attr( $plugin_page ),
|
131 |
+
'delete-mapping',
|
132 |
+
absint( $item['option_id'] ),
|
133 |
+
$delete_nonce ),
|
134 |
+
);
|
135 |
+
|
136 |
+
|
137 |
+
// Return the title contents
|
138 |
+
$getItem = $item['option_name'];
|
139 |
+
$itemInfo = maybe_unserialize( get_option( $getItem ) );
|
140 |
+
$title = $itemInfo['mappingname'];
|
141 |
+
|
142 |
+
return sprintf( '%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
|
143 |
+
/*$1%s*/
|
144 |
+
$title,
|
145 |
+
/*$2%s*/
|
146 |
+
$item['option_id'],
|
147 |
+
/*$3%s*/
|
148 |
+
$this->row_actions( $actions )
|
149 |
+
);
|
150 |
+
}
|
151 |
+
|
152 |
+
public static function get_mappings() {
|
153 |
+
global $wpdb;
|
154 |
+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
155 |
+
$result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", 'wf_cmapping_%' ), 'ARRAY_A' );
|
156 |
+
|
157 |
+
return $result;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Delete a contact record.
|
162 |
+
*
|
163 |
+
* @param int $id customer ID
|
164 |
+
*
|
165 |
+
* @return false|int
|
166 |
+
*/
|
167 |
+
public static function delete_mapping( $id ) {
|
168 |
+
global $wpdb;
|
169 |
+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
170 |
+
return $wpdb->delete( "{$wpdb->prefix}options", array( 'option_id' => $id ), array( '%d' ) );
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Returns the count of records in the database.
|
175 |
+
*
|
176 |
+
* @return null|string
|
177 |
+
*/
|
178 |
+
public static function record_count() {
|
179 |
+
global $wpdb;
|
180 |
+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
181 |
+
return $wpdb->get_var( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name like %s", 'woo_cmapping_%' ) );
|
182 |
+
}
|
183 |
+
|
184 |
+
/** Text displayed when no contact data is available */
|
185 |
+
public function no_items() {
|
186 |
+
_e( 'No mapping available.', 'woo-feed' );
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
/** ************************************************************************
|
191 |
+
* REQUIRED if displaying checkboxes or using bulk actions! The 'cb' column
|
192 |
+
* is given special treatment when columns are processed. It ALWAYS needs to
|
193 |
+
* have it's own method.
|
194 |
+
*
|
195 |
+
* @param array $item A singular item (one full row's worth of data)
|
196 |
+
*
|
197 |
+
* @return string Text to be placed inside the column <td> (movie title only)
|
198 |
+
* *************************************************************************@see WP_List_Table::::single_row_columns()
|
199 |
+
*/
|
200 |
+
function column_cb( $item ) {
|
201 |
+
return sprintf(
|
202 |
+
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
203 |
+
/*$1%s*/
|
204 |
+
$this->_args['singular'], // Let's simply repurpose the table's singular label ("movie")
|
205 |
+
/*$2%s*/
|
206 |
+
$item['option_id'] // The value of the checkbox should be the record's id
|
207 |
+
);
|
208 |
+
}
|
209 |
+
|
210 |
+
|
211 |
+
function column_name( $item ) {
|
212 |
+
global $plugin_page;
|
213 |
+
$edit_nonce = wp_create_nonce( 'wf_edit_mapping' );
|
214 |
+
$delete_nonce = wp_create_nonce( 'wf_delete_mapping' );
|
215 |
+
$title = '<strong>' . $item['option_name'] . '</strong>';
|
216 |
+
$actions = array(
|
217 |
+
'edit' => sprintf( '<a href="?page=%s&action=%s&cmapping=%s&_wpnonce=%s">' . __( 'Edit', 'woo-feed' ) . '</a>',
|
218 |
+
esc_attr( $plugin_page ),
|
219 |
+
'edit-mapping',
|
220 |
+
absint( $item['option_id'] ),
|
221 |
+
$edit_nonce ),
|
222 |
+
'delete' => sprintf( '<a val="?page=%s&action=%s&cmapping=%s&_wpnonce=%s" class="single-category-delete" style="cursor: pointer;">' . __( 'Delete', 'woo-feed' ) . '</a>',
|
223 |
+
esc_attr( $plugin_page ),
|
224 |
+
'delete-mapping',
|
225 |
+
absint( $item['option_id'] ),
|
226 |
+
$delete_nonce ),
|
227 |
+
);
|
228 |
+
|
229 |
+
return $title . $this->row_actions( $actions );
|
230 |
+
}
|
231 |
+
|
232 |
+
/** ************************************************************************
|
233 |
+
* REQUIRED! This method dictates the table's columns and titles. This should
|
234 |
+
* return an array where the key is the column slug (and class) and the value
|
235 |
+
* is the column's title text. If you need a checkbox for bulk actions, refer
|
236 |
+
* to the $columns array below.
|
237 |
+
*
|
238 |
+
* The 'cb' column is treated differently than the rest. If including a checkbox
|
239 |
+
* column in your table you must create a column_cb() method. If you don't need
|
240 |
+
* bulk actions or checkboxes, simply leave the 'cb' entry out of your array.
|
241 |
+
*
|
242 |
+
* @return array An associative array containing column information: 'slugs'=>'Visible Titles'
|
243 |
+
* *************************************************************************@see WP_List_Table::::single_row_columns()
|
244 |
+
*/
|
245 |
+
function get_columns() {
|
246 |
+
$columns = array(
|
247 |
+
'cb' => '<input type="checkbox" />', // Render a checkbox instead of text
|
248 |
+
'option_name' => __( 'Category Name', 'woo-feed' ),
|
249 |
+
'provider' => __( 'Category Type', 'woo-feed' ),
|
250 |
+
'view' => __( 'Action', 'woo-feed' ),
|
251 |
+
);
|
252 |
+
|
253 |
+
return $columns;
|
254 |
+
}
|
255 |
+
|
256 |
+
|
257 |
+
/** ************************************************************************
|
258 |
+
* Optional. If you want one or more columns to be sortable (ASC/DESC toggle),
|
259 |
+
* you will need to register it here. This should return an array where the
|
260 |
+
* key is the column that needs to be sortable, and the value is db column to
|
261 |
+
* sort by. Often, the key and value will be the same, but this is not always
|
262 |
+
* the case (as the value is a column name from the database, not the list table).
|
263 |
+
*
|
264 |
+
* This method merely defines which columns should be sortable and makes them
|
265 |
+
* clickable - it does not handle the actual sorting. You still need to detect
|
266 |
+
* the ORDERBY and ORDER querystring variables within prepare_items() and sort
|
267 |
+
* your data accordingly (usually by modifying your query).
|
268 |
+
*
|
269 |
+
* @return array An associative array containing all the columns that should be sortable: 'slugs'=>array('data_values',bool)
|
270 |
+
**************************************************************************/
|
271 |
+
function get_sortable_columns() {
|
272 |
+
$sortable_columns = array(
|
273 |
+
'option_name' => array( 'option_name', false ),
|
274 |
+
);
|
275 |
+
|
276 |
+
return $sortable_columns;
|
277 |
+
}
|
278 |
+
|
279 |
+
|
280 |
+
/** ************************************************************************
|
281 |
+
* Optional. If you need to include bulk actions in your list table, this is
|
282 |
+
* the place to define them. Bulk actions are an associative array in the format
|
283 |
+
* 'slug'=>'Visible Title'
|
284 |
+
*
|
285 |
+
* If this method returns an empty value, no bulk action will be rendered. If
|
286 |
+
* you specify any bulk actions, the bulk actions box will be rendered with
|
287 |
+
* the table automatically on display().
|
288 |
+
*
|
289 |
+
* Also note that list tables are not automatically wrapped in <form> elements,
|
290 |
+
* so you will need to create those manually in order for bulk actions to function.
|
291 |
+
*
|
292 |
+
* @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles'
|
293 |
+
**************************************************************************/
|
294 |
+
function get_bulk_actions() {
|
295 |
+
$actions = array(
|
296 |
+
'bulk-delete' => __( 'Delete', 'woo-feed' ),
|
297 |
+
);
|
298 |
+
return $actions;
|
299 |
+
}
|
300 |
+
|
301 |
+
|
302 |
+
/** ************************************************************************
|
303 |
+
* Optional. You can handle your bulk actions anywhere or anyhow you prefer.
|
304 |
+
* For this example package, we will handle it in the class to keep things
|
305 |
+
* clean and organized.
|
306 |
+
*
|
307 |
+
* @see $this->prepare_items()
|
308 |
+
**************************************************************************/
|
309 |
+
public function process_bulk_action() {
|
310 |
+
$nonce = isset( $_REQUEST['_wpnonce'] ) && ! empty( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( $_REQUEST['_wpnonce'] ) : '';
|
311 |
+
// Detect when a bulk action is being triggered...
|
312 |
+
if ( 'delete-mapping' === $this->current_action() ) {
|
313 |
+
// In our file that handles the request, verify the nonce.
|
314 |
+
if ( ! wp_verify_nonce( $nonce, 'wf_delete_mapping' ) ) {
|
315 |
+
// die(_e('You do not have sufficient permission to delete!'));
|
316 |
+
update_option( 'wpf_message', esc_html__( 'Failed To Delete Mapping. You do not have sufficient permission to delete.', 'woo-feed' ), false );
|
317 |
+
wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=error' ) );
|
318 |
+
die();
|
319 |
+
} else {
|
320 |
+
if ( isset( $_GET['cmapping'] ) && self::delete_mapping( absint( $_GET['cmapping'] ) ) ) {
|
321 |
+
update_option( 'wpf_message', esc_html__( 'Mapping Deleted Successfully', 'woo-feed' ), false );
|
322 |
+
wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=success' ) );
|
323 |
+
die();
|
324 |
+
} else {
|
325 |
+
update_option( 'wpf_message', esc_html__( 'Failed To Delete Mapping', 'woo-feed' ), false );
|
326 |
+
wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=error' ) );
|
327 |
+
die();
|
328 |
+
}
|
329 |
+
}
|
330 |
+
}
|
331 |
+
// Detect when a bulk action is being triggered...
|
332 |
+
if ( 'edit-mapping' === $this->current_action() ) {
|
333 |
+
// In our file that handles the request, verify the nonce.
|
334 |
+
if ( ! wp_verify_nonce( $nonce, 'wf_edit_mapping' ) ) {
|
335 |
+
wp_die( esc_html__( 'You do not have sufficient permission to delete!', 'woo-feed' ), 403 );
|
336 |
+
}
|
337 |
+
}
|
338 |
+
|
339 |
+
// If the delete bulk action is triggered
|
340 |
+
if ( ( isset( $_POST['mapping'] ) ) && ( isset( $_POST['action'] ) && 'bulk-delete' == $_POST['action'] ) || ( isset( $_POST['action2'] ) && 'bulk-delete' == $_POST['action2'] ) ) {
|
341 |
+
if ( 'bulk-delete' === $this->current_action() ) {
|
342 |
+
if ( ! wp_verify_nonce( $nonce, 'bulk-' . $this->_args['plural'] ) ) {
|
343 |
+
update_option( 'wpf_message', esc_html__( 'Failed To Delete Mapping. You do not have sufficient permission to delete.', 'woo-feed' ), false );
|
344 |
+
wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=error' ) );
|
345 |
+
die();
|
346 |
+
} else {
|
347 |
+
$delete_ids = array_map( 'absint', $_POST['mapping'] );
|
348 |
+
$delete_ids = array_filter( $delete_ids );
|
349 |
+
// loop over the array of record IDs and delete them
|
350 |
+
if ( ! empty( $delete_ids ) ) {
|
351 |
+
$count = count( $delete_ids );
|
352 |
+
foreach ( $delete_ids as $id ) {
|
353 |
+
self::delete_mapping( $id );
|
354 |
+
}
|
355 |
+
$message = sprintf(
|
356 |
+
/* translators: 1: number of item deleted. */
|
357 |
+
esc_html( _n( '%d Mapping Successfully Deleted.',
|
358 |
+
'%d Mappings Successfully Deleted.',
|
359 |
+
$count,
|
360 |
+
'woo-feed' ) ),
|
361 |
+
$count
|
362 |
+
);
|
363 |
+
update_option( 'wpf_message', $message, false );
|
364 |
+
wp_safe_redirect( admin_url( 'admin.php?page=webappick-feed-category-mapping&wpf_message=success' ) );
|
365 |
+
die();
|
366 |
+
}
|
367 |
+
}
|
368 |
+
}
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
+
|
373 |
+
/** ************************************************************************
|
374 |
+
* REQUIRED! This is where you prepare your data for display. This method will
|
375 |
+
* usually be used to query the database, sort and filter the data, and generally
|
376 |
+
* get it ready to be displayed. At a minimum, we should set $this->items and
|
377 |
+
* $this->set_pagination_args(), although the following properties and methods
|
378 |
+
* are frequently interacted with here...
|
379 |
+
*
|
380 |
+
* @global WPDB $wpdb
|
381 |
+
* @uses $this->_column_headers
|
382 |
+
* @uses $this->items
|
383 |
+
* @uses $this->get_columns()
|
384 |
+
* @uses $this->get_sortable_columns()
|
385 |
+
* @uses $this->get_pagenum()
|
386 |
+
* @uses $this->set_pagination_args()
|
387 |
+
**************************************************************************/
|
388 |
+
function prepare_items() {
|
389 |
+
/**
|
390 |
+
* First, lets decide how many records per page to show
|
391 |
+
*/
|
392 |
+
$per_page = 10;
|
393 |
+
|
394 |
+
|
395 |
+
/**
|
396 |
+
* REQUIRED. Now we need to define our column headers. This includes a complete
|
397 |
+
* array of columns to be displayed (slugs & titles), a list of columns
|
398 |
+
* to keep hidden, and a list of columns that are sortable. Each of these
|
399 |
+
* can be defined in another method (as we've done here) before being
|
400 |
+
* used to build the value for our _column_headers property.
|
401 |
+
*/
|
402 |
+
$columns = $this->get_columns();
|
403 |
+
$hidden = array();
|
404 |
+
$sortable = $this->get_sortable_columns();
|
405 |
+
|
406 |
+
|
407 |
+
/**
|
408 |
+
* REQUIRED. Finally, we build an array to be used by the class for column
|
409 |
+
* headers. The $this->_column_headers property takes an array which contains
|
410 |
+
* 3 other arrays. One for all columns, one for hidden columns, and one
|
411 |
+
* for sortable columns.
|
412 |
+
*/
|
413 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
414 |
+
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Optional. You can handle your bulk actions however you see fit. In this
|
418 |
+
* case, we'll handle them within our package just to keep things clean.
|
419 |
+
*/
|
420 |
+
$this->process_bulk_action();
|
421 |
+
|
422 |
+
|
423 |
+
/**
|
424 |
+
* Instead of querying a database, we're going to fetch the example data
|
425 |
+
* property we created for use in this plugin. This makes this example
|
426 |
+
* package slightly different than one you might build on your own. In
|
427 |
+
* this example, we'll be using array manipulation to sort and paginate
|
428 |
+
* our data. In a real-world implementation, you will probably want to
|
429 |
+
* use sort and pagination data to build a custom query instead, as you'll
|
430 |
+
* be able to use your precisely-queried data immediately.
|
431 |
+
*/
|
432 |
+
$data = $this->get_mappings();
|
433 |
+
|
434 |
+
usort( $data, 'woo_feed_usort_reorder' );
|
435 |
+
|
436 |
+
|
437 |
+
/***********************************************************************
|
438 |
+
* ---------------------------------------------------------------------
|
439 |
+
*
|
440 |
+
* In a real-world situation, this is where you would place your query.
|
441 |
+
*
|
442 |
+
* For information on making queries in WordPress, see this Codex entry:
|
443 |
+
* http://codex.wordpress.org/Class_Reference/wpdb
|
444 |
+
*
|
445 |
+
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
446 |
+
* ---------------------------------------------------------------------
|
447 |
+
*/
|
448 |
+
|
449 |
+
|
450 |
+
/**
|
451 |
+
* REQUIRED for pagination. Let's figure out what page the user is currently
|
452 |
+
* looking at. We'll need this later, so you should always include it in
|
453 |
+
* your own package classes.
|
454 |
+
*/
|
455 |
+
$current_page = $this->get_pagenum();
|
456 |
+
|
457 |
+
/**
|
458 |
+
* REQUIRED for pagination. Let's check how many items are in our data array.
|
459 |
+
* In real-world use, this would be the total number of items in your database,
|
460 |
+
* without filtering. We'll need this later, so you should always include it
|
461 |
+
* in your own package classes.
|
462 |
+
*/
|
463 |
+
$total_items = count( $data );
|
464 |
+
|
465 |
+
|
466 |
+
/**
|
467 |
+
* The WP_List_Table class does not handle pagination for us, so we need
|
468 |
+
* to ensure that the data is trimmed to only the current page. We can use
|
469 |
+
* array_slice() to
|
470 |
+
*/
|
471 |
+
$data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );
|
472 |
+
|
473 |
+
/**
|
474 |
+
* REQUIRED. We also have to register our pagination options & calculations.
|
475 |
+
*/
|
476 |
+
$this->set_pagination_args(
|
477 |
+
array(
|
478 |
+
'total_items' => $total_items,
|
479 |
+
// WE have to calculate the total number of items.
|
480 |
+
'per_page' => $per_page,
|
481 |
+
// WE have to determine how many items to show on a page.
|
482 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
483 |
+
// WE have to calculate the total number of pages.
|
484 |
+
)
|
485 |
+
);
|
486 |
+
|
487 |
+
// $this->set_pagination_args( array(
|
488 |
+
// 'total_items' => $total_items, //WE have to calculate the total number of items
|
489 |
+
// 'per_page' => $per_page //WE have to determine how many items to show on a page
|
490 |
+
// ) );
|
491 |
+
|
492 |
+
/**
|
493 |
+
* REQUIRED. Now we can add our *sorted* data to the items property, where
|
494 |
+
* it can be used by the rest of the class.
|
495 |
+
*/
|
496 |
+
$this->items = $data;
|
497 |
+
}
|
498 |
+
}
|
admin/partials/woo-feed-category-mapping-list.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Category Mapping List View
|
4 |
+
*
|
5 |
+
* @link https://webappick.com/
|
6 |
+
* @since 1.0.0
|
7 |
+
*
|
8 |
+
* @package Woo_Feed
|
9 |
+
* @subpackage Woo_Feed/admin/partial
|
10 |
+
* @author Ohidul Islam <wahid@webappick.com>
|
11 |
+
*/
|
12 |
+
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
die();
|
15 |
+
}
|
16 |
+
global $plugin_page;
|
17 |
+
$myListTable = new Woo_Feed_Category_list();
|
18 |
+
$myListTable->prepare_items();
|
19 |
+
?>
|
20 |
+
<div class="wrap">
|
21 |
+
<h2><?php esc_html_e( 'Category Mapping List', 'woo-feed' ); ?><a href="<?php echo esc_url( admin_url( 'admin.php?page=webappick-feed-category-mapping&action=add-mapping' ) ); ?>" class="page-title-action"><?php esc_html_e( 'Add New Mapping', 'woo-feed' ); ?></a></h2>
|
22 |
+
<?php WPFFWMessage()->displayMessages(); ?>
|
23 |
+
<form id="contact-filter" method="post">
|
24 |
+
<!-- For plugins, we also need to ensure that the form posts back to our current page -->
|
25 |
+
<input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>">
|
26 |
+
<!-- Now we can render the completed list table -->
|
27 |
+
<?php $myListTable->display(); ?>
|
28 |
+
</form>
|
29 |
+
</div>
|
30 |
+
<script type="text/javascript">
|
31 |
+
(function ($) {
|
32 |
+
"use strict";
|
33 |
+
$(document).ready(function () {
|
34 |
+
$('body').find(".single-category-delete").click(function () {
|
35 |
+
if (confirm('<?php esc_html_e( 'Are You Sure to Delete?', 'woo-feed' ); ?>')) {
|
36 |
+
window.location.href = jQuery(this).attr('val');
|
37 |
+
}
|
38 |
+
});
|
39 |
+
|
40 |
+
$('#doaction').click(function () {
|
41 |
+
return confirm('<?php esc_html_e( 'Are You Sure to Delete?', 'woo-feed' ); ?>');
|
42 |
+
});
|
43 |
+
|
44 |
+
$('#doaction2').click(function () {
|
45 |
+
return confirm('<?php esc_html_e( 'Are You Sure to Delete?', 'woo-feed' ); ?>');
|
46 |
+
});
|
47 |
+
});
|
48 |
+
})(jQuery);
|
49 |
+
</script>
|
admin/partials/woo-feed-category-mapping.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Add New Category Mapping View
|
4 |
+
*
|
5 |
+
* @link https://webappick.com/
|
6 |
+
* @since 1.0.0
|
7 |
+
*
|
8 |
+
* @package Woo_Feed
|
9 |
+
* @subpackage Woo_Feed/admin/partial
|
10 |
+
* @author Ohidul Islam <wahid@webappick.com>
|
11 |
+
*/
|
12 |
+
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
die();
|
15 |
+
}
|
16 |
+
|
17 |
+
$wooFeedDropDown = new Woo_Feed_Dropdown();
|
18 |
+
$value = array();
|
19 |
+
if ( isset( $_GET['action'], $_GET['cmapping'] ) ) { // phpcs:ignore
|
20 |
+
$option = get_option( sanitize_text_field( $_GET['cmapping'] ) ); // phpcs:ignore
|
21 |
+
$value = maybe_unserialize( $option );
|
22 |
+
}
|
23 |
+
?>
|
24 |
+
<div class="wrap">
|
25 |
+
<h2><?php esc_html_e( 'Category Mapping', 'woo-feed' ); ?></h2>
|
26 |
+
<?php WPFFWMessage()->displayMessages(); ?>
|
27 |
+
<form action="" name="feed" id="category-mapping-form" method="post" autocomplete="off">
|
28 |
+
<?php wp_nonce_field( 'category-mapping' ); ?>
|
29 |
+
<table class=" widefat fixed" id="cmTable">
|
30 |
+
<tbody>
|
31 |
+
<tr>
|
32 |
+
<td width="30%">
|
33 |
+
<label for="providers"><b><?php esc_html_e( 'Merchant', 'woo-feed' ); ?> <span class="requiredIn">*</span></b></label>
|
34 |
+
</td>
|
35 |
+
<td>
|
36 |
+
<select name="mappingprovider" id="providers" class="generalInput" required>
|
37 |
+
<?php
|
38 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
39 |
+
echo $wooFeedDropDown->merchantsDropdown( isset( $value['mappingprovider'] ) ? $value['mappingprovider'] : '' );
|
40 |
+
?>
|
41 |
+
</select>
|
42 |
+
</td>
|
43 |
+
</tr>
|
44 |
+
<tr>
|
45 |
+
<td><b><?php esc_html_e( 'Mapping Name', 'woo-feed' ); ?><span class="requiredIn">*</span></b></td>
|
46 |
+
<td>
|
47 |
+
<input required value="<?php echo isset( $value['mappingname'] ) ? esc_attr( $value['mappingname'] ) : ''; ?>" name="mappingname" wftitle="<?php esc_attr_e( 'Mapping Name should be unique and don\'t use space. Otherwise it will override the existing Category Mapping. Example: myMappingName or my_mapping_name', 'woo-feed' ); ?>" type="text" class="generalInput wfmasterTooltip">
|
48 |
+
</td>
|
49 |
+
</tr>
|
50 |
+
</tbody>
|
51 |
+
</table>
|
52 |
+
<br/>
|
53 |
+
<table class="table tree widefat fixed ">
|
54 |
+
<thead>
|
55 |
+
<tr>
|
56 |
+
<th><?php esc_html_e( 'Local Category', 'woo-feed' ); ?></th>
|
57 |
+
<th><?php esc_html_e( 'Merchant Category', 'woo-feed' ); ?></th>
|
58 |
+
</tr>
|
59 |
+
</thead>
|
60 |
+
<tbody>
|
61 |
+
<?php woo_feed_render_categories( 0, '', $value ); ?>
|
62 |
+
</tbody>
|
63 |
+
<tfoot>
|
64 |
+
<tr>
|
65 |
+
<td colspan="2">
|
66 |
+
<button name="<?php echo isset( $_GET['action'] ) ? esc_attr( sanitize_text_field( $_GET['action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>" type="submit" class="button button-large button-primary"><?php esc_html_e( 'Save Mapping', 'woo-feed' ); ?></button>
|
67 |
+
</td>
|
68 |
+
</tr>
|
69 |
+
</tfoot>
|
70 |
+
</table>
|
71 |
+
</form>
|
72 |
+
</div>
|
woo-feed.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
* Plugin URI: https://webappick.com/
|
12 |
* Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
|
13 |
*
|
14 |
-
* Version: 3.7.
|
15 |
* Author: WebAppick
|
16 |
* Author URI: https://webappick.com/
|
17 |
* License: GPL v2
|
@@ -39,7 +39,7 @@ if ( ! defined( 'WOO_FEED_FREE_VERSION' ) ) {
|
|
39 |
* @var string
|
40 |
* @since 3.1.6
|
41 |
*/
|
42 |
-
define( 'WOO_FEED_FREE_VERSION', '3.7.
|
43 |
}
|
44 |
|
45 |
if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {
|
11 |
* Plugin URI: https://webappick.com/
|
12 |
* Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
|
13 |
*
|
14 |
+
* Version: 3.7.4
|
15 |
* Author: WebAppick
|
16 |
* Author URI: https://webappick.com/
|
17 |
* License: GPL v2
|
39 |
* @var string
|
40 |
* @since 3.1.6
|
41 |
*/
|
42 |
+
define( 'WOO_FEED_FREE_VERSION', '3.7.4' );
|
43 |
}
|
44 |
|
45 |
if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {
|