class-delete-old-posts-filters.php
3 years ago
class-delete-old-posts-redirects.php
3 years ago
class-delete-old-posts.php
3 years ago
class-enqueue-assets.php
3 years ago
class-delete-old-posts.php
1198 lines
| 1 | <?php |
| 2 | namespace DEL\OLD\Posts\Cls; |
| 3 | |
| 4 | /** |
| 5 | * Make the plugin class. |
| 6 | */ |
| 7 | class Delete_Old_Posts { |
| 8 | |
| 9 | /** |
| 10 | * Hooks init (nothing else) and calls things that need to run right away. |
| 11 | */ |
| 12 | public function __construct(){ |
| 13 | add_action( 'admin_menu', [ $this, 'deloldp_custom_menu_page' ] ); |
| 14 | add_filter( 'plugin_action_links_delete-old-posts/delete-old-posts.php', [ $this, 'deloldp_settings_link' ] ); |
| 15 | |
| 16 | // add scheduled task |
| 17 | add_filter( 'cron_schedules', [ $this, 'deloldp_add_cron_interval' ] ); |
| 18 | add_action( 'deloldp_cron_delete_old_posts', [ $this, 'deloldp_cron_exec' ] ); |
| 19 | if ( ! wp_next_scheduled( 'deloldp_cron_delete_old_posts' ) ) { |
| 20 | wp_schedule_event( time(), 'fifteen_seconds', 'deloldp_cron_delete_old_posts' ); |
| 21 | } |
| 22 | // delete scheduled tasks when deactivated |
| 23 | register_deactivation_hook( plugin_dir_path( dirname( __FILE__ , 1 ) ), [ $this, 'deloldp_deactivate' ] ); |
| 24 | // Not like register_uninstall_hook(), you do NOT have to use a static function. |
| 25 | dop_fs()->add_action('after_uninstall', [ $this, 'deloldp_deleted']); |
| 26 | } |
| 27 | |
| 28 | /** |
| 29 | * add a custom menu in admin menu |
| 30 | */ |
| 31 | function deloldp_custom_menu_page() { |
| 32 | |
| 33 | $deloldp_menu = add_menu_page( |
| 34 | __( 'Delete old posts', 'delete-old-posts' ), |
| 35 | 'Delete old posts', |
| 36 | 'manage_options', |
| 37 | 'delete-old-posts', |
| 38 | array( $this, 'deloldp_PluginPage'), |
| 39 | 'dashicons-trash', |
| 40 | 5 |
| 41 | ); |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * add settings link to plugin in the list of plugins |
| 46 | */ |
| 47 | function deloldp_settings_link( $links ) { |
| 48 | // Build and escape the URL. |
| 49 | $url = esc_url( add_query_arg( |
| 50 | 'page', |
| 51 | 'delete-old-posts', |
| 52 | get_admin_url() . 'admin.php' |
| 53 | ) ); |
| 54 | // Create the link. |
| 55 | $settings_link = "<a href='$url'>" . __( 'Settings' ) . '</a>'; |
| 56 | // Adds the link to the end of the array. |
| 57 | array_push( |
| 58 | $links, |
| 59 | $settings_link |
| 60 | ); |
| 61 | return $links; |
| 62 | } |
| 63 | |
| 64 | /** |
| 65 | * create an alert |
| 66 | */ |
| 67 | function deloldp_makeAlert( $alertText = '', $alertStyle = 'success', $alertClose = 'is-dismissible' ) { |
| 68 | $alert = ' |
| 69 | <div class="notice notice-'.$alertStyle.' '.$alertClose.'"> |
| 70 | <p>' . $alertText . '</p> |
| 71 | </div>'; |
| 72 | |
| 73 | return $alert; |
| 74 | } |
| 75 | |
| 76 | /* |
| 77 | * trim words |
| 78 | */ |
| 79 | private function deloldp_TrimWords($s, $limit=3) { |
| 80 | return preg_replace('/((\w+\W*){'.($limit-1).'}(\w+))(.*)/', '${1}', $s); |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * create a dropdown |
| 85 | */ |
| 86 | public function deloldp_Dropdown() { |
| 87 | ?> |
| 88 | <div x-data="{ open: false }" class="p-6 bg-gray-200 m-3.5"> |
| 89 | <button @click="open = true">Open Dropdown</button> |
| 90 | |
| 91 | <ul |
| 92 | x-show="open" |
| 93 | @click.away="open = false" |
| 94 | x-cloak |
| 95 | > |
| 96 | Dropdown Body |
| 97 | </ul> |
| 98 | </div> |
| 99 | <?php |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * function to display on Plugin Page |
| 104 | */ |
| 105 | public function deloldp_PluginPage() { |
| 106 | |
| 107 | /** |
| 108 | * check if user have the rights to delete posts |
| 109 | */ |
| 110 | if( ! current_user_can( 'delete_posts' ) & ! current_user_can( 'delete_others_posts' ) ) { |
| 111 | esc_html_e("You don't have rights to delete the posts.", "delete-old-posts"); |
| 112 | // exit |
| 113 | return; |
| 114 | } |
| 115 | |
| 116 | global $dop_fs; |
| 117 | |
| 118 | $displayInfoTop = false; $pluginOptionArray = array(); $postDeleteDays = 9999; |
| 119 | $pluginName = basename( plugin_dir_path( dirname( __FILE__ , 1 ) ) ); |
| 120 | $pluginName = ucwords(str_replace("-"," ", $pluginName)); |
| 121 | |
| 122 | /** |
| 123 | * process the post data |
| 124 | */ |
| 125 | if( isset( $_POST ) && !empty($_POST) ){ |
| 126 | if ( ! isset( $_POST['secured-delete-old-posts'] ) |
| 127 | || ! wp_verify_nonce( $_POST['secured-delete-old-posts'], 'start-delete-old-posts' ) |
| 128 | ) { |
| 129 | esc_html__( 'Sorry, the security key did not verify.', 'delete-old-posts'); |
| 130 | exit; |
| 131 | } else { |
| 132 | // process form data |
| 133 | if ( isset($_POST['deloldp-post-days']) && $_POST['deloldp-post-days'] > 0 ) { |
| 134 | // save the desired post date in option |
| 135 | $pluginOptionArray['deloldpDays'] = (int) sanitize_text_field($_POST['deloldp-post-days']); |
| 136 | |
| 137 | if ( $dop_fs->can_use_premium_code() ) { |
| 138 | |
| 139 | // save skiptrash to option |
| 140 | if ( ! isset($_POST['deloldp-post-skiptrash']) ) { |
| 141 | $pluginOptionArray['deloldpSkiptrash'] = 0; |
| 142 | } else if( $_POST['deloldp-post-skiptrash'] == 1 ) { |
| 143 | $pluginOptionArray['deloldpSkiptrash'] = 1; |
| 144 | } |
| 145 | // save number of posts to delete |
| 146 | if ( ! isset($_POST['deloldp-posts-number']) ) { |
| 147 | $pluginOptionArray['deloldpPostsNr'] = 1; |
| 148 | } else if( $_POST['deloldp-posts-number'] > 1 ) { |
| 149 | $pluginOptionArray['deloldpPostsNr'] = (int) sanitize_text_field($_POST['deloldp-posts-number']); |
| 150 | } |
| 151 | |
| 152 | } |
| 153 | |
| 154 | // save redirection to option |
| 155 | if ( ! isset($_POST['deloldp-post-redirect']) ) { |
| 156 | $pluginOptionArray['deloldpRedirect'] = 0; |
| 157 | } else if( $_POST['deloldp-post-redirect'] == 1 ) { |
| 158 | $pluginOptionArray['deloldpRedirect'] = 1; |
| 159 | } |
| 160 | |
| 161 | // save start/ stop deleting posts option |
| 162 | if ( ! isset($_POST['toggledelete']) ) { |
| 163 | $pluginOptionArray['toggledelete'] = 0; |
| 164 | } else if( $_POST['toggledelete'] == 1 ) { |
| 165 | $pluginOptionArray['toggledelete'] = 1; |
| 166 | } |
| 167 | |
| 168 | // save fixed date to option |
| 169 | if ( isset($_POST['deloldp-fix-date']) & isset($_POST['date']) ) $pluginOptionArray['deloldpFixDate'] = sanitize_text_field( $_POST['date'] ); |
| 170 | |
| 171 | // save data into plugin option |
| 172 | $this->saveOption($pluginOptionArray); |
| 173 | } else { |
| 174 | // display info |
| 175 | echo $this->deloldp_makeAlert( esc_html__("Choose a date or specify the number of days for the posts to be deleted!", "delete-old-posts"), "warning", "is-dismissible" ); |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | // get user saved options |
| 181 | $getOptionObject = get_option('deloldp-post-days-option'); |
| 182 | |
| 183 | // display an Info on the top of the page |
| 184 | if (is_object($getOptionObject) && property_exists($getOptionObject, 'params') && property_exists($getOptionObject->params,'deloldpDays')) $postDeleteDays = $getOptionObject->params->deloldpDays; |
| 185 | if (is_object($getOptionObject) && property_exists($getOptionObject, 'params') && property_exists($getOptionObject->params,'toggledelete')) $postToggledelete = $getOptionObject->params->toggledelete; |
| 186 | $postDeleteDaysTime = $this->userDaysToTimestamp(); |
| 187 | |
| 188 | // display info on top only when the post delete days have been set |
| 189 | if( isset($postDeleteDaysTime) && $postDeleteDaysTime > 0) $displayInfoTop = true; |
| 190 | |
| 191 | $infoText = "Hint! Test the list with deleted posts in the \"Filters\" menu. Activate the \"Start deleting the posts\" option below and click \"Save\" when you are ready to start deleting the posts. No posts will be deleted until then."; |
| 192 | if( $displayInfoTop ) { |
| 193 | if( $postDeleteDays > 0 & $postToggledelete == 1 ) { |
| 194 | $timezoneGmtOffset = get_option('gmt_offset'); |
| 195 | $timestampNextCronRun = wp_next_scheduled( 'deloldp_cron_delete_old_posts' ); |
| 196 | $calculateMaxNumberOfDeletedPosts = ( isset($getOptionObject->params->deloldpPostsNr) ) ? ((60/15)*60*24) * $getOptionObject->params->deloldpPostsNr : ((60/15)*60*24); |
| 197 | $infoText = sprintf( __("Posts published on %s %s, %s and before that will be deleted regularly in the background. Up to %d Posts/Day.", "delete-old-posts"), date("F", $postDeleteDaysTime), date("d", $postDeleteDaysTime), date("Y", $postDeleteDaysTime), $calculateMaxNumberOfDeletedPosts ); |
| 198 | $infoText .= '<br />'; |
| 199 | $infoText .= sprintf( __("Next cron job run scheduled on %s.", "delete-old-posts"), gmdate("l jS \of F Y h:i:s A", $timestampNextCronRun + $timezoneGmtOffset * 3600 ) ); |
| 200 | // show warning if post are permanently deleted |
| 201 | if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') ) |
| 202 | if ( $dop_fs->can_use_premium_code() ) { |
| 203 | if ( is_object($getOptionObject->params) && (property_exists($getOptionObject->params, 'deloldpSkiptrash') & $getOptionObject->params->deloldpSkiptrash == 1) ) $infoText .= sprintf( " <span class='text-red-500'>%s.</span>", __('The posts will be permanently deleted', 'delete-old-posts') ); |
| 204 | } |
| 205 | } |
| 206 | // show info on top |
| 207 | echo $this->deloldp_makeAlert( sprintf( __("%s", "delete-old-posts"), $infoText ), "info", "is-dismissible" ); |
| 208 | } |
| 209 | |
| 210 | // check if fixed date selected |
| 211 | $fixDate = false; |
| 212 | if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') ) |
| 213 | if ( $getOptionObject->params->deloldpFixDate != '' ) $fixDate = true; |
| 214 | ?> |
| 215 | |
| 216 | <section x-data="deloldp_Start()" x-init="onstart()"> |
| 217 | <div id="pluginInfo" x-cloak class="bg-green-50 border-t-4 border-green-500 rounded-b text-teal-900 px-4 py-3 shadow-md m-5 relative" role="info"> |
| 218 | <div class="flex"> |
| 219 | <div class="py-1"><svg class="fill-current h-6 w-6 text-teal-500 mr-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z"/></svg></div> |
| 220 | <div> |
| 221 | <p class="font-bold"><?php esc_html_e('Choose a date or specify the number of days for the posts to be deleted.', 'delete-old-posts'); ?></p> |
| 222 | <p class="text-sm"> |
| 223 | <?php esc_html_e('Your posts older than the specified days will be automatically deleted in the background any time the WP Cron runs or someone visits your website.', 'delete-old-posts'); ?> |
| 224 | </p> |
| 225 | </div> |
| 226 | </div> |
| 227 | <button type="button" class="notice-dismiss" @click="dismiss"> |
| 228 | <span class="screen-reader-text"><?php esc_html_e('Dismiss this notice.', 'delete-old-posts'); ?></span> |
| 229 | </button> |
| 230 | </div> |
| 231 | |
| 232 | <form method="post"> |
| 233 | <div class="flex-grow container mx-auto sm:px-4 pt-6 pb-6"> |
| 234 | <div class="bg-white border-t border-b sm:border-l sm:border-r sm:rounded shadow mb-6"> |
| 235 | <div class="border-b px-6"> |
| 236 | <div class="flex justify-between -mb-px"> |
| 237 | <div class=" text-blue-dark py-4 text-lg"> |
| 238 | <?php esc_html_e('Delete Old Posts automatically', 'delete-old-posts'); ?> |
| 239 | </div> |
| 240 | <div class="flex text-sm"> |
| 241 | <div class="py-4 text-grey-dark border-b border-transparent hover:border-grey-dark mr-3"> |
| 242 | <span class="dashicons dashicons-trash"></span> |
| 243 | <span class="dashicons dashicons-image-rotate"></span> |
| 244 | </div> |
| 245 | </div> |
| 246 | </div> |
| 247 | </div> |
| 248 | <div class="lg:flex"> |
| 249 | <div class="lg:w-1/2 text-center py-8"> |
| 250 | <div class="md:border-r md:border-b md:pb-6 lg:border-b-0"> |
| 251 | <div class="m-2 text-base"> |
| 252 | <?php esc_html_e('Delete Post older than:', 'delete-old-posts'); ?> |
| 253 | <input |
| 254 | type="number" |
| 255 | size="5" |
| 256 | name="deloldp-post-days" |
| 257 | id="deloldpDays" |
| 258 | x-on:input.debounce.1750="checkDays($event.target.value)" |
| 259 | class="w-20" |
| 260 | <?php |
| 261 | if( ! $fixDate ){ |
| 262 | if( is_object($getOptionObject) && property_exists($getOptionObject,'params') ) |
| 263 | if ( $getOptionObject->params->deloldpDays > 0 ) echo " value='" . $getOptionObject->params->deloldpDays . "'"; |
| 264 | } else { |
| 265 | // get the number of days between two dates |
| 266 | $fixDateTimestamp = strtotime( $getOptionObject->params->deloldpFixDate ); |
| 267 | $datediff = time() - $fixDateTimestamp; |
| 268 | echo " value='" . round( $datediff / (60 * 60 * 24) ) . "'"; |
| 269 | } |
| 270 | ?> |
| 271 | /> |
| 272 | <?php |
| 273 | esc_html_e('days.', 'delete-old-posts'); |
| 274 | ?> |
| 275 | <span |
| 276 | class="dashicons dashicons-editor-help has-tooltip" |
| 277 | x-on:mouseover="tooltip = true" |
| 278 | x-on:mouseleave="tooltip = false" |
| 279 | > |
| 280 | <span class='tooltip rounded shadow-lg bg-gray-100 p-3 text-sm font-sans -mt-8 text-left max-w-md'> |
| 281 | <?php |
| 282 | printf( __('Your posts published before the %s, will be automatically deleted in the background any time the WP Cron runs or someone visits your website.', 'delete-old-posts'), '<strong>specified days</strong>' ); |
| 283 | ?> |
| 284 | </span> |
| 285 | </span> |
| 286 | </div> |
| 287 | <div class="m-2 text-gray-500"> |
| 288 | <?php esc_html_e("Choose the number of ", "delete-old-posts")?> |
| 289 | <select |
| 290 | id="deloldp-post-months" |
| 291 | name="deloldp-post-months" |
| 292 | x-on:change="calculateDaysInMonths($event.target.value)" |
| 293 | > |
| 294 | <option value="" selected="selected"><?php esc_html_e("months", "delete-old-posts")?></option> |
| 295 | <option value="1">1</option> |
| 296 | <option value="2">2</option> |
| 297 | <option value="3">3</option> |
| 298 | <option value="4">4</option> |
| 299 | <option value="5">5</option> |
| 300 | <option value="6">6</option> |
| 301 | <option value="7">7</option> |
| 302 | <option value="8">8</option> |
| 303 | <option value="9">9</option> |
| 304 | <option value="10">10</option> |
| 305 | <option value="11">11</option> |
| 306 | <option value="12">12</option> |
| 307 | </select> |
| 308 | <?php esc_html_e(' to calculate the number of days automatically,', 'delete-old-posts'); ?> |
| 309 | <!-- <span class="dashicons dashicons-arrow-up-alt cursor-pointer" x-on:click="copyDays()"></span> --> |
| 310 | <span id="daysInXMonths" class="hidden"></span> |
| 311 | <?php // esc_html_e('Days', 'delete-old-posts'); ?> |
| 312 | <!-- <span class="text-xs cursor-pointer" x-on:click="copyDays()"><?php esc_html_e('Click to copy', 'delete-old-posts'); ?></span> --> |
| 313 | </div> |
| 314 | <div class="m-2"> |
| 315 | <div x-data="app()" x-init="[initDate(), getNoOfDays()]" x-cloak> |
| 316 | <div class="container mx-auto"> |
| 317 | <div class="mx-auto w-64"> |
| 318 | <label for="datepicker" class="mb-1 text-gray-500 block"> |
| 319 | <?php esc_html_e( "or select a date to calculate days in the past automatically:", "delete-old-posts" ); ?> |
| 320 | </label> |
| 321 | <div class="relative"> |
| 322 | <input type="hidden" name="date" x-ref="date" :value="datepickerValue" /> |
| 323 | <input type="text" x-on:click="showDatepicker = !showDatepicker" x-model="datepickerValue" x-on:keydown.escape="showDatepicker = false" class="w-full pl-4 pr-10 py-3 !bg-white leading-none rounded-lg shadow-sm focus:outline-none text-gray-600 font-medium focus:ring focus:ring-blue-600 focus:ring-opacity-50" placeholder="<?php esc_html__("Select date", "delete-old-posts"); ?>" readonly /> |
| 324 | |
| 325 | <div class="absolute top-0 right-0 px-3 py-1"> |
| 326 | <svg class="h-6 w-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 327 | <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> |
| 328 | </svg> |
| 329 | </div> |
| 330 | |
| 331 | <!-- <div x-text="no_of_days.length"></div> |
| 332 | <div x-text="32 - new Date(year, month, 32).getDate()"></div> |
| 333 | <div x-text="new Date(year, month).getDay()"></div> --> |
| 334 | |
| 335 | <div class="bg-white mt-12 rounded-lg shadow p-4 absolute top-0 left-0" style="width: 17rem" x-show.transition="showDatepicker" @click.away="showDatepicker = false"> |
| 336 | <div class="flex justify-between items-center mb-2"> |
| 337 | <div> |
| 338 | <span x-text="MONTH_NAMES[month]" class="text-lg font-bold text-gray-800"></span> |
| 339 | <span x-text="year" class="ml-1 text-lg text-gray-600 font-normal"></span> |
| 340 | </div> |
| 341 | <div> |
| 342 | <button type="button" class="focus:outline-none focus:shadow-outline transition ease-in-out duration-100 inline-flex cursor-pointer hover:bg-gray-100 p-1 rounded-full" @click="if (month == 0) { |
| 343 | year--; |
| 344 | month = 12; |
| 345 | } month--; getNoOfDays()"> |
| 346 | <svg class="h-6 w-6 text-gray-400 inline-flex" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 347 | <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" /> |
| 348 | </svg> |
| 349 | </button> |
| 350 | <button type="button" class="focus:outline-none focus:shadow-outline transition ease-in-out duration-100 inline-flex cursor-pointer hover:bg-gray-100 p-1 rounded-full" @click="if (month == 11) { |
| 351 | month = 0; |
| 352 | year++; |
| 353 | } else { |
| 354 | month++; |
| 355 | } getNoOfDays()"> |
| 356 | <svg class="h-6 w-6 text-gray-400 inline-flex" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| 357 | <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /> |
| 358 | </svg> |
| 359 | </button> |
| 360 | </div> |
| 361 | </div> |
| 362 | |
| 363 | <div class="flex flex-wrap mb-3 -mx-1"> |
| 364 | <template x-for="(day, index) in DAYS" :key="index"> |
| 365 | <div style="width: 14.26%" class="px-0.5"> |
| 366 | <div x-text="day" class="text-gray-800 font-medium text-center text-xs"></div> |
| 367 | </div> |
| 368 | </template> |
| 369 | </div> |
| 370 | |
| 371 | <div class="flex flex-wrap -mx-1"> |
| 372 | <template x-for="blankday in blankdays"> |
| 373 | <div style="width: 14.28%" class="text-center border p-1 border-transparent text-sm"></div> |
| 374 | </template> |
| 375 | <template x-for="(date, dateIndex) in no_of_days" :key="dateIndex"> |
| 376 | <div style="width: 14.28%" class="px-1 mb-1"> |
| 377 | <div @click="getDateValue(date)" x-text="date" class="cursor-pointer text-center text-sm leading-none rounded-full leading-loose transition ease-in-out duration-100" :class="{ |
| 378 | 'bg-indigo-200': isToday(date) == true, |
| 379 | 'text-gray-600 hover:bg-indigo-200': isToday(date) == false && isSelectedDate(date) == false, |
| 380 | 'bg-indigo-500 text-white hover:bg-opacity-75': isSelectedDate(date) == true |
| 381 | }"></div> |
| 382 | </div> |
| 383 | </template> |
| 384 | </div> |
| 385 | </div> |
| 386 | </div> |
| 387 | </div> |
| 388 | </div> |
| 389 | </div> |
| 390 | </div> |
| 391 | <div class="mt-8"> |
| 392 | <input |
| 393 | type="checkbox" |
| 394 | value="<?php if( $fixDate ) echo $getOptionObject->params->deloldpFixDate; ?>" |
| 395 | name="deloldp-fix-date" |
| 396 | id="fixdate" |
| 397 | <?php |
| 398 | if ( $fixDate ) echo ' checked'; |
| 399 | ?> |
| 400 | /> |
| 401 | <label for="fixdate"> |
| 402 | <?php esc_html_e("Use a fixed date instead of a number of days in the past.", 'delete-old-posts'); ?> |
| 403 | <span |
| 404 | class="dashicons dashicons-editor-help has-tooltip" |
| 405 | x-on:mouseover="tooltip = true" |
| 406 | x-on:mouseleave="tooltip = false" |
| 407 | > |
| 408 | <span class='tooltip rounded shadow-lg bg-gray-100 p-3 text-sm font-sans -mt-8 text-left max-w-md'> |
| 409 | <?php |
| 410 | esc_html_e('Select this option if you want to use a fixed date instead of a number of days in the past. If you select this option, only the posts older than the selected date will be deleted. If this option is not selected, the post older than the number of days in the past will be deleted, which will always be relative to today.', 'delete-old-posts'); |
| 411 | ?> |
| 412 | </span> |
| 413 | </span> |
| 414 | </label> |
| 415 | </div> |
| 416 | </div> |
| 417 | </div> |
| 418 | <div class="lg:w-1/2 text-center py-8"> |
| 419 | <div class="m-2"> |
| 420 | <input |
| 421 | type="checkbox" |
| 422 | value="1" |
| 423 | name="deloldp-post-redirect" |
| 424 | id="redirect" |
| 425 | <?php |
| 426 | if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') ) |
| 427 | if ( $getOptionObject->params->deloldpRedirect == 1 ) echo ' checked'; |
| 428 | ?> |
| 429 | /> |
| 430 | <label for="redirect" class=""> |
| 431 | <?php esc_html_e("Redirect the URL of the deleted post to a similar post when requested.", 'delete-old-posts'); ?> |
| 432 | <span |
| 433 | class="dashicons dashicons-editor-help has-tooltip" |
| 434 | x-on:mouseover="tooltip = true" |
| 435 | x-on:mouseleave="tooltip = false" |
| 436 | > |
| 437 | <span class='tooltip rounded shadow-lg bg-gray-100 p-3 text-sm font-sans -mt-8 max-w-md right-3 text-left'> |
| 438 | <?php |
| 439 | esc_html_e('Even after the posts are removed, they can still be linked to or found on Google. Choose this option if you want to redirect your visitors to the deleted post to another similar post on your website. The plugin will automatically find the best matching option, but you can customize it in the "Redirects" menu. The HTTP response status code 301 Moved Permanently is used for the redirect.', 'delete-old-posts'); |
| 440 | ?> |
| 441 | </span> |
| 442 | </span> |
| 443 | </label> |
| 444 | </div> |
| 445 | |
| 446 | <div class="border-r"> |
| 447 | <input |
| 448 | type="checkbox" |
| 449 | value="1" |
| 450 | @click="confirmSkipTrash()" |
| 451 | name="deloldp-post-skiptrash" |
| 452 | id="skiptrash" |
| 453 | <?php |
| 454 | if ( $dop_fs->can_use_premium_code() ) { |
| 455 | if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') ) |
| 456 | if ( $getOptionObject->params->deloldpSkiptrash == 1 ) echo ' checked'; |
| 457 | } else echo ' disabled'; |
| 458 | ?> |
| 459 | /> |
| 460 | <label for="skiptrash" class="text-red-600"> |
| 461 | <?php esc_html_e("Delete the Posts permanently, don't add them into Trash", 'delete-old-posts'); ?> <span class="dashicons dashicons-database-remove"></span>. |
| 462 | </label> |
| 463 | |
| 464 | <div class="m-2"> |
| 465 | <?php |
| 466 | printf( __('Number of post to delete when the %s runs.', 'delete-old-posts'), '<a href="https://developer.wordpress.org/plugins/cron/" target="_blank">WP-Cron</a>' ); |
| 467 | $numberOfPostsToDelete = 1; |
| 468 | if ( $dop_fs->can_use_premium_code() ){ |
| 469 | if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') ) |
| 470 | if ( property_exists($getOptionObject->params, 'deloldpPostsNr') ) $numberOfPostsToDelete = $getOptionObject->params->deloldpPostsNr; |
| 471 | } |
| 472 | ?> |
| 473 | <select |
| 474 | id="deloldp-post-number" |
| 475 | name="deloldp-posts-number" |
| 476 | <?php |
| 477 | if ( !$dop_fs->can_use_premium_code() ) echo "disabled"; |
| 478 | ?> |
| 479 | > |
| 480 | <?php |
| 481 | $postNrs = array(1,2,3,4,5,10,20,30,50,100); |
| 482 | foreach($postNrs as $pnr) { |
| 483 | ?> |
| 484 | <option value="<?php echo $pnr; ?>" <?php echo (isset($numberOfPostsToDelete) && $numberOfPostsToDelete == $pnr) ? 'selected="selected"' : ''; ?>><?php echo $pnr; ?></option> |
| 485 | <?php |
| 486 | } |
| 487 | ?> |
| 488 | </select> |
| 489 | <span |
| 490 | class="dashicons dashicons-editor-help has-tooltip" |
| 491 | x-on:mouseover="tooltip = true" |
| 492 | x-on:mouseleave="tooltip = false" |
| 493 | > |
| 494 | <span class='tooltip rounded shadow-lg bg-gray-100 p-3 text-sm font-sans -mt-8 max-w-md right-3 text-left'> |
| 495 | <?php |
| 496 | esc_html_e('Choose the number of post to be deleted at the same time. Please note, that a higher number of post deleted at once means a higher load on your server. You can choose a smaller number on a hosting with low resources (ex. shared hosting) and a higher number if your website is running for example on a dedicated server. By default, one post is deleted.', 'delete-old-posts'); |
| 497 | ?> |
| 498 | </span> |
| 499 | </span> |
| 500 | </div> |
| 501 | |
| 502 | <?php |
| 503 | if ( ! $dop_fs->can_use_premium_code() ) { |
| 504 | echo ' |
| 505 | <section>' . esc_html__('These options are available in the Professional version.', 'delete-old-posts'); |
| 506 | echo ' |
| 507 | <a href="' . $dop_fs->get_upgrade_url() . '">' . |
| 508 | '<u>' .esc_html__('Upgrade Now!', 'delete-old-posts') . '</u>' . |
| 509 | '</a>'; |
| 510 | echo ' |
| 511 | </section>'; |
| 512 | } |
| 513 | ?> |
| 514 | |
| 515 | <section class="mx-8 mt-8 text-slate-500"> |
| 516 | <?php esc_html_e("Filter the deleted post by selecting more options in the filters menu. Available filters are custom post types, categories, taxonomies, users, favorite post, and text search (posts containing a text), so only some from the posts will be deleted even if they are older than selected date (selected days).", "delete-old-posts")?> |
| 517 | </section> |
| 518 | |
| 519 | </div> |
| 520 | </div> |
| 521 | </div> |
| 522 | <div class="mt-3 mb-3 w-full flex items-center"> |
| 523 | <div class="text-right w-1/2"> |
| 524 | <div> |
| 525 | <!-- Rounded switch --> |
| 526 | <?php |
| 527 | $toggledelete = false; |
| 528 | if (is_object($getOptionObject) && property_exists($getOptionObject, 'params') && property_exists($getOptionObject->params, 'toggledelete')) |
| 529 | if( $getOptionObject->params->toggledelete == 1) $toggledelete = true; |
| 530 | if( ! $toggledelete ) esc_html_e("Start", "delete-old-posts"); |
| 531 | else esc_html_e("Stop", "delete-old-posts"); |
| 532 | echo " "; |
| 533 | esc_html_e("deleting the posts:", "delete-old-posts"); |
| 534 | ?> |
| 535 | <label class="switch ml-2"> |
| 536 | <input |
| 537 | type="checkbox" |
| 538 | id="toggledelete" |
| 539 | name="toggledelete" |
| 540 | value="1" |
| 541 | <?php if( $toggledelete ) echo "checked"; ?> |
| 542 | > |
| 543 | <span class="slider round"></span> |
| 544 | </label> |
| 545 | <!-- Help tooltip --> |
| 546 | <span |
| 547 | class="dashicons dashicons-editor-help has-tooltip" |
| 548 | x-on:mouseover="tooltip = true" |
| 549 | x-on:mouseleave="tooltip = false" |
| 550 | > |
| 551 | <span class='tooltip rounded shadow-lg bg-gray-100 p-3 text-sm text-left font-sans max-w-md'> |
| 552 | <?php |
| 553 | esc_html_e('Start/ Stop deleting posts. Select this option and click save to start/ stop deleting the posts automatically in background. Hint! You can first test the results when you save the filters.', 'delete-old-posts'); |
| 554 | ?> |
| 555 | </span> |
| 556 | </span> |
| 557 | </div> |
| 558 | </div> |
| 559 | <div class="text-left w-1/2 items-right"> |
| 560 | <button |
| 561 | type="submit" |
| 562 | class="bg-blue-500 rounded-full font-bold text-white px-4 py-3 ml-5 inline-block transition duration-300 ease-in-out hover:bg-blue-600" |
| 563 | > |
| 564 | <?php esc_html_e('Save', 'delete-old-posts'); ?> |
| 565 | <svg xmlns="http://www.w3.org/2000/svg" class="inline ml-2 w-6 stroke-current text-white stroke-2" viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round"> |
| 566 | <line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/> |
| 567 | </svg> |
| 568 | </button> |
| 569 | <?php wp_nonce_field('start-delete-old-posts', 'secured-delete-old-posts'); ?> |
| 570 | </div> |
| 571 | </div> |
| 572 | </div> |
| 573 | </div> |
| 574 | </form> |
| 575 | |
| 576 | <?php |
| 577 | /** |
| 578 | * get post deletion log |
| 579 | */ |
| 580 | $post_delete_log = array(); |
| 581 | if( get_option('post_delete_log_array') !== false ) $post_delete_log = get_option('post_delete_log_array'); |
| 582 | ?> |
| 583 | |
| 584 | <div class="flex-grow container mx-auto sm:px-4 pt-1 pb-1" x-data="{}"> |
| 585 | <div class="bg-white border-t border-b sm:border-l sm:border-r sm:rounded shadow mb-6"> |
| 586 | <div class="border-b px-6"> |
| 587 | <div class="flex justify-between -mb-px"> |
| 588 | <div class=" text-blue-dark py-4 text-lg"> |
| 589 | <?php esc_html_e('The latest deleted post:', 'delete-old-posts'); ?> |
| 590 | </div> |
| 591 | <div class="flex text-sm"> |
| 592 | <div class="py-4 text-grey-dark border-b border-transparent hover:border-grey-dark mr-3"> |
| 593 | <span class="dashicons dashicons-nametag"></span> |
| 594 | </div> |
| 595 | </div> |
| 596 | </div> |
| 597 | </div> |
| 598 | <div class="text-gray-400 grid auto-cols-auto grid-flow-col gap-3"> |
| 599 | <div class="tblrow"> |
| 600 | <?php |
| 601 | esc_html_e('Post published date:', 'delete-old-posts'); |
| 602 | if( isset($post_delete_log['deleted_post_timestamp']) ) echo " " . date("d M Y h:i:s A", $post_delete_log['deleted_post_timestamp']); |
| 603 | ?> |
| 604 | <br /> |
| 605 | <?php |
| 606 | esc_html_e('Id:', 'delete-old-posts'); |
| 607 | echo " "; |
| 608 | if(isset($post_delete_log['deleted_post_id'])) echo $post_delete_log['deleted_post_id']; |
| 609 | ?> |
| 610 | </div> |
| 611 | <div class="tblrow">Title: <?php if(isset($post_delete_log['deleted_post_title'])) echo $post_delete_log['deleted_post_title']; ?></div> |
| 612 | </div> |
| 613 | </div> |
| 614 | </div> |
| 615 | </section> |
| 616 | |
| 617 | <?php |
| 618 | } |
| 619 | |
| 620 | /** |
| 621 | * add custom cron interval |
| 622 | */ |
| 623 | function deloldp_add_cron_interval( $schedules ) { |
| 624 | $schedules['fifteen_seconds'] = array( |
| 625 | 'interval' => 15, |
| 626 | 'display' => esc_html__( 'Every Fifteen Seconds' ), ); |
| 627 | return $schedules; |
| 628 | } |
| 629 | |
| 630 | /** |
| 631 | * function to delete the cron job |
| 632 | */ |
| 633 | function deloldp_deactivate() { |
| 634 | // delete plugin data |
| 635 | delete_option('deloldp-post-days-option'); |
| 636 | // error_log('plugin deactivated'); |
| 637 | $timestamp = wp_next_scheduled( 'deloldp_cron_delete_old_posts' ); |
| 638 | wp_unschedule_event( $timestamp, 'deloldp_cron_delete_old_posts' ); |
| 639 | } |
| 640 | |
| 641 | /** |
| 642 | * function exec. when cron run |
| 643 | */ |
| 644 | function deloldp_cron_exec() { |
| 645 | // error_log('cron running...'); |
| 646 | /** |
| 647 | * check if user selected the option to start deleting the posts |
| 648 | */ |
| 649 | $startDeletingPosts = false; |
| 650 | // get user saved options |
| 651 | $getOptionObject = get_option('deloldp-post-days-option'); |
| 652 | // check if start delete posts option is on |
| 653 | if ( is_object($getOptionObject) && property_exists($getOptionObject,'params') && property_exists($getOptionObject->params,'toggledelete') ) |
| 654 | if ( $getOptionObject->params->toggledelete == 1 ) $startDeletingPosts = true; |
| 655 | |
| 656 | // get the posts to delete |
| 657 | if( $startDeletingPosts ){ |
| 658 | $nrOfPostsToGet = $this->getNumberOfPosts(); |
| 659 | $altPostsArray = $this->getAltestPostsObj($nrOfPostsToGet); |
| 660 | } |
| 661 | |
| 662 | /** |
| 663 | * delete the altest post |
| 664 | * @return NULL | array |
| 665 | */ |
| 666 | if( isset($altPostsArray) && is_array($altPostsArray) ) $this->deletePosts( $altPostsArray, $getOptionObject ); |
| 667 | } |
| 668 | |
| 669 | /** |
| 670 | * get the posts list |
| 671 | * @param $nrOfPostsToGet - the number of posts to retrieve |
| 672 | * @return post object |
| 673 | */ |
| 674 | function getAltestPostObj( $nrOfPostsToGet = 1 ) { |
| 675 | |
| 676 | $post_list = array(); |
| 677 | |
| 678 | // set sql query vars |
| 679 | $postTypes = $this->formatSQLParam('postType'); |
| 680 | $postCat = $this->formatSQLParam('postCategory'); |
| 681 | $postAuthor = $this->formatSQLParam('postAuthor'); |
| 682 | $relation = $this->formatSQLParam('relation'); |
| 683 | $postids = $this->formatSQLParam('postids'); |
| 684 | $skeywords = $this->formatSQLParam('search_keywords'); |
| 685 | |
| 686 | // create tax_query array |
| 687 | $tax_query = array(); |
| 688 | $tax_query['relation'] = $relation; |
| 689 | if( is_array($postCat) ) foreach( $postCat as $cat ){ |
| 690 | $tax_query[] = array( |
| 691 | 'taxonomy' => 'category', |
| 692 | 'field' => 'term_id', |
| 693 | 'terms' => $cat |
| 694 | ); |
| 695 | } |
| 696 | |
| 697 | // get the altest post |
| 698 | if( is_array($postTypes) ) $post_list = get_posts( array( |
| 699 | // 'fields' => 'ids', // Only get post IDs |
| 700 | 'post_type' => $postTypes, |
| 701 | 'post_status' => 'publish', |
| 702 | 'orderby' => 'date', |
| 703 | 'order' => 'ASC', |
| 704 | 'posts_per_page' => $nrOfPostsToGet, |
| 705 | 'include' => array(), //An array of post IDs to retrieve |
| 706 | 'exclude' => $postids, //An array of post IDs not to retrieve. |
| 707 | // 'category' => $postCat, //Category ID or comma-separated list of IDs. Default 0. - Not used. tax_query used instead. |
| 708 | 'author' => $postAuthor, //Author ID, or comma-separated list of IDs. Default 0. |
| 709 | 'meta_key' => '', |
| 710 | 'meta_value' => '', |
| 711 | 's' => $skeywords, //Search keyword(s). Prepending a term with a hyphen will exclude posts matching that term. Eg, 'pillow -sofa' will return posts containing 'pillow' but not 'sofa'. |
| 712 | 'tax_query' => $tax_query |
| 713 | ) ); |
| 714 | |
| 715 | return $post_list; |
| 716 | } |
| 717 | |
| 718 | /** |
| 719 | * get the custom posts list |
| 720 | * @param $nrOfPostsToGet - the number of posts to retrieve |
| 721 | * @return post object |
| 722 | */ |
| 723 | function getAltestCustomPostObj( $nrOfPostsToGet = 1 ) { |
| 724 | |
| 725 | $custom_post_list = array(); |
| 726 | |
| 727 | // set sql query vars |
| 728 | $customPostTypes = $this->formatSQLParam('customPostTypes'); |
| 729 | |
| 730 | // create a request for each specified cpt |
| 731 | $custom_post_list = array(); |
| 732 | if( is_array($customPostTypes) ) { |
| 733 | foreach( $customPostTypes as $cpt ){ |
| 734 | // get the tax_query |
| 735 | $postTax = $this->formatSQLParam('postTax', $cpt); |
| 736 | $postAuthor = $this->formatSQLParam('postAuthor'); |
| 737 | $postids = $this->formatSQLParam('postids'); |
| 738 | $skeywords = $this->formatSQLParam('search_keywords'); |
| 739 | |
| 740 | // get the altest post |
| 741 | $custom_post_arr = get_posts( array( |
| 742 | // 'fields' => 'ids', // Only get post IDs |
| 743 | 'post_type' => $cpt, |
| 744 | 'post_status' => 'publish', |
| 745 | 'orderby' => 'date', |
| 746 | 'order' => 'ASC', |
| 747 | 'posts_per_page' => $nrOfPostsToGet, |
| 748 | 'include' => array(), //An array of post IDs to retrieve |
| 749 | 'exclude' => $postids, //An array of post IDs not to retrieve. |
| 750 | // 'category' => $postCat, //Category ID or comma-separated list of IDs. Default 0. |
| 751 | 'author' => $postAuthor, //Author ID, or comma-separated list of IDs. Default 0. |
| 752 | 'meta_key' => '', |
| 753 | 'meta_value' => '', |
| 754 | 's' => $skeywords, //Search keyword(s). Prepending a term with a hyphen will exclude posts matching that term. Eg, 'pillow -sofa' will return posts containing 'pillow' but not 'sofa'. |
| 755 | 'tax_query' => $postTax |
| 756 | ) ); |
| 757 | |
| 758 | if( is_array($custom_post_arr) ) foreach( $custom_post_arr as $postsObject ){ |
| 759 | $custom_post_list[] = $postsObject; |
| 760 | } |
| 761 | } |
| 762 | } |
| 763 | |
| 764 | return $custom_post_list; |
| 765 | } |
| 766 | |
| 767 | /** |
| 768 | * make user choosed days in a timestamp |
| 769 | */ |
| 770 | function userDaysToTimestamp() { |
| 771 | $getOptionObject = get_option('deloldp-post-days-option'); |
| 772 | // check if fixed date selected |
| 773 | $fixDate = false; |
| 774 | if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') ) |
| 775 | if ( $getOptionObject->params->deloldpFixDate != '' ) $fixDate = true; |
| 776 | |
| 777 | switch( $fixDate ){ |
| 778 | case true: |
| 779 | // get the number of days between two dates |
| 780 | $fixDateTimestamp = strtotime( $getOptionObject->params->deloldpFixDate ); |
| 781 | $datediff = time() - $fixDateTimestamp; |
| 782 | $deleteSavedDays = absint( round( $datediff / (60 * 60 * 24) ) + 1 ); |
| 783 | break; |
| 784 | case false: |
| 785 | if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') ) |
| 786 | if ( property_exists($getOptionObject->params, 'deloldpDays') ) { |
| 787 | $deleteSavedDays = absint( $getOptionObject->params->deloldpDays + 1 ); |
| 788 | } |
| 789 | break; |
| 790 | } |
| 791 | |
| 792 | if( isset($deleteSavedDays) && is_int($deleteSavedDays) ){ |
| 793 | $post2DelTimestamp = strtotime("-" . $deleteSavedDays . ' days'); |
| 794 | /** |
| 795 | * get the timestamp of the date at 23:59:59 |
| 796 | * all post published untill this date and time will be deleted |
| 797 | */ |
| 798 | $post2DelTimestamp00 = mktime(23, 59, 59, date('m', $post2DelTimestamp), date('d', $post2DelTimestamp), date('Y', $post2DelTimestamp)); |
| 799 | |
| 800 | return $post2DelTimestamp00; |
| 801 | } |
| 802 | |
| 803 | return false; |
| 804 | } |
| 805 | |
| 806 | /** |
| 807 | * save options - save plugin data |
| 808 | */ |
| 809 | function saveOption( $optionValue = array() ) { |
| 810 | $myOptions = new \stdClass(); |
| 811 | $myOptions->name = 'deloldp-post-days-option'; |
| 812 | $myOptions->params = (object) $this -> sanitize_text_or_array_field($optionValue); |
| 813 | /** |
| 814 | * save the plugin options |
| 815 | */ |
| 816 | return update_option( 'deloldp-post-days-option', $myOptions ); |
| 817 | } |
| 818 | |
| 819 | /** |
| 820 | * Recursive sanitation for text or array |
| 821 | * |
| 822 | * @param $array_or_string (array|string) |
| 823 | * @since 0.1 |
| 824 | * @return mixed |
| 825 | */ |
| 826 | function sanitize_text_or_array_field($array_or_string) { |
| 827 | if( is_string($array_or_string) ){ |
| 828 | $array_or_string = sanitize_text_field($array_or_string); |
| 829 | } elseif ( is_array($array_or_string) ){ |
| 830 | foreach ( $array_or_string as $key => &$value ) { |
| 831 | if ( is_array( $value ) ) { |
| 832 | $value = $this -> sanitize_text_or_array_field($value); |
| 833 | } else { |
| 834 | $value = sanitize_text_field( $value ); |
| 835 | } |
| 836 | } |
| 837 | } |
| 838 | |
| 839 | return $array_or_string; |
| 840 | } |
| 841 | |
| 842 | /** |
| 843 | * Make some actions when the plugin is removed |
| 844 | */ |
| 845 | function deloldp_deleted(){ |
| 846 | return true; |
| 847 | } |
| 848 | |
| 849 | /** |
| 850 | * Save deleted posts data in an option and use it to rediect traffic |
| 851 | * |
| 852 | * @param $deletedPostData (array) |
| 853 | */ |
| 854 | function saveToRedirectOpt( $deletedPostData ){ |
| 855 | // check if option to redirect the deleted posts is checked |
| 856 | $deloldpRedirect_opt = get_option('deloldp-post-days-option'); |
| 857 | if( is_object($deloldpRedirect_opt) && property_exists($deloldpRedirect_opt->params, 'deloldpRedirect' ) ){ |
| 858 | if ( $deloldpRedirect_opt->params->deloldpRedirect == 1 ) { |
| 859 | // option checked - save the redirect |
| 860 | if( is_object($deletedPostData) ){ |
| 861 | // update deletedpostredirectsopt |
| 862 | $deletedpostredirectsopt = get_option('deletedpostredirectsopt'); |
| 863 | if( ! is_array($deletedpostredirectsopt) ) $deletedpostredirectsopt = array(); |
| 864 | $deletedpostredirectsopt[] = (isset($deletedPostData->post_name)) ? $deletedPostData->post_name : ''; |
| 865 | // update the option |
| 866 | array_unique( $deletedpostredirectsopt ); |
| 867 | update_option('deletedpostredirectsopt', $deletedpostredirectsopt); |
| 868 | } |
| 869 | } |
| 870 | } |
| 871 | } |
| 872 | |
| 873 | /** |
| 874 | * Create help tooltips |
| 875 | */ |
| 876 | function generateHelpTooltip( $helpTxt, $tooltipClass = '', $tooltipTxtClass = '' ){ |
| 877 | ?> |
| 878 | <span |
| 879 | class="dashicons dashicons-editor-help has-tooltip <?php echo $tooltipClass; ?>" |
| 880 | x-on:mouseover="tooltip = true" |
| 881 | x-on:mouseleave="tooltip = false" |
| 882 | > |
| 883 | <span class='tooltip rounded shadow-lg bg-gray-100 p-3 text-sm font-sans -mt-8 max-w-md <?php echo $tooltipTxtClass; ?>'> |
| 884 | <?php echo $helpTxt; ?> |
| 885 | </span> |
| 886 | </span> |
| 887 | <?php |
| 888 | } |
| 889 | |
| 890 | /** |
| 891 | * format the SQL parameters used to fetch the posts to be deleted |
| 892 | * @param $what -> define what parameter to return |
| 893 | * @return array | string |
| 894 | */ |
| 895 | function formatSQLParam( $what = '', $cpt = ''){ |
| 896 | |
| 897 | // get filters options saved values |
| 898 | $delop_filters = get_option('delop_filters'); |
| 899 | |
| 900 | switch ($what){ |
| 901 | case 'postType': |
| 902 | // default post type = post |
| 903 | $postTypes = array( 'post' ); |
| 904 | // check if only custom post types selected |
| 905 | if( is_array($delop_filters) && isset($delop_filters['cpt']) && is_array($delop_filters['cpt']) && ! in_array('post', $delop_filters['cpt']) ) $postTypes = 'skip'; |
| 906 | |
| 907 | return $postTypes; |
| 908 | case 'customPostTypes': |
| 909 | $customPostTypes = 'skip'; |
| 910 | // if user selected the post types just return the cpt array |
| 911 | if( is_array($delop_filters) && isset($delop_filters['cpt']) ) { |
| 912 | $customPostTypes = $delop_filters['cpt']; |
| 913 | // delete post in cpt array |
| 914 | if (($post_val_key = array_search('post', $customPostTypes)) !== false) unset($customPostTypes[$post_val_key]); |
| 915 | // check if any post left in the cpt array |
| 916 | if( count($customPostTypes) == 0 ) $customPostTypes = 'skip'; |
| 917 | |
| 918 | return $customPostTypes; |
| 919 | } |
| 920 | case 'postCategory': |
| 921 | // default val. for category = 0 -> no category |
| 922 | $postCat = 0; |
| 923 | if( is_array($delop_filters) && isset($delop_filters['post_category']) && is_array($delop_filters['post_category']) ){ |
| 924 | // $postCat = implode( ',', filter_var_array($delop_filters['post_category']) ); |
| 925 | $postCat = filter_var_array($delop_filters['post_category']); |
| 926 | } |
| 927 | |
| 928 | return $postCat; |
| 929 | case 'postAuthor': |
| 930 | $postAuthor = 0; |
| 931 | if( is_array($delop_filters) && isset($delop_filters['userid']) && is_array($delop_filters['userid']) ){ |
| 932 | $postAuthor = implode( ',', filter_var_array($delop_filters['userid']) ); |
| 933 | } |
| 934 | |
| 935 | return $postAuthor; |
| 936 | case 'postTax': |
| 937 | $postTax = array(); |
| 938 | if( isset($cpt) && is_string($cpt) && $cpt != '' ){ // check if cpt specified - needed to check if the taxonomies are registered for (belongs to) the cpt |
| 939 | if( is_array($delop_filters) && isset($delop_filters['tax_input']) && is_array($delop_filters['tax_input']) ){ |
| 940 | // format the taxonomy array like this |
| 941 | // array( |
| 942 | // 'relation' => 'AND', |
| 943 | // array( |
| 944 | // 'taxonomy' => 'services', // you can change it according to your taxonomy |
| 945 | // 'field' => 'term_id', // this can be 'term_id', 'slug' & 'name' |
| 946 | // 'terms' => $service->term_id, |
| 947 | // ) |
| 948 | // ) |
| 949 | $relation = 'AND'; |
| 950 | if( is_array($delop_filters) && isset($delop_filters['relation']) ) $relation = sanitize_text_field($delop_filters['relation']); |
| 951 | $postTax['relation'] = $relation; // use relation when are more terms (AND | OR) |
| 952 | foreach( $delop_filters['tax_input'] as $key => $tax_input ){ |
| 953 | $get_obj_taxonomies = get_object_taxonomies( $cpt ); |
| 954 | if( is_array($tax_input) && in_array($key, $get_obj_taxonomies) ){ |
| 955 | if( is_array($tax_input) ) foreach( $tax_input as $term ){ |
| 956 | $postTax[] = array( |
| 957 | 'taxonomy' => $key, |
| 958 | 'field' => 'term_id', |
| 959 | 'terms' => $term |
| 960 | ); |
| 961 | } |
| 962 | } |
| 963 | } |
| 964 | } |
| 965 | } |
| 966 | |
| 967 | return $postTax; |
| 968 | case 'relation': |
| 969 | // get the selected relation for tax_query |
| 970 | $relation = 'AND'; |
| 971 | if( is_array($delop_filters) && isset($delop_filters['relation']) ) $relation = sanitize_text_field($delop_filters['relation']); |
| 972 | |
| 973 | return $relation; |
| 974 | case 'postids': |
| 975 | $postids = array(); |
| 976 | if( is_array($delop_filters) && isset($delop_filters['postids']) ) { |
| 977 | $postids = array_map('trim', explode(',', sanitize_text_field( $delop_filters['postids'] ))); |
| 978 | } |
| 979 | |
| 980 | return $postids; |
| 981 | case 'search_keywords': |
| 982 | $search_keywords = ''; |
| 983 | if( is_array($delop_filters) ){ |
| 984 | if( isset($delop_filters['search_keyword']) && $delop_filters['search_keyword'] != '' ) { |
| 985 | $search_keywords = sanitize_text_field( $delop_filters['search_keyword'] ); |
| 986 | // check if negative keywords exists |
| 987 | if( isset($delop_filters['search_keyword_negativ']) && $delop_filters['search_keyword_negativ'] != '' ) |
| 988 | $search_keywords = $search_keywords . ' -' . sanitize_text_field( $delop_filters['search_keyword_negativ'] ); |
| 989 | } |
| 990 | } |
| 991 | |
| 992 | return $search_keywords; |
| 993 | } |
| 994 | |
| 995 | return ''; |
| 996 | } |
| 997 | |
| 998 | /** |
| 999 | * get the old posts to delete array |
| 1000 | */ |
| 1001 | function getAltestPostsObj($nrOfPostsToGet){ |
| 1002 | $altPostsFinalArray = array(); |
| 1003 | // get the default posts list |
| 1004 | $altPostsArray = $this->getAltestPostObj($nrOfPostsToGet); |
| 1005 | // get the custom posts list |
| 1006 | $altCustomPostsArray = $this->getAltestCustomPostObj($nrOfPostsToGet); |
| 1007 | // combine the lists toghether |
| 1008 | if( is_array($altPostsArray) ) foreach( $altPostsArray as $oldPost ){ |
| 1009 | $altPostsFinalArray[] = $oldPost; |
| 1010 | } |
| 1011 | if( is_array($altCustomPostsArray) ) foreach( $altCustomPostsArray as $oldCustomPost ){ |
| 1012 | $altPostsFinalArray[] = $oldCustomPost; |
| 1013 | } |
| 1014 | |
| 1015 | // get user saved options |
| 1016 | $getOptionObject = get_option('deloldp-post-days-option'); |
| 1017 | // get the list of deleted posts without deleting them |
| 1018 | $postsDeleted = $this->deletePosts( $altPostsFinalArray, $getOptionObject, false ); |
| 1019 | if( ! is_array($postsDeleted) ) $postsDeleted = array(); // if NULL returned |
| 1020 | |
| 1021 | return $postsDeleted; |
| 1022 | } |
| 1023 | |
| 1024 | /** |
| 1025 | * retrieve the number of post to delete |
| 1026 | */ |
| 1027 | function getNumberOfPosts(){ |
| 1028 | |
| 1029 | global $dop_fs; |
| 1030 | |
| 1031 | $nrOfPostsToGet = 1; |
| 1032 | if ( $dop_fs->can_use_premium_code() ){ |
| 1033 | $getOptionObject = get_option('deloldp-post-days-option'); |
| 1034 | if ( is_object($getOptionObject) && property_exists($getOptionObject, 'params') ) |
| 1035 | if ( property_exists($getOptionObject->params, 'deloldpPostsNr') ) $nrOfPostsToGet = $getOptionObject->params->deloldpPostsNr; |
| 1036 | } |
| 1037 | |
| 1038 | return $nrOfPostsToGet; |
| 1039 | } |
| 1040 | |
| 1041 | /** |
| 1042 | * log var_dump errors |
| 1043 | * you can only echo the results you have to capture the output buffer with ob_start(), assign it to a variable, |
| 1044 | * and then clean the buffer with ob_end_clean() allowing you to write the resulting variable to the error_log |
| 1045 | */ |
| 1046 | function var_error_log( $object=null ){ |
| 1047 | ob_start(); // start buffer capture |
| 1048 | var_dump( $object ); // dump the values |
| 1049 | $contents = ob_get_contents(); // put the buffer into a variable |
| 1050 | ob_end_clean(); // end capture |
| 1051 | error_log( $contents ); // log contents of the result of var_dump( $object ) |
| 1052 | } |
| 1053 | |
| 1054 | /** |
| 1055 | * delete the posts |
| 1056 | * @param array $altPostsArray = array of posts selected from DB |
| 1057 | * @param object $getOptionObject = saved plugin options |
| 1058 | * @param true|false $action -> true = delete the posts | false = test (return the list of posts to delete) |
| 1059 | */ |
| 1060 | function deletePosts( $altPostsArray, $getOptionObject, $action = true ){ |
| 1061 | |
| 1062 | global $dop_fs; |
| 1063 | |
| 1064 | // get the user delete days |
| 1065 | $postDeleteDaysTime = $this->userDaysToTimestamp(); |
| 1066 | |
| 1067 | /** check if number of days was set */ |
| 1068 | if( ! $postDeleteDaysTime ) return; // posts nr. of days to be deleted not defined - exit |
| 1069 | |
| 1070 | // error_log("Time: " . date("d M Y", $postDeleteDaysTime)); |
| 1071 | |
| 1072 | if( isset($altPostsArray) && is_array($altPostsArray) ) { |
| 1073 | $i=0; $deletedPostsArray = array(); |
| 1074 | // get saved attached_img option |
| 1075 | $delop_filters = get_option('delop_filters'); |
| 1076 | $attached_img_opt = ( is_array($delop_filters) && isset($delop_filters['attached_img']) ) ? $delop_filters[ 'attached_img' ] : ''; |
| 1077 | foreach( $altPostsArray as $altPostDataObj ){ |
| 1078 | if( is_object($altPostDataObj) ){ |
| 1079 | $altPostTimestamp = strtotime( $altPostDataObj->post_date ); |
| 1080 | |
| 1081 | if( $postDeleteDaysTime > $altPostTimestamp ) { |
| 1082 | // save the last entry for log |
| 1083 | if( $i == (count($altPostsArray) - 1) ){ |
| 1084 | if( $action ) update_option('post_delete_log_array', array( |
| 1085 | 'deleted_post_id' => $altPostDataObj->ID, |
| 1086 | 'deleted_post_timestamp' => $altPostTimestamp, |
| 1087 | 'deleted_post_title' => $altPostDataObj->post_title, |
| 1088 | 'deleted_post_name' => $altPostDataObj->post_name, |
| 1089 | 'deleted_post_url' => $altPostDataObj->guid, |
| 1090 | )); |
| 1091 | } |
| 1092 | $i++; |
| 1093 | // ======== delete post ========= |
| 1094 | $deletePostSkipTrash = false; |
| 1095 | if ( $dop_fs->can_use_premium_code() ) { |
| 1096 | // check if skipTrash is set |
| 1097 | $skipTrashOption = 0; |
| 1098 | if ( is_object($getOptionObject) && property_exists($getOptionObject,'params') ) |
| 1099 | if ( $getOptionObject->params->deloldpSkiptrash ) $skipTrashOption = $getOptionObject->params->deloldpSkiptrash; |
| 1100 | if( $skipTrashOption == 1 ) $deletePostSkipTrash = true; |
| 1101 | } |
| 1102 | // delete the post |
| 1103 | if( isset($altPostDataObj->ID) ) { |
| 1104 | if( $action ){ |
| 1105 | if( $deletePostSkipTrash ) $deletePostResult = wp_delete_post( (int) $altPostDataObj->ID, $deletePostSkipTrash ); |
| 1106 | else $deletePostResult = wp_trash_post( (int) $altPostDataObj->ID ); //cpt are not trashed with wp_delete_post |
| 1107 | /** |
| 1108 | * delete all attached media |
| 1109 | */ |
| 1110 | if ( $dop_fs->can_use_premium_code() ) { |
| 1111 | if( isset($attached_img_opt) && $attached_img_opt == 1 ) $this->delopt_delete_all_attached_media( $altPostDataObj->ID ); |
| 1112 | } |
| 1113 | } else { |
| 1114 | /** |
| 1115 | * test -> create the array of deleted posts to return without actually deleting them |
| 1116 | */ |
| 1117 | $deletedPostsArray[] = $altPostDataObj; |
| 1118 | } |
| 1119 | } |
| 1120 | |
| 1121 | /** |
| 1122 | * Save deleted post data in an option to redirect it later to a similar post if old post URL called |
| 1123 | */ |
| 1124 | if( $action ) $this->saveToRedirectOpt($altPostDataObj); |
| 1125 | } |
| 1126 | } |
| 1127 | } |
| 1128 | |
| 1129 | if( ! $action ) { |
| 1130 | // return the array with posts that normally would have been deleted |
| 1131 | return $deletedPostsArray; |
| 1132 | } |
| 1133 | } |
| 1134 | } |
| 1135 | |
| 1136 | /** |
| 1137 | * delete all attached media |
| 1138 | * @param $post_id = the ID of the Post |
| 1139 | * @return $attachment_ids = array with ID of the deleted attachments; |
| 1140 | */ |
| 1141 | function delopt_delete_all_attached_media( $post_id, $delete_media = true ) { |
| 1142 | |
| 1143 | $attachment_ids = array(); // get all deleted attachment ids |
| 1144 | $attachments = get_attached_media( '', absint( $post_id ) ); |
| 1145 | |
| 1146 | foreach ($attachments as $attachment) { |
| 1147 | // check if attachment is used in more than one post |
| 1148 | $attachmentMultipleUsed = ($this->delop_get_image_count( $attachment->ID ) > 1) ? true : false; |
| 1149 | if( $delete_media && ! $attachmentMultipleUsed ) wp_delete_attachment( $attachment->ID, 'true' ); |
| 1150 | if( isset($attachment->guid) && ! $attachmentMultipleUsed ) $attachment_ids[] = $attachment->guid; |
| 1151 | } |
| 1152 | |
| 1153 | return $attachment_ids; |
| 1154 | |
| 1155 | } |
| 1156 | |
| 1157 | /** |
| 1158 | * Given an attachment ID, searches for any post with that attachment used |
| 1159 | * as a featured image, or if it is present in the content of the post. |
| 1160 | * Needs caching (and the cache needs to be tidied up where possible) |
| 1161 | */ |
| 1162 | function delop_get_image_count( $id ){ |
| 1163 | global $wpdb; |
| 1164 | |
| 1165 | // $att = get_post_custom( $id ); |
| 1166 | // $file = $att['_wp_attached_file'][0]; |
| 1167 | // //Do not take full path as different image sizes could |
| 1168 | // // have different month, year folders due to theme and image size changes |
| 1169 | // $file = sprintf( "%s.%s", |
| 1170 | // pathinfo( $file, PATHINFO_FILENAME ), |
| 1171 | // pathinfo( $file, PATHINFO_EXTENSION ) |
| 1172 | // ); |
| 1173 | |
| 1174 | $sql = "SELECT {$wpdb->posts}.ID |
| 1175 | FROM {$wpdb->posts} |
| 1176 | INNER JOIN {$wpdb->postmeta} |
| 1177 | ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id) |
| 1178 | AND ( |
| 1179 | {$wpdb->posts}.post_status = 'publish' OR |
| 1180 | {$wpdb->posts}.post_status = 'future' OR |
| 1181 | {$wpdb->posts}.post_status = 'draft' |
| 1182 | ) |
| 1183 | AND {$wpdb->postmeta}.meta_key = '_thumbnail_id' AND {$wpdb->postmeta}.meta_value = %d |
| 1184 | GROUP BY {$wpdb->posts}.ID"; |
| 1185 | |
| 1186 | $prepared_sql = $wpdb->prepare( $sql, $id ); |
| 1187 | |
| 1188 | $post_ids = $wpdb->get_results( $prepared_sql ); |
| 1189 | |
| 1190 | $count = count( $post_ids ); |
| 1191 | |
| 1192 | return $count; |
| 1193 | } |
| 1194 | |
| 1195 | } |
| 1196 | |
| 1197 | ?> |
| 1198 |