1: <?php
  2: 
  3:   4:   5: 
  6: class Quform_Admin_Page_Entries_List extends Quform_Admin_Page_Entries
  7: {
  8:       9:  10: 
 11:     protected $formFactory;
 12: 
 13:      14:  15: 
 16:     protected $options;
 17: 
 18:      19:  20:  21:  22:  23: 
 24:     public function __construct(Quform_ViewFactory $viewFactory, Quform_Repository $repository,
 25:                                 Quform_Form_Factory $formFactory, Quform_Options $options)
 26:     {
 27:         parent::__construct($viewFactory, $repository);
 28: 
 29:         $this->formFactory = $formFactory;
 30:         $this->options = $options;
 31:     }
 32: 
 33:     public function init()
 34:     {
 35:         $this->template = QUFORM_TEMPLATE_PATH . '/admin/entries/list.php';
 36:     }
 37: 
 38:      39:  40: 
 41:     protected function enqueueStyles()
 42:     {
 43:         wp_enqueue_style('qtip2', Quform::url('css/jquery.qtip.min.css'), array(), '3.0.4');
 44:         wp_enqueue_style('spectrum', Quform::adminUrl('css/spectrum.min.css'), array(), '1.8.1');
 45: 
 46:         parent::enqueueStyles();
 47:     }
 48: 
 49:      50:  51: 
 52:     protected function enqueueScripts()
 53:     {
 54:         wp_enqueue_script('jeditable', Quform::adminUrl('js/jquery.jeditable.min.js'), array('jquery'), '2.0.17', true);
 55:         wp_enqueue_script('qtip2', Quform::url('js/jquery.qtip.min.js'), array('jquery'), '3.0.4', true);
 56:         wp_enqueue_script('spectrum', Quform::adminUrl('js/spectrum.min.js'), array(), '1.8.1', true);
 57: 
 58:         parent::enqueueScripts();
 59: 
 60:         wp_enqueue_script('quform-entries-list', Quform::adminUrl('js/entries.list.min.js'), array('jquery', 'jquery-ui-sortable'), QUFORM_VERSION, true);
 61: 
 62:         wp_localize_script('quform-entries-list', 'quformEntriesListL10n', array(
 63:             'singleDeleteEntryMessage' => __('Are you sure you want to delete this entry? All data for this entry will be lost and this cannot be undone.', 'quform'),
 64:             'pluralDeleteEntryMessage' => __('Are you sure you want to delete these entries? All data for these entries will be lost and this cannot be undone.', 'quform'),
 65:             'saveEntriesTableSettingsNonce' => wp_create_nonce('quform_save_entries_table_settings'),
 66:             'entryLabelEditHtml' => $this->getEntryLabelEditHtml()
 67:         ));
 68:     }
 69: 
 70:      71:  72: 
 73:     public function process()
 74:     {
 75:         if ( ! current_user_can('quform_view_entries')) {
 76:             wp_die(__( 'You do not have sufficient permissions to access this page.', 'quform'), 403);
 77:         }
 78: 
 79:         
 80:         $this->processActions();
 81: 
 82:         if (isset($_GET['id']) && Quform::isNonEmptyString($_GET['id'])) {
 83:             $config = $this->repository->getConfig((int) $_GET['id']);
 84: 
 85:             if ($config === null) {
 86:                 wp_die(esc_html__('The form could not be found. Perhaps it was deleted?', 'quform'));
 87:             }
 88:         } else {
 89:             $config = $this->repository->firstConfig();
 90: 
 91:             if ($config === null) {
 92:                 
 93:                 wp_safe_redirect(admin_url('admin.php?page=quform.forms'));
 94:                 exit;
 95:             }
 96:         }
 97: 
 98:         $config['environment'] = 'listEntry';
 99: 
100:         $form = $this->formFactory->create($config);
101: 
102:         $this->addPageMessages();
103: 
104:         $table = new Quform_Entry_List_Table($this, $form, $this->repository, $this->options);
105:         $table->prepare_items();
106: 
107:         $perPage = get_user_meta(get_current_user_id(), 'quform_entries_per_page', true);
108:         if ( ! is_numeric($perPage)) {
109:             $perPage = 20;
110:         }
111: 
112:         $this->view->with(array(
113:             'form' => $form,
114:             'table' => $table,
115:             'perPage' => $perPage,
116:             'labels' => $this->repository->getFormEntryLabels($form->getId())
117:         ));
118: 
119:         add_filter('removable_query_args', array($this, 'removableQueryArgs'));
120:     }
121: 
122:     protected function processActions()
123:     {
124:         $nonce = Quform::get($_GET, '_wpnonce');
125:         $action = null;
126:         $ids = array();
127: 
128:         if (isset($_GET['eid'])) {
129:             $action = Quform::get($_GET, 'action');
130:             $ids = (int) $_GET['eid'];
131:         } elseif (isset($_GET['eids'])) {
132:             $action = $this->getBulkAction();
133:             $ids = (array) Quform::get($_GET, 'eids');
134:             $ids = array_map('intval', $ids);
135:         } elseif (isset($_GET['delete_all'])) {
136:             $action = 'delete_all';
137:         }
138: 
139:         if ($action == null) {
140:             if (Quform::get($_GET, '_wp_http_referer')) {
141:                 wp_safe_redirect(esc_url_raw(remove_query_arg(array('_wp_http_referer', '_wpnonce'), wp_unslash($_SERVER['REQUEST_URI']))));
142:                 exit;
143:             }
144: 
145:             return;
146:         }
147: 
148:         do_action('quform_pre_process_entries_list_action', $action, $ids);
149: 
150:         $returnUrl = remove_query_arg(array('action', 'action2', 'eid', 'eids', 'read', 'unread', 'trashed', 'deleted', 'error'), wp_get_referer());
151: 
152:         switch ($action) {
153:             case 'read':
154:                 $result = $this->processReadAction($ids, $nonce);
155:                 $returnUrl = add_query_arg($result, $returnUrl);
156:                 break;
157:             case 'unread':
158:                 $result = $this->processUnreadAction($ids, $nonce);
159:                 $returnUrl = add_query_arg($result, $returnUrl);
160:                 break;
161:             case 'trash':
162:                 $result = $this->processTrashAction($ids, $nonce);
163:                 $returnUrl = add_query_arg($result, $returnUrl);
164:                 break;
165:             case 'untrash':
166:                 $result = $this->processUntrashAction($ids, $nonce);
167:                 $returnUrl = add_query_arg($result, $returnUrl);
168:                 break;
169:             case 'delete':
170:                 $result = $this->processDeleteAction($ids, $nonce);
171:                 $returnUrl = add_query_arg($result, $returnUrl);
172:                 break;
173:             case 'delete_all':
174:                 $ids = $this->repository->getEntryIdsByStatus((int) Quform::get($_GET, 'id'), 'trash');
175:                 $result = $this->processDeleteAction($ids, $nonce);
176:                 $returnUrl = add_query_arg($result, $returnUrl);
177:                 break;
178:         }
179: 
180:         wp_safe_redirect(esc_url_raw($returnUrl));
181:         exit;
182:     }
183: 
184:     185: 186: 187: 188: 189: 190: 
191:     protected function processReadAction($entryIds, $nonce)
192:     {
193:         if (is_array($entryIds)) {
194:             $nonceAction = 'bulk-qfb-entries';
195:         } else {
196:             $nonceAction = 'quform_read_entry_' . $entryIds;
197:             $entryIds = array($entryIds);
198:         }
199: 
200:         if ( ! $nonce || ! count($entryIds)) {
201:             return array('error' => self::BAD_REQUEST);
202:         }
203: 
204:         if ( ! current_user_can('quform_view_entries')) {
205:             return array('error' => self::NO_PERMISSION);
206:         }
207: 
208:         if ( ! wp_verify_nonce($nonce, $nonceAction)) {
209:             return array('error' => self::NONCE_CHECK_FAILED);
210:         }
211: 
212:         $count = $this->repository->readEntries($entryIds);
213: 
214:         return array('read' => $count);
215:     }
216: 
217:     218: 219: 220: 221: 222: 223: 
224:     protected function processUnreadAction($entryIds, $nonce)
225:     {
226:         if (is_array($entryIds)) {
227:             $nonceAction = 'bulk-qfb-entries';
228:         } else {
229:             $nonceAction = 'quform_unread_entry_' . $entryIds;
230:             $entryIds = array($entryIds);
231:         }
232: 
233:         if ( ! $nonce || ! count($entryIds)) {
234:             return array('error' => self::BAD_REQUEST);
235:         }
236: 
237:         if ( ! current_user_can('quform_view_entries')) {
238:             return array('error' => self::NO_PERMISSION);
239:         }
240: 
241:         if ( ! wp_verify_nonce($nonce, $nonceAction)) {
242:             return array('error' => self::NONCE_CHECK_FAILED);
243:         }
244: 
245:         $count = $this->repository->unreadEntries($entryIds);
246: 
247:         return array('unread' => $count);
248:     }
249: 
250:     251: 252: 253: 254: 255: 256: 
257:     protected function processTrashAction($entryIds, $nonce)
258:     {
259:         if (is_array($entryIds)) {
260:             $nonceAction = 'bulk-qfb-entries';
261:         } else {
262:             $nonceAction = 'quform_trash_entry_' . $entryIds;
263:             $entryIds = array($entryIds);
264:         }
265: 
266:         if ( ! $nonce || ! count($entryIds)) {
267:             return array('error' => self::BAD_REQUEST);
268:         }
269: 
270:         if ( ! current_user_can('quform_delete_entries')) {
271:             return array('error' => self::NO_PERMISSION);
272:         }
273: 
274:         if ( ! wp_verify_nonce($nonce, $nonceAction)) {
275:             return array('error' => self::NONCE_CHECK_FAILED);
276:         }
277: 
278:         $count = $this->repository->trashEntries($entryIds);
279: 
280:         return array('trashed' => $count);
281:     }
282: 
283:     284: 285: 286: 287: 288: 289: 
290:     protected function processUntrashAction($entryIds, $nonce)
291:     {
292:         if (is_array($entryIds)) {
293:             $nonceAction = 'bulk-qfb-entries';
294:         } else {
295:             $nonceAction = 'quform_untrash_entry_' . $entryIds;
296:             $entryIds = array($entryIds);
297:         }
298: 
299:         if ( ! $nonce || ! count($entryIds)) {
300:             return array('error' => self::BAD_REQUEST);
301:         }
302: 
303:         if ( ! current_user_can('quform_delete_entries')) {
304:             return array('error' => self::NO_PERMISSION);
305:         }
306: 
307:         if ( ! wp_verify_nonce($nonce, $nonceAction)) {
308:             return array('error' => self::NONCE_CHECK_FAILED);
309:         }
310: 
311:         $count = $this->repository->untrashEntries($entryIds);
312: 
313:         return array('untrashed' => $count);
314:     }
315: 
316:     317: 318: 319: 320: 321: 322: 
323:     protected function processDeleteAction($entryIds, $nonce)
324:     {
325:         if (is_array($entryIds)) {
326:             $nonceAction = 'bulk-qfb-entries';
327:         } else {
328:             $nonceAction = 'quform_delete_entry_' . $entryIds;
329:             $entryIds = array($entryIds);
330:         }
331: 
332:         if ( ! $nonce || ! count($entryIds)) {
333:             return array('error' => self::BAD_REQUEST);
334:         }
335: 
336:         if ( ! current_user_can('quform_delete_entries')) {
337:             return array('error' => self::NO_PERMISSION);
338:         }
339: 
340:         if ( ! wp_verify_nonce($nonce, $nonceAction)) {
341:             return array('error' => self::NONCE_CHECK_FAILED);
342:         }
343: 
344:         $count = $this->repository->deleteEntries($entryIds);
345: 
346:         return array('deleted' => $count);
347:     }
348: 
349:     350: 351: 352: 353: 
354:     protected function getBulkAction()
355:     {
356:         $action = null;
357: 
358:         $a1 = Quform::get($_GET, 'action', '-1');
359:         $a2 = Quform::get($_GET, 'action2', '-1');
360: 
361:         if ($a1 != '-1') {
362:             $action = $a1;
363:         } elseif ($a2 != '-1') {
364:             $action = $a2;
365:         }
366: 
367:         return $action;
368:     }
369: 
370:     371: 372: 
373:     protected function addPageMessages()
374:     {
375:         $read = (int) Quform::get($_GET, 'read');
376:         if ($read > 0) {
377:             
378:             $this->addMessage('success', sprintf(_n('%s entry marked as read', '%s entries marked as read', $read, 'quform'), number_format_i18n($read)));
379:         }
380: 
381:         $unread = (int) Quform::get($_GET, 'unread');
382:         if ($unread > 0) {
383:             
384:             $this->addMessage('success', sprintf(_n('%s entry marked as unread', '%s entries marked as unread', $unread, 'quform'), number_format_i18n($unread)));
385:         }
386: 
387:         $trashed = (int) Quform::get($_GET, 'trashed');
388:         if ($trashed > 0) {
389:             
390:             $this->addMessage('success', sprintf(_n('%s entry moved to the Trash', '%s entries moved to the Trash', $trashed, 'quform'), number_format_i18n($trashed)));
391:         }
392: 
393:         $untrashed = (int) Quform::get($_GET, 'untrashed');
394:         if ($untrashed > 0) {
395:             
396:             $this->addMessage('success', sprintf(_n('%s entry restored', '%s entries restored', $untrashed, 'quform'), number_format_i18n($untrashed)));
397:         }
398: 
399:         $deleted = (int) Quform::get($_GET, 'deleted');
400:         if ($deleted > 0) {
401:             
402:             $this->addMessage('success', sprintf(_n('%s entry deleted', '%s entries deleted', $deleted, 'quform'), number_format_i18n($deleted)));
403:         }
404: 
405:         switch ((int) Quform::get($_GET, 'error')) {
406:             case self::BAD_REQUEST:
407:                 $this->addMessage('error', __('Bad request.', 'quform'));
408:                 break;
409:             case self::NO_PERMISSION:
410:                 $this->addMessage('error', __('You do not have permission to do this.', 'quform'));
411:                 break;
412:             case self::NONCE_CHECK_FAILED:
413:                 $this->addMessage('error', __('Nonce check failed.', 'quform'));
414:                 break;
415:         }
416:     }
417: 
418:     419: 420: 421: 422: 423: 
424:     public function removableQueryArgs($args)
425:     {
426:         $args[] = 'read';
427:         $args[] = 'unread';
428: 
429:         return $args;
430:     }
431: 
432:     433: 434: 435: 436: 437: 438: 
439:     public function getNavHtml(array $currentForm = null, array $extra = array())
440:     {
441:         $extra[40] = sprintf(
442:             '<div class="qfb-nav-item qfb-nav-page-info"><i class="qfb-nav-page-icon qfb-mdi qfb-mdi-message"></i><span class="qfb-nav-page-title">%s</span></div>',
443:             
444:             Quform::escape(sprintf(__('Entries for %s', 'quform'), $currentForm['name']))
445:         );
446: 
447:         $extra[50] = '<div class="qfb-nav-item qfb-nav-item-right"><a id="qfb-show-entries-table-settings" class="qfb-nav-item-link"><i class="qfb-mdi qfb-mdi-settings"></i></a></div>';
448: 
449:         return parent::getNavHtml($currentForm, $extra);
450:     }
451: 
452:     453: 454: 455: 456: 457: 
458:     public function getEntryLabelEditHtml(array $label = null)
459:     {
460:         $output = sprintf(
461:             '<div class="qfb-entry-label-edit qfb-cf"%s%s>',
462:             is_array($label) ? sprintf(' data-label="%s"', Quform::escape(wp_json_encode($label))) : '',
463:             is_array($label) ? sprintf(' style="background-color: %s;"', Quform::escape($label['color'])) : ''
464:         );
465: 
466:         $output .= sprintf(
467:             '<span class="qfb-entry-label-edit-name" title="%s">%s</span>',
468:             esc_attr__('Click to edit name', 'quform'),
469:             is_array($label) ? Quform::escape($label['name']) : ''
470:         );
471: 
472:         $output .= '<div class="qfb-entry-label-edit-actions">';
473:         $output .= '<span class="qfb-entry-label-edit-action-color"><i class="qfb-mdi qfb-mdi-format_color_fill"></i></span>';
474:         $output .= '<span class="qfb-entry-label-edit-action-duplicate"><i class="qfb-mdi qfb-mdi-content_copy"></i></span>';
475:         $output .= '<span class="qfb-entry-label-edit-action-remove"><i class="qfb-icon qfb-icon-trash"></i></span>';
476:         $output .= '</div></div>';
477: 
478:         return $output;
479:     }
480: }
481: