Plugin Directory

Changeset 3229463


Ignore:
Timestamp:
01/27/2025 12:00:04 PM (14 months ago)
Author:
crowdaa
Message:

Version 2.0.1

Location:
crowdaa-sync
Files:
13 edited
43 copied

Legend:

Unmodified
Added
Removed
  • crowdaa-sync/tags/2.0.1/CHANGELOG

    r3218183 r3229463  
    88## [Unreleased]
    99
    10 ## [1.10.8] - 2025-01-07
    11 
    12 ### Changed
    13 
    14 - Preventing Crowdaa API post deletion when WP>API sync is not enabled
    15 
    16 ## [1.10.7] - 2025-01-03
    17 
    18 ### Changed
    19 
    20 - Fixed order of synchronization steps to remove elements before adding others, to avoid conflicts
     10## [2.0.1] - 2025-01-27
     11
     12### Changed
     13
     14- Added missing translations
     15- Now removing items first before adding new ones (categories, badges) to avoid duplicate issues
     16- Fixed an issue with articles unpublishing from WP to the API
     17- Preventing API posts deletion when deleting from WP when the WP>API sync is not enabled
     18
     19## [2.0.0] - 2024-12-13
     20
     21This is marked as a major release beacause it will force a full re-synchronization of all articles. There are no breaking changes other than that.
     22
     23### Changed
     24
     25- Reworked the synchronization process to use the update date from the API instead of the publication dates. It allows to :
     26- Synchronize unpublished articles and articles published at a future date both ways
    2127
    2228## [1.10.6] - 2024-12-04
  • crowdaa-sync/tags/2.0.1/README.txt

    r3218183 r3229463  
    66Requires PHP: 7.3
    77Tested up to: 5.9
    8 Stable tag: 1.10.8
     8Stable tag: 2.0.1
    99License: GPLv2 or later
    1010License URI: http://www.gnu.org/licenses/gpl-2.0.html
  • crowdaa-sync/tags/2.0.1/admin/class-crowdaa-sync-add-info-api.php

    r3216233 r3229463  
    279279          ];
    280280        } else if (
    281           $synced_by_wp_id[$id]->permission_hash !== $permission->hash &&
     281          (
     282            $synced_by_wp_id[$id]->permission_hash !== $permission->hash ||
     283            $sync_db->get_version() !== $synced_by_wp_id[$id]->sync_version
     284          ) &&
    282285          isset($badges_by_id[$synced_by_wp_id[$id]->api_id])
    283286        ) {
     
    315318          ];
    316319        } else if (
    317           $synced_by_api_id[$id]->badge_hash !== $badge->hash &&
     320          (
     321            $synced_by_api_id[$id]->badge_hash !== $badge->hash ||
     322            $sync_db->get_version() !== $synced_by_api_id[$id]->sync_version
     323          ) &&
    318324          isset($permissions_by_id[$synced_by_api_id[$id]->wp_id])
    319325        ) {
     
    365371    $categories_by_id = [];
    366372    $sync_api         = new Crowdaa_Sync_API();
    367     $sync_db          = new Crowdaa_Sync_Syncdb('categories');
     373    $sync_db          = Crowdaa_Sync_Syncdb::instance('categories');
    368374    $synced           = $sync_db->get_synced_entries();
    369375    $all_categories   = $sync_api->get_categories();
     
    532538              ];
    533539            } else if (
    534               $synced_by_wp_id[$id]->term_hash !== $term->hash &&
     540              (
     541                $synced_by_wp_id[$id]->term_hash !== $term->hash ||
     542                $sync_db->get_version() !== $synced_by_wp_id[$id]->sync_version
     543              ) &&
    535544              isset($categories_by_id[$synced_by_wp_id[$id]->api_id])
    536545            ) {
     
    578587              ];
    579588            } else if (
    580               $synced_by_api_id[$id]->category_hash !== $category->hash &&
     589              (
     590                $synced_by_api_id[$id]->category_hash !== $category->hash ||
     591                $sync_db->get_version() !== $synced_by_api_id[$id]->sync_version
     592              ) &&
    581593              isset($terms_by_id[$synced_by_api_id[$id]->wp_id])
    582594            ) {
     
    648660        'start' => '0',
    649661        'limit' => $fetch_batch_count,
     662        'sortBy' => 'updatedAt',
    650663        'getAuthors' => 'false',
    651664        'getDrafts' => 'false',
    652665        'getOrphansArticles' => 'false',
    653666        'getPictures' => 'false',
    654         'onlyPublished' => 'true',
     667        'onlyPublished' => 'false',
    655668        'showHiddenOnFeed' => 'true',
    656669        'showWithHiddenCategories' => 'false',
     
    668681
    669682      foreach ($api_posts->articles as $api_data) {
    670         $update_date_unix = strtotime($api_data->publicationDate);
     683        $update_date_unix = strtotime($api_data->updatedAt);
    671684        if ($update_date_unix > $oldest_api_post) {
    672685          $oldest_api_post = $update_date_unix;
     
    690703            $posts_table.post_modified_gmt >= %s AND
    691704            $posts_table.post_type          = %s AND
    692             $posts_table.post_status        = %s
     705            $posts_table.post_status        IN (%s, %s, %s)
    693706          ORDER BY $posts_table.post_modified_gmt ASC
    694707          LIMIT 0, %d",
     
    696709        'post',
    697710        'publish',
     711        'future',
     712        'draft',
    698713        $fetch_batch_count
    699714      );
     
    733748    foreach ($all_api_posts as $api_post) {
    734749      $api_post_id = $api_post['api_id'];
    735       if (!array_key_exists($api_post_id, $all_wp_posts)) {
     750      if (array_key_exists($api_post_id, $all_wp_posts)) {
     751        $wp_post = $all_wp_posts[$api_post_id];
     752      } else {
    736753        $raw_wp_post = get_posts([
    737754          'post_type'    => 'post',
     
    753770        $wp_post['post_name']        = $raw_wp_post->post_title;
    754771        $wp_post['update_date_unix'] = strtotime($raw_wp_post->post_modified_gmt);
    755       } else {
    756         $wp_post = $all_wp_posts[$api_post_id];
    757       }
    758 
    759       if ($api_post['update_date_unix'] > $wp_post['update_date_unix']) {
    760         $last_sync = get_post_meta($wp_post['post_id'], 'crowdaa_last_wp_to_api_sync', true) ?: 0;
    761         if ($api_post['update_date_unix'] > $last_sync) {
     772      }
     773
     774      $last_api_sync = strtotime(get_post_meta($wp_post['post_id'], 'crowdaa_last_api_update', true));
     775      $last_wp_sync = strtotime(get_post_meta($wp_post['post_id'], 'crowdaa_last_wp_update', true));
     776
     777      if ($api_post['update_date_unix'] !== $last_api_sync && $wp_post['update_date_unix'] !== $last_wp_sync) {
     778        if ($api_post['update_date_unix'] >= $wp_post['update_date_unix']) {
    762779          $result['api_to_wp'][] = $api_post;
     780        } else {
     781          $result['wp_to_api'][] = $api_post;
    763782        }
    764783        unset($all_wp_posts[$api_post_id]);
    765784        unset($all_api_posts[$api_post_id]);
    766       } elseif ($api_post['update_date_unix'] <= $wp_post['update_date_unix']) {
     785      } else if ($api_post['update_date_unix'] !== $last_api_sync) {
     786        $result['api_to_wp'][] = $api_post;
     787        unset($all_wp_posts[$api_post_id]);
     788        unset($all_api_posts[$api_post_id]);
     789      } else if ($wp_post['update_date_unix'] !== $last_wp_sync) {
     790        $result['wp_to_api'][] = $api_post;
     791        unset($all_wp_posts[$api_post_id]);
     792        unset($all_api_posts[$api_post_id]);
     793      } else {
    767794        $need_sync = get_post_meta($wp_post['post_id'], 'crowdaa_need_sync', true);
    768795        $sync_version = get_post_meta($wp_post['post_id'], 'crowdaa_version', true);
     
    10621089    delete_post_meta($post_id, 'crowdaa_need_sync');
    10631090    delete_post_meta($post_id, 'crowdaa_version');
    1064     delete_post_meta($post_id, 'crowdaa_last_wp_to_api_sync');
     1091    delete_post_meta($post_id, 'crowdaa_last_api_update');
     1092    delete_post_meta($post_id, 'crowdaa_last_wp_update');
    10651093    delete_post_meta($post_id, 'api_post_id');
    10661094  }
     
    11511179    }
    11521180    $sync_api     = new Crowdaa_Sync_API();
    1153     $sync_db      = new Crowdaa_Sync_Syncdb('categories');
     1181    $sync_db      = Crowdaa_Sync_Syncdb::instance('categories');
    11541182    $errors       = [];
    11551183
     
    12441272    $errors             = [];
    12451273    $sync_api           = new Crowdaa_Sync_API();
    1246     $cat_sync_db        = new Crowdaa_Sync_Syncdb('categories');
     1274    $cat_sync_db        = Crowdaa_Sync_Syncdb::instance('categories');
    12471275    $cat_synced_entries = $cat_sync_db->get_synced_entries();
    12481276
     
    12701298
    12711299      // Get category. On multiple categories, pick childless ones first
    1272       $child_term = false;
    12731300      $post_terms = get_the_terms($post['post_id'], 'category');
    12741301      if (empty($post_terms)) {
     
    13701397      }
    13711398
     1399      $api_whole_post = $sync_api->get_article($post['api_id']);
     1400      $wp_whole_post = get_post($post['post_id']);
     1401
    13721402      update_post_meta($post['post_id'], 'crowdaa_need_sync', 'no');
    13731403      update_post_meta($post['post_id'], 'crowdaa_version', Crowdaa_Sync_Versions::get_version());
    1374       update_post_meta($post['post_id'], 'crowdaa_last_wp_to_api_sync', time());
     1404      update_post_meta($post['post_id'], 'crowdaa_last_api_update', $api_whole_post->updatedAt);
     1405      update_post_meta($post['post_id'], 'crowdaa_last_wp_update', $wp_whole_post->post_modified_gmt);
    13751406    }
    13761407
     
    13981429  {
    13991430    $missing = [];
    1400     $result_code = null;
    1401     $output = null;
    14021431
    14031432    $default_image = get_option('default_image');
  • crowdaa-sync/tags/2.0.1/admin/class-crowdaa-sync-add-info-wp.php

    r3216233 r3229463  
    143143  ) {
    144144    $errors                = [];
    145     $sync_db               = new Crowdaa_Sync_Syncdb('categories');
     145    $sync_db               = Crowdaa_Sync_Syncdb::instance('categories');
    146146    $categories_sync_to_wp = array_merge($remove_wp, $api_to_wp, $only_api);
    147147
     
    261261  private function create_wp_post_from_api($api_data)
    262262  {
    263     $created_posts  = [];
    264     $cat_sync_db    = new Crowdaa_Sync_Syncdb('categories');
     263    $cat_sync_db    = Crowdaa_Sync_Syncdb::instance('categories');
    265264
    266265    if (isset($api_data->categories) && count($api_data->categories) > 0) {
     
    276275    }
    277276
    278     // $publicationTime = self::api_date_to_unix($api_data->publicationDate);
     277    $publicationTime = self::api_date_to_unix($api_data->publicationDate);
    279278    $post_data = [
    280279      'post_title'    => $api_data->title,
    281280      'post_content'  => $api_data->text,
    282       // 'post_date'     => date('Y-m-d H:i:s', $publicationTime),
    283       // 'post_date_gmt' => gmdate('Y-m-d H:i:s', $publicationTime),
     281      'post_date'     => date('Y-m-d H:i:s', $publicationTime),
     282      'post_date_gmt' => gmdate('Y-m-d H:i:s', $publicationTime),
    284283      'post_status'   => 'publish',
    285284      'post_type'     => 'post',
    286285      'post_author'   => get_current_user_id(),
    287286    ];
    288     // if ($publicationTime > time()) {
    289     //   $data['post_status'] = 'future';
    290     // }
     287    if ($publicationTime > time()) {
     288      $data['post_status'] = 'future';
     289    } else if (!$api_data->isPublished) {
     290      $data['post_status'] = 'draft';
     291    } else {
     292      $data['post_status'] = 'publish';
     293    }
    291294
    292295    $wp_post_id = wp_insert_post($post_data);
     
    315318    }
    316319
     320    $wp_whole_post = get_post($wp_post_id);
    317321    update_post_meta($wp_post_id, 'crowdaa_need_sync', 'no');
    318322    update_post_meta($wp_post_id, 'crowdaa_version', Crowdaa_Sync_Versions::get_version());
     323    update_post_meta($wp_post_id, 'crowdaa_last_api_update', $api_data->updatedAt);
     324    update_post_meta($wp_post_id, 'crowdaa_last_wp_update', $wp_whole_post->post_modified_gmt);
    319325
    320326    Crowdaa_Sync_Logs::log('Created WP post', $wp_post_id);
     
    323329  }
    324330
    325   // private static function api_date_to_unix($date) {
    326   //   $matches = [];
    327   //   preg_match('/^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)\.\d+Z/', $date, $matches);
    328   //   $time = gmmktime(
    329   //     intval($matches[4], 10),
    330   //     intval($matches[5], 10),
    331   //     intval($matches[6], 10),
    332   //     intval($matches[2], 10),
    333   //     intval($matches[3], 10),
    334   //     intval($matches[1], 10),
    335   //   );
    336   //   return ($time);
    337   // }
     331  private static function api_date_to_unix($date)
     332  {
     333    $matches = [];
     334    preg_match('/^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)\.\d+Z/', $date, $matches);
     335    $time = gmmktime(
     336      intval($matches[4], 10),
     337      intval($matches[5], 10),
     338      intval($matches[6], 10),
     339      intval($matches[2], 10),
     340      intval($matches[3], 10),
     341      intval($matches[1], 10),
     342    );
     343    return ($time);
     344  }
    338345
    339346  private function update_wp_post_from_api($api_data, $wp_post_id)
    340347  {
    341     $created_posts  = [];
    342     $cat_sync_db    = new Crowdaa_Sync_Syncdb('categories');
     348    $cat_sync_db    = Crowdaa_Sync_Syncdb::instance('categories');
    343349
    344350    if (isset($api_data->categories) && count($api_data->categories) > 0) {
     
    354360    }
    355361
    356     // $publicationTime = self::api_date_to_unix($api_data->publicationDate);
     362    $publicationTime = self::api_date_to_unix($api_data->publicationDate);
    357363    $data = [
    358364      'ID'            => $wp_post_id,
    359365      'post_title'    => $api_data->title,
    360366      'post_content'  => $api_data->text,
    361       // 'post_date'     => date('Y-m-d H:i:s', $publicationTime),
    362       // 'post_date_gmt' => gmdate('Y-m-d H:i:s', $publicationTime),
     367      'post_date'     => date('Y-m-d H:i:s', $publicationTime),
     368      'post_date_gmt' => gmdate('Y-m-d H:i:s', $publicationTime),
    363369    ];
    364     // if ($publicationTime > time()) {
    365     //   $data['post_status'] = 'future';
    366     // }
     370    if ($publicationTime > time()) {
     371      $data['post_status'] = 'future';
     372    } else if (!$api_data->isPublished) {
     373      $data['post_status'] = 'draft';
     374    } else {
     375      $data['post_status'] = 'publish';
     376    }
    367377
    368378    wp_set_post_terms($wp_post_id, $terms, 'category');
     
    391401    }
    392402
     403    $wp_whole_post = get_post($wp_post_id);
    393404    update_post_meta($wp_post_id, 'crowdaa_need_sync', 'no');
    394405    update_post_meta($wp_post_id, 'crowdaa_version', Crowdaa_Sync_Versions::get_version());
     406    update_post_meta($wp_post_id, 'crowdaa_last_api_update', $api_data->updatedAt);
     407    update_post_meta($wp_post_id, 'crowdaa_last_wp_update', $wp_whole_post->post_modified_gmt);
    395408
    396409    Crowdaa_Sync_Logs::log('Updated WP post', $wp_post_id, $api_data->_id);
     
    497510          ]));
    498511        } catch (\Throwable $e) {
    499           Crowdaa_Sync_Logs::log('Set WP term feed picture error', $e->getMessage());
    500512          throw new Crowdaa_Sync_Category_Error(__('Set WP term feed picture error : ', CROWDAA_SYNC_PLUGIN_NAME) . $e->getMessage());
    501513        }
     
    574586          $fetch_err = $this->get_uploads($feed_pic_url, $feed_pic_name);
    575587          if ($fetch_err) {
    576             $errors[] = $fetch_err;
     588            throw new Crowdaa_Sync_Post_Error(__('Feed image synchronization error (download) : ', CROWDAA_SYNC_PLUGIN_NAME) . $fetch_err);
    577589          }
    578590        }
     
    581593            $attachment_id = $this->set_uploads($wp_post_id, $feed_pic_name, true);
    582594          } catch (\Throwable $e) {
    583             Crowdaa_Sync_Logs::log('Set WP post feed picture error', $e->getMessage());
    584             $errors[] = $e->getMessage();
    585             return;
     595            throw new Crowdaa_Sync_Post_Error(__('Feed image synchronization error (storage) : ', CROWDAA_SYNC_PLUGIN_NAME) . $e->getMessage());
    586596          }
    587597          update_post_meta($wp_post_id, 'api_feedpicture_id', serialize([
     
    631641          $fetch_err = $this->get_uploads($image_url, $image_name);
    632642          if ($fetch_err) {
    633             $errors[] = $fetch_err;
    634             continue;
     643            throw new Crowdaa_Sync_Post_Error(__('Image synchronization error (download) : ', CROWDAA_SYNC_PLUGIN_NAME) . $fetch_err);
    635644          }
    636645        }
     
    640649          $images_map[$image_id] = $attachment_id;
    641650        } catch (\Throwable $e) {
    642           Crowdaa_Sync_Logs::log('Set WP post image error', $e->getMessage());
    643           $errors[] = $e->getMessage();
    644           continue;
     651          throw new Crowdaa_Sync_Post_Error(__('Image synchronization error (storage) : ', CROWDAA_SYNC_PLUGIN_NAME) . $e->getMessage());
    645652        }
    646653      }
     
    680687          $convert_error = $this->ffmpeg_video_converter($video->url, $video_name);
    681688          if ($convert_error) {
    682             $errors[] = $convert_error;
    683             continue;
     689            throw new Crowdaa_Sync_Post_Error(__('Video synchronization error (convert) : ', CROWDAA_SYNC_PLUGIN_NAME) . $convert_error);
    684690          }
    685691        }
     
    689695          $videos_map[$video_id] = $attachment_id;
    690696        } catch (\Throwable $e) {
    691           Crowdaa_Sync_Logs::log('Set WP post video error', $e->getMessage());
    692           $errors[] = $e->getMessage();
    693           continue;
     697          throw new Crowdaa_Sync_Post_Error(__('Video synchronization error (storage) : ', CROWDAA_SYNC_PLUGIN_NAME) . $e->getMessage());
    694698        }
    695699      }
     
    834838
    835839    try {
    836       wp_remote_get($img_url, [
     840      $ret = wp_remote_get($img_url, [
    837841        'method'          => 'GET',
    838842        'timeout'         => 45,
     
    841845        'sslcertificates' => CROWDAA_SYNC_CACERT_PATH,
    842846      ]);
     847
     848      if (is_wp_error($ret)) {
     849        return $ret->get_error_message();
     850      }
    843851
    844852      return (false);
  • crowdaa-sync/tags/2.0.1/admin/class-crowdaa-sync-admin-display.php

    r3202416 r3229463  
    4141    Crowdaa_Sync_Permissions::reset();
    4242
    43     $sync_db = new Crowdaa_Sync_Syncdb('categories');
     43    $sync_db = Crowdaa_Sync_Syncdb::instance('categories');
    4444    $sync_db->reset();
    4545
  • crowdaa-sync/tags/2.0.1/admin/class-crowdaa-sync-api.php

    r3169735 r3229463  
    254254      }
    255255
    256       $send_notification = (
    257         get_post_meta($wp_post_id, 'crowdaa_notification_send', true) === 'yes' &&
    258         get_post_meta($wp_post_id, 'crowdaa_notification_sent', true) !== 'yes'
    259       );
    260       $publish_error = $this->publish_post_draft_api(
    261         $json->draftId,
    262         $api_post_id,
    263         $publication_time,
    264         $send_notification,
    265         (get_post_meta($wp_post_id, 'crowdaa_notification_content', true) ?: null),
    266         (get_post_meta($wp_post_id, 'crowdaa_notification_title', true) ?: null),
    267       );
    268       if ($publish_error) {
    269         Crowdaa_Sync_Logs::log('Article publish error', $api_post_id, $publish_error);
    270         throw new Crowdaa_Sync_Post_Error(__('Post publish error : ', CROWDAA_SYNC_PLUGIN_NAME) . $publish_error);
    271       }
    272 
    273       if ($send_notification) {
    274         update_post_meta($wp_post_id, 'crowdaa_notification_sent', 'yes');
    275       }
    276 
    277       Crowdaa_Sync_Logs::log('Updated API article successfully', $api_post_id, $json->draftId);
    278     }
    279   }
    280 
     256      $post_status = get_post_status($wp_post_id);
     257      if ($post_status === 'draft') {
     258        Crowdaa_Sync_Logs::log('Updated API post (draft)', $json->articleId);
     259        $this->unpublish_api_article($json->articleId);
     260      } else {
     261        $send_notification = (
     262          get_post_meta($wp_post_id, 'crowdaa_notification_send', true) === 'yes' &&
     263          get_post_meta($wp_post_id, 'crowdaa_notification_sent', true) !== 'yes'
     264        );
     265        $publish_error = $this->publish_post_draft_api(
     266          $json->draftId,
     267          $api_post_id,
     268          $publication_time,
     269          $send_notification,
     270          (get_post_meta($wp_post_id, 'crowdaa_notification_content', true) ?: null),
     271          (get_post_meta($wp_post_id, 'crowdaa_notification_title', true) ?: null),
     272        );
     273        if ($publish_error) {
     274          Crowdaa_Sync_Logs::log('Article publish error', $api_post_id, $publish_error);
     275          throw new Crowdaa_Sync_Post_Error(__('Post publish error : ', CROWDAA_SYNC_PLUGIN_NAME) . $publish_error);
     276        }
     277
     278        if ($send_notification) {
     279          update_post_meta($wp_post_id, 'crowdaa_notification_sent', 'yes');
     280        }
     281
     282        Crowdaa_Sync_Logs::log('Updated API article successfully', $api_post_id, $json->draftId);
     283      }
     284    }
     285  }
     286
     287  public function unpublish_api_article($api_post_id)
     288  {
     289    $url = '/press/articles/' . rawurlencode($api_post_id) . '/unpublish';
     290    $response = $this->http_request('PUT', $url);
     291    $err    = is_wp_error($response) ? $response->get_error_message() : null;
     292    if (!$err) {
     293      $body = wp_remote_retrieve_body($response);
     294      $json = json_decode($body);
     295    }
     296
     297    if ($err) {
     298      Crowdaa_Sync_Logs::log('Unpublish article query error', $api_post_id, $err);
     299      return ((object) [
     300        'message' => $err,
     301      ]);
     302    }
     303
     304    if (isset($json->message)) {
     305      Crowdaa_Sync_Logs::log('Unpublish article error', $json->message);
     306    }
     307
     308    return ($json);
     309  }
    281310
    282311  /**
     
    541570      }
    542571
    543       $send_notification = (
    544         get_post_meta($wp_post_id, 'crowdaa_notification_send', true) === 'yes' &&
    545         get_post_meta($wp_post_id, 'crowdaa_notification_sent', true) !== 'yes'
    546       );
    547       $publish_error = $this->publish_post_draft_api(
    548         $json->draftId,
    549         $json->articleId,
    550         $publication_time,
    551         $send_notification,
    552         (get_post_meta($wp_post_id, 'crowdaa_notification_content', true) ?: null),
    553         (get_post_meta($wp_post_id, 'crowdaa_notification_title', true) ?: null),
    554       );
    555       if ($publish_error) {
    556         Crowdaa_Sync_Logs::log('Article first publish error', $json->articleId, $json->draftId, $publish_error);
    557         throw new Crowdaa_Sync_Post_Error(__('Post first publish error : ', CROWDAA_SYNC_PLUGIN_NAME) . $publish_error);
    558       }
    559 
    560       update_post_meta($wp_post_id, 'api_post_id', $json->articleId);
    561       if ($send_notification) {
    562         update_post_meta($wp_post_id, 'crowdaa_notification_sent', 'yes');
    563       }
    564       Crowdaa_Sync_Logs::log('Created API post', $json->articleId);
     572      $post_status = get_post_status($wp_post_id);
     573      if ($post_status === 'draft') {
     574        Crowdaa_Sync_Logs::log('Updated API post (draft)', $json->articleId);
     575        $this->unpublish_api_article($json->articleId);
     576      } else {
     577        $send_notification = (
     578          get_post_meta($wp_post_id, 'crowdaa_notification_send', true) === 'yes' &&
     579          get_post_meta($wp_post_id, 'crowdaa_notification_sent', true) !== 'yes'
     580        );
     581        $publish_error = $this->publish_post_draft_api(
     582          $json->draftId,
     583          $json->articleId,
     584          $publication_time,
     585          $send_notification,
     586          (get_post_meta($wp_post_id, 'crowdaa_notification_content', true) ?: null),
     587          (get_post_meta($wp_post_id, 'crowdaa_notification_title', true) ?: null),
     588        );
     589        if ($publish_error) {
     590          Crowdaa_Sync_Logs::log('Article first publish error', $json->articleId, $json->draftId, $publish_error);
     591          throw new Crowdaa_Sync_Post_Error(__('Post first publish error : ', CROWDAA_SYNC_PLUGIN_NAME) . $publish_error);
     592        }
     593
     594        update_post_meta($wp_post_id, 'api_post_id', $json->articleId);
     595        if ($send_notification) {
     596          update_post_meta($wp_post_id, 'crowdaa_notification_sent', 'yes');
     597        }
     598
     599        Crowdaa_Sync_Logs::log('Created API post', $json->articleId);
     600      }
     601
     602      return $json->articleId;
    565603    }
    566604  }
  • crowdaa-sync/tags/2.0.1/admin/partials/crowdaa-sync-admin-display.php

    r3169735 r3229463  
    198198        <br />
    199199        <?php wp_nonce_field('crowdaa_cron_sync_enabled_data', 'crowdaa_cron_sync_enabled'); ?>
    200         <?php submit_button('Save parameters'); ?>
     200        <?php submit_button(__('Save parameters', CROWDAA_SYNC_PLUGIN_NAME)); ?>
    201201      </form>
    202202    </div>
     
    221221        <input type="file" required name="file" id="image_file" accept=".jpg, .jpeg, .png" />
    222222        <?php
    223         submit_button('Save picture');
     223        submit_button(__('Save picture', CROWDAA_SYNC_PLUGIN_NAME));
    224224        ?>
    225225      </form>
     
    275275        <?php wp_nonce_field('crowdaa_set_sync_categories_data', 'crowdaa_set_sync_categories'); ?>
    276276        <?php
    277         submit_button('Save mode & categories');
     277        submit_button(__('Save mode & categories', CROWDAA_SYNC_PLUGIN_NAME));
    278278        ?>
    279279      </form>
     
    323323        <?php wp_nonce_field('crowdaa_set_feed_categories_data', 'crowdaa_set_feed_categories'); ?>
    324324        <?php
    325         submit_button('Save feed categories');
     325        submit_button(__('Save feed categories', CROWDAA_SYNC_PLUGIN_NAME));
    326326        ?>
    327327      </form>
  • crowdaa-sync/tags/2.0.1/crowdaa-sync.php

    r3218183 r3229463  
    1414 * Plugin URI:       
    1515 * Description:       Plugin for synchronizing WordPress site and Crowdaa CMS
    16  * Version:           1.10.8
     16 * Version:           2.0.1
    1717 * Requires at least: 5.5
    1818 * Requires PHP:      7.2
     
    3434 * Uses SemVer - https://semver.org
    3535 */
    36 define('CROWDAA_SYNC_VERSION', '1.10.8');
     36define('CROWDAA_SYNC_VERSION', '2.0.1');
    3737define('CROWDAA_SYNC_PLUGIN_DIR', __DIR__);
    3838define('CROWDAA_SYNC_PLUGIN_NAME', 'crowdaa-sync');
     
    4444 * Just bump the version, it will handle the rest.
    4545 */
    46 define('CROWDAA_SYNC_META_VERSION', '3');
     46define('CROWDAA_SYNC_META_VERSION', '4');
    4747
    4848$last_version = get_option('crowdaa_last_version', false);
  • crowdaa-sync/tags/2.0.1/includes/class-crowdaa-sync-exception.php

    r3149200 r3229463  
    1111 */
    1212
     13class Crowdaa_Sync_Generic_Exception extends Exception
     14{
     15  public function __construct($message = 'NO_MESSAGE_GIVEN', ...$extra)
     16  {
     17    parent::__construct($message);
     18
     19    $to_log = $message;
     20    if ($extra) {
     21      foreach ($extra as $item) {
     22        if (!is_string($item)) {
     23          $to_log .= '|' . print_r($item, true);
     24        } else {
     25          $to_log .= '|' . $item;
     26        }
     27      }
     28    }
     29
     30    Crowdaa_Sync_Logs::log((new \ReflectionClass($this))->getShortName(), '__construct() called with', $to_log);
     31  }
     32}
     33
    1334/**
    1435 * The base project exception, when a fatal error occurs.
     
    2142 * @author     Crowdaa <contact@crowdaa.com>
    2243 */
    23 class Crowdaa_Sync_Error extends Exception
    24 {
    25 }
     44class Crowdaa_Sync_Error extends Crowdaa_Sync_Generic_Exception {}
    2645
    2746/**
     
    3352 * @author     Crowdaa <contact@crowdaa.com>
    3453 */
    35 class Crowdaa_Sync_Badge_Error extends Exception
    36 {
    37 }
     54class Crowdaa_Sync_Badge_Error extends Crowdaa_Sync_Generic_Exception {}
    3855
    3956/**
     
    4562 * @author     Crowdaa <contact@crowdaa.com>
    4663 */
    47 class Crowdaa_Sync_Category_Error extends Exception
    48 {
    49 }
     64class Crowdaa_Sync_Category_Error extends Crowdaa_Sync_Generic_Exception {}
    5065
    5166/**
     
    5772 * @author     Crowdaa <contact@crowdaa.com>
    5873 */
    59 class Crowdaa_Sync_Post_Error extends Exception
    60 {
    61 }
     74class Crowdaa_Sync_Post_Error extends Crowdaa_Sync_Generic_Exception {}
    6275
    6376/**
     
    6982 * @author     Crowdaa <contact@crowdaa.com>
    7083 */
    71 class Crowdaa_Sync_Post_Skip_Error extends Crowdaa_Sync_Post_Error
    72 {
    73 }
     84class Crowdaa_Sync_Post_Skip_Error extends Crowdaa_Sync_Post_Error {}
    7485
    7586/**
     
    8192 * @author     Crowdaa <contact@crowdaa.com>
    8293 */
    83 class Crowdaa_Sync_Timeout_Error extends Exception
    84 {
    85 }
     94class Crowdaa_Sync_Timeout_Error extends Crowdaa_Sync_Generic_Exception {}
  • crowdaa-sync/tags/2.0.1/includes/class-crowdaa-sync-permissions.php

    r3179247 r3229463  
    129129  public static function sync_db()
    130130  {
    131     return (new Crowdaa_Sync_Syncdb('user_badges'));
     131    return (Crowdaa_Sync_Syncdb::instance('user_badges'));
    132132  }
    133133
  • crowdaa-sync/tags/2.0.1/includes/class-crowdaa-sync-syncdb.php

    r3195042 r3229463  
    1616  private static $loaded = array();
    1717
     18  public static function instance($tableName)
     19  {
     20    switch ($tableName) {
     21      case 'categories':
     22      case 'user_badges':
     23        return new self($tableName, CROWDAA_SYNC_META_VERSION);
     24        break;
     25      default:
     26        return new self($tableName);
     27        break;
     28    }
     29  }
     30
    1831  /**
    1932   * Initialize the database.
     
    4962  }
    5063
     64  public function get_version()
     65  {
     66    return $this->version;
     67  }
     68
    5169  /**
    5270   * Returns an assoc array of synced elements, with the provided fields (null means all)
     
    151169      if (isset($v->sync_data)) {
    152170        $v->sync_data = unserialize($v->sync_data);
     171      } else {
     172        $v->sync_data = [];
    153173      }
    154174    }
     
    266286    return (array_pop($result));
    267287  }
     288
     289  /**
     290   * Delete an entry with the specified internal ID.
     291   */
     292  public function delete_entry_with_id($id)
     293  {
     294    global $wpdb;
     295
     296    list($whereStr, $whereArg) = self::prepare_wherein($id, 'id');
     297
     298    $wpdb->get_results($wpdb->prepare("DELETE FROM `$this->tableName` WHERE $whereStr", ...$whereArg), OBJECT_K);
     299  }
    268300}
  • crowdaa-sync/tags/2.0.1/languages/crowdaa-sync-fr_FR.po

    r3169735 r3229463  
    33"Project-Id-Version: WpCrowdaaSyncTranslations\n"
    44"Report-Msgid-Bugs-To: \n"
    5 "POT-Creation-Date: 2024-10-15 17:46+0400\n"
    6 "PO-Revision-Date: 2024-10-15 17:47+0400\n"
     5"POT-Creation-Date: 2024-12-16 10:58+0400\n"
     6"PO-Revision-Date: 2024-12-16 11:05+0400\n"
    77"Last-Translator: \n"
    88"Language-Team: Français\n"
     
    1212"Content-Transfer-Encoding: 8bit\n"
    1313"Plural-Forms: nplurals=2; plural=(n > 1);\n"
    14 "X-Generator: Poedit 3.2.2\n"
     14"X-Generator: Poedit 3.4.2\n"
    1515"X-Poedit-Basepath: ..\n"
    1616"X-Poedit-KeywordsList: __;_e;esc_html_e;esc_attr_e\n"
     
    2424
    2525#: admin/class-crowdaa-sync-add-info-api.php:217
    26 #: admin/class-crowdaa-sync-add-info-api.php:630
     26#: admin/class-crowdaa-sync-add-info-api.php:643
    2727msgid "User is not connected"
    2828msgstr "Utilisateur non connecté"
    2929
    3030#: admin/class-crowdaa-sync-add-info-api.php:245
    31 #: admin/class-crowdaa-sync-add-info-api.php:372
    32 #: admin/class-crowdaa-sync-add-info-api.php:660
     31#: admin/class-crowdaa-sync-add-info-api.php:378
     32#: admin/class-crowdaa-sync-add-info-api.php:674
    3333msgid "API query error : "
    3434msgstr "Erreur de requête d'API :"
    3535
    36 #: admin/class-crowdaa-sync-add-info-api.php:827
     36#: admin/class-crowdaa-sync-add-info-api.php:855
    3737msgid "The synchronization cannot be done, missing dependencies : "
    3838msgstr "La synchronisation ne peut se faire, dépendances manquantes :"
    3939
    40 #: admin/class-crowdaa-sync-add-info-api.php:832
     40#: admin/class-crowdaa-sync-add-info-api.php:860
    4141msgid "Cannot run : a synchronization is already running"
    4242msgstr "Une synchronisation est déjà en cours, merci de réessayer plus tard"
    4343
    44 #: admin/class-crowdaa-sync-add-info-api.php:966
     44#: admin/class-crowdaa-sync-add-info-api.php:994
    4545msgid "Some errors happened during synchronization : "
    4646msgstr "Des erreurs ont eu lieu pendant la synchronisation :"
    4747
    48 #: admin/class-crowdaa-sync-add-info-api.php:969
     48#: admin/class-crowdaa-sync-add-info-api.php:997
    4949msgid "All data synced successfully"
    5050msgstr "Données synchronisées avec succès"
    5151
    52 #: admin/class-crowdaa-sync-add-info-api.php:974
     52#: admin/class-crowdaa-sync-add-info-api.php:1002
    5353msgid ""
    5454"The synchronization process timed out, please retry it until it succeeds."
     
    5757"relancer jusqu'à ce que qu'elle se termine entièrement."
    5858
    59 #: admin/class-crowdaa-sync-add-info-api.php:976
     59#: admin/class-crowdaa-sync-add-info-api.php:1004
    6060msgid "Uncaught Post synchronization error : "
    61 msgstr ""
    62 
    63 #: admin/class-crowdaa-sync-add-info-api.php:978
     61msgstr "Erreur non rattrapée de synchronsation de post : "
     62
     63#: admin/class-crowdaa-sync-add-info-api.php:1006
    6464msgid "Category synchronization error : "
    65 msgstr ""
    66 
    67 #: admin/class-crowdaa-sync-add-info-api.php:980
     65msgstr "Erreur de synchronisation de catégorie : "
     66
     67#: admin/class-crowdaa-sync-add-info-api.php:1008
    6868msgid "Badge synchronization error : "
    69 msgstr ""
    70 
    71 #: admin/class-crowdaa-sync-add-info-api.php:982
     69msgstr "Erreur de synchronisation de badge : "
     70
     71#: admin/class-crowdaa-sync-add-info-api.php:1010
    7272msgid "Fatal synchronization error : "
    73 msgstr ""
    74 
    75 #: admin/class-crowdaa-sync-add-info-api.php:984
     73msgstr "Erreur de synchronisation fatale : "
     74
     75#: admin/class-crowdaa-sync-add-info-api.php:1012
    7676msgid "Unknown synchronzation error : "
    77 msgstr ""
    78 
    79 #: admin/class-crowdaa-sync-add-info-wp.php:490
     77msgstr "Erreur de synchronisation inconnue : "
     78
     79#: admin/class-crowdaa-sync-add-info-wp.php:501
    8080msgid "Errors when downloading term image for "
    81 msgstr ""
    82 
    83 #: admin/class-crowdaa-sync-add-info-wp.php:502
     81msgstr "Erreur de téléchargement de l'image de catégorie pour "
     82
     83#: admin/class-crowdaa-sync-add-info-wp.php:512
    8484msgid "Set WP term feed picture error : "
    85 msgstr ""
    86 
    87 #: admin/class-crowdaa-sync-add-info-wp.php:869
     85msgstr "Erreur de définition de l'image du feed :"
     86
     87#: admin/class-crowdaa-sync-add-info-wp.php:588
     88msgid "Feed image synchronization error (download) : "
     89msgstr "Erreur de synchronisation de l'image du feed (téléchargement) :"
     90
     91#: admin/class-crowdaa-sync-add-info-wp.php:595
     92msgid "Feed image synchronization error (storage) : "
     93msgstr "Erreur de synchronisation de l'image du feed (stockage) :"
     94
     95#: admin/class-crowdaa-sync-add-info-wp.php:643
     96msgid "Image synchronization error (download) : "
     97msgstr "Erreur de synchronisation d'image (téléchargement) :"
     98
     99#: admin/class-crowdaa-sync-add-info-wp.php:651
     100msgid "Image synchronization error (storage) : "
     101msgstr "Erreur de synchronisation d'image (stockage) :"
     102
     103#: admin/class-crowdaa-sync-add-info-wp.php:689
     104msgid "Video synchronization error (convert) : "
     105msgstr "Erreur de synchronisation de vidéo (conversion) :"
     106
     107#: admin/class-crowdaa-sync-add-info-wp.php:697
     108msgid "Video synchronization error (storage) : "
     109msgstr "Erreur de synchronisation de vidéo (stockage) :"
     110
     111#: admin/class-crowdaa-sync-add-info-wp.php:875
    88112msgid ""
    89113"You don't have ffmpeg installed on your server to download videos, please "
     
    94118"hébergeur"
    95119
    96 #: admin/class-crowdaa-sync-admin-display.php:197
    97 #: admin/class-crowdaa-sync-admin-display.php:208
     120#: admin/class-crowdaa-sync-admin-display.php:205
     121#: admin/class-crowdaa-sync-admin-display.php:216
    98122msgid "Failed to get data. Please try again later"
    99123msgstr "Communication réseau impossible, merci de réessayer ultérieurement"
    100124
    101 #: admin/class-crowdaa-sync-admin-display.php:219
     125#: admin/class-crowdaa-sync-admin-display.php:227
    102126msgid "Data is incorrect please double-check and try again"
    103127msgstr "Les données sont incorrectes, merci de vérifier les paramètres fournis"
    104128
    105 #: admin/class-crowdaa-sync-admin-display.php:247
     129#: admin/class-crowdaa-sync-admin-display.php:255
    106130msgid "Failed to complete login initialization process"
    107131msgstr "Échec d'initialisation du plugin, merci de réessayer"
    108132
    109 #: admin/class-crowdaa-sync-admin-display.php:254
     133#: admin/class-crowdaa-sync-admin-display.php:262
    110134msgid "You are successfully logged in"
    111135msgstr "Vous êtes connecté!"
    112136
    113 #: admin/class-crowdaa-sync-admin-display.php:265
     137#: admin/class-crowdaa-sync-admin-display.php:273
    114138msgid "Please, provide all user data"
    115139msgstr "Merci de remplir tous les champs demandés"
    116140
    117 #: admin/class-crowdaa-sync-api.php:184 admin/class-crowdaa-sync-api.php:336
    118 #: admin/class-crowdaa-sync-api.php:398 admin/class-crowdaa-sync-api.php:466
     141#: admin/class-crowdaa-sync-api.php:184 admin/class-crowdaa-sync-api.php:341
     142#: admin/class-crowdaa-sync-api.php:403 admin/class-crowdaa-sync-api.php:471
    119143msgid "Not connected to the API"
    120144msgstr "Non connecté"
    121145
    122 #: admin/class-crowdaa-sync-api.php:195 admin/class-crowdaa-sync-api.php:478
     146#: admin/class-crowdaa-sync-api.php:195 admin/class-crowdaa-sync-api.php:483
    123147msgid "Cannot sync article without any image or video!"
    124148msgstr "Impossible de synchroniser un article sans image ou vidéo!"
    125149
    126 #: admin/class-crowdaa-sync-api.php:206 admin/class-crowdaa-sync-api.php:489
     150#: admin/class-crowdaa-sync-api.php:206 admin/class-crowdaa-sync-api.php:494
    127151msgid "Without title"
    128152msgstr "Sans titre"
    129153
    130 #: admin/class-crowdaa-sync-api.php:213 admin/class-crowdaa-sync-api.php:495
     154#: admin/class-crowdaa-sync-api.php:213 admin/class-crowdaa-sync-api.php:500
    131155msgid "Without content"
    132156msgstr "Sans contenu"
     
    140164msgstr ""
    141165
    142 #: admin/class-crowdaa-sync-api.php:270 admin/class-crowdaa-sync-api.php:441
     166#: admin/class-crowdaa-sync-api.php:274 admin/class-crowdaa-sync-api.php:446
    143167msgid "Post publish error : "
    144168msgstr ""
    145169
    146 #: admin/class-crowdaa-sync-api.php:340
     170#: admin/class-crowdaa-sync-api.php:345
    147171msgid "Unable to create article without Category"
    148172msgstr ""
    149173
    150 #: admin/class-crowdaa-sync-api.php:344 admin/class-crowdaa-sync-api.php:406
     174#: admin/class-crowdaa-sync-api.php:349 admin/class-crowdaa-sync-api.php:411
    151175msgid "Cannot sync article without any image and video!"
    152176msgstr ""
    153177
    154 #: admin/class-crowdaa-sync-api.php:348 admin/class-crowdaa-sync-api.php:410
     178#: admin/class-crowdaa-sync-api.php:353 admin/class-crowdaa-sync-api.php:415
    155179msgid "Cannot sync article without any title or content!"
    156180msgstr ""
    157181
    158 #: admin/class-crowdaa-sync-api.php:362
     182#: admin/class-crowdaa-sync-api.php:367
    159183#, php-format
    160184msgid "Custom article creation error, query response : %s"
    161185msgstr ""
    162186
    163 #: admin/class-crowdaa-sync-api.php:365
     187#: admin/class-crowdaa-sync-api.php:370
    164188#, php-format
    165189msgid "Custom article creation error, response : %s"
    166190msgstr ""
    167191
    168 #: admin/class-crowdaa-sync-api.php:368
     192#: admin/class-crowdaa-sync-api.php:373
    169193#, php-format
    170194msgid "Custom article creation error, API response : %s"
    171195msgstr ""
    172196
    173 #: admin/class-crowdaa-sync-api.php:379 admin/class-crowdaa-sync-api.php:557
     197#: admin/class-crowdaa-sync-api.php:384 admin/class-crowdaa-sync-api.php:566
    174198msgid "Post first publish error : "
    175199msgstr ""
    176200
    177 #: admin/class-crowdaa-sync-api.php:402
     201#: admin/class-crowdaa-sync-api.php:407
    178202msgid "Unable to update article without Category"
    179203msgstr ""
    180204
    181 #: admin/class-crowdaa-sync-api.php:424
     205#: admin/class-crowdaa-sync-api.php:429
    182206#, php-format
    183207msgid "Custom article update error, query response : %s"
    184208msgstr ""
    185209
    186 #: admin/class-crowdaa-sync-api.php:427
     210#: admin/class-crowdaa-sync-api.php:432
    187211#, php-format
    188212msgid "Custom article update error, response : %s"
    189213msgstr ""
    190214
    191 #: admin/class-crowdaa-sync-api.php:430
     215#: admin/class-crowdaa-sync-api.php:435
    192216#, php-format
    193217msgid "Custom article update error, API response : %s"
    194218msgstr ""
    195219
    196 #: admin/class-crowdaa-sync-api.php:461
     220#: admin/class-crowdaa-sync-api.php:466
    197221msgid "Unable to sync article without Category or Media in Gallery"
    198222msgstr ""
    199223
    200 #: admin/class-crowdaa-sync-api.php:533
     224#: admin/class-crowdaa-sync-api.php:538
    201225#, php-format
    202226msgid "Post creation error for wp post %d, query response : %s"
    203227msgstr ""
    204228
    205 #: admin/class-crowdaa-sync-api.php:536
     229#: admin/class-crowdaa-sync-api.php:541
    206230#, php-format
    207231msgid "Post creation error for wp post %d, response : %s"
    208232msgstr ""
    209233
    210 #: admin/class-crowdaa-sync-api.php:540
     234#: admin/class-crowdaa-sync-api.php:545
    211235#, php-format
    212236msgid "Post creation error for wp post %d, API response : %s"
    213237msgstr ""
    214238
    215 #: admin/class-crowdaa-sync-api.php:587
     239#: admin/class-crowdaa-sync-api.php:600
    216240msgid "Default article image not set"
    217241msgstr "L'image par défaut n'est pas définie"
    218242
    219 #: admin/class-crowdaa-sync-api.php:607
     243#: admin/class-crowdaa-sync-api.php:620
    220244msgid "Missing featured image on post, skipping"
    221245msgstr ""
    222246
    223 #: admin/class-crowdaa-sync-api.php:611 admin/class-crowdaa-sync-api.php:672
     247#: admin/class-crowdaa-sync-api.php:624 admin/class-crowdaa-sync-api.php:685
    224248msgid "Image synchronization error : "
    225249msgstr ""
    226250
    227 #: admin/class-crowdaa-sync-api.php:667
     251#: admin/class-crowdaa-sync-api.php:680
    228252msgid "Missing gallery image/video on post, skipping"
    229253msgstr ""
    230254
    231 #: admin/class-crowdaa-sync-api.php:697
     255#: admin/class-crowdaa-sync-api.php:710
    232256msgid "No picture could be synchronized for post "
    233257msgstr ""
    234258
    235 #: admin/class-crowdaa-sync-api.php:743
     259#: admin/class-crowdaa-sync-api.php:756
    236260msgid "Not logged in"
    237261msgstr "Non connecté"
    238262
    239 #: admin/class-crowdaa-sync-api.php:908
     263#: admin/class-crowdaa-sync-api.php:921
    240264msgid "Query error during badge creation : "
    241265msgstr ""
    242266
    243 #: admin/class-crowdaa-sync-api.php:912
     267#: admin/class-crowdaa-sync-api.php:925
    244268msgid "API error during badge creation : "
    245269msgstr ""
    246270
    247 #: admin/class-crowdaa-sync-api.php:942
     271#: admin/class-crowdaa-sync-api.php:955
    248272msgid "Query error during badge update : "
    249273msgstr ""
    250274
    251 #: admin/class-crowdaa-sync-api.php:946
     275#: admin/class-crowdaa-sync-api.php:959
    252276msgid "API error during badge update : "
    253277msgstr ""
    254278
    255 #: admin/class-crowdaa-sync-api.php:966
     279#: admin/class-crowdaa-sync-api.php:979
    256280msgid "Query error during badge delete : "
    257281msgstr ""
    258282
    259 #: admin/class-crowdaa-sync-api.php:970
     283#: admin/class-crowdaa-sync-api.php:983
    260284msgid "API error during badge delete : "
    261285msgstr ""
    262286
    263 #: admin/class-crowdaa-sync-api.php:1000
     287#: admin/class-crowdaa-sync-api.php:1013
    264288msgid "Errors when uploading category image for "
    265289msgstr ""
    266290
    267 #: admin/class-crowdaa-sync-api.php:1061
     291#: admin/class-crowdaa-sync-api.php:1074
    268292msgid "Query error during category creation : "
    269293msgstr ""
    270294
    271 #: admin/class-crowdaa-sync-api.php:1065
     295#: admin/class-crowdaa-sync-api.php:1078
    272296msgid "API error during category creation : "
    273297msgstr ""
    274298
    275 #: admin/class-crowdaa-sync-api.php:1119
     299#: admin/class-crowdaa-sync-api.php:1132
    276300msgid "Query error during category update : "
    277301msgstr ""
    278302
    279 #: admin/class-crowdaa-sync-api.php:1123
     303#: admin/class-crowdaa-sync-api.php:1136
    280304msgid "API error during category update : "
    281305msgstr ""
    282306
    283 #: admin/class-crowdaa-sync-api.php:1158
     307#: admin/class-crowdaa-sync-api.php:1171
    284308msgid "Query error during category delete : "
    285309msgstr ""
    286310
    287 #: admin/class-crowdaa-sync-api.php:1162
     311#: admin/class-crowdaa-sync-api.php:1175
    288312msgid "API error during category delete : "
    289313msgstr ""
     
    457481#: admin/class-crowdaa-sync-wp-hooks.php:95
    458482msgid "Event category"
    459 msgstr ""
     483msgstr "Catégorie d'événements"
    460484
    461485#: admin/class-crowdaa-sync-wp-hooks.php:83
     
    465489"dates)"
    466490msgstr ""
     491"Si cette catégorie contient des événements (posts avec une date de début et "
     492"de fin d'événement)"
    467493
    468494#: admin/class-crowdaa-sync-wp-hooks.php:152
     
    590616msgstr "Plugin de permissions utilisé"
    591617
     618#: admin/partials/crowdaa-sync-admin-display.php:200
     619msgid "Save parameters"
     620msgstr "Enregistrer les paramètres"
     621
    592622#: admin/partials/crowdaa-sync-admin-display.php:206
    593623msgid "Add default picture to the Gallery"
    594624msgstr "Ajouter une image par défaut"
    595625
     626#: admin/partials/crowdaa-sync-admin-display.php:223
     627msgid "Save picture"
     628msgstr "Enregistrer l'image"
     629
    596630#: admin/partials/crowdaa-sync-admin-display.php:231
    597631msgid "Set categories to synchronize"
     
    631665msgstr ""
    632666
     667#: admin/partials/crowdaa-sync-admin-display.php:277
     668msgid "Save mode & categories"
     669msgstr "Enregistrer le mode et les catégories"
     670
    633671#: admin/partials/crowdaa-sync-admin-display.php:285
    634672msgid "Set feed (front-page) categories"
     
    645683"principale."
    646684
     685#: admin/partials/crowdaa-sync-admin-display.php:325
     686msgid "Save feed categories"
     687msgstr "Enregistrer les catégories du feed"
     688
    647689#: admin/partials/crowdaa-sync-admin-display.php:334
    648690msgid "Synchronization"
  • crowdaa-sync/trunk/CHANGELOG

    r3218183 r3229463  
    88## [Unreleased]
    99
    10 ## [1.10.8] - 2025-01-07
    11 
    12 ### Changed
    13 
    14 - Preventing Crowdaa API post deletion when WP>API sync is not enabled
    15 
    16 ## [1.10.7] - 2025-01-03
    17 
    18 ### Changed
    19 
    20 - Fixed order of synchronization steps to remove elements before adding others, to avoid conflicts
     10## [2.0.1] - 2025-01-27
     11
     12### Changed
     13
     14- Added missing translations
     15- Now removing items first before adding new ones (categories, badges) to avoid duplicate issues
     16- Fixed an issue with articles unpublishing from WP to the API
     17- Preventing API posts deletion when deleting from WP when the WP>API sync is not enabled
     18
     19## [2.0.0] - 2024-12-13
     20
     21This is marked as a major release beacause it will force a full re-synchronization of all articles. There are no breaking changes other than that.
     22
     23### Changed
     24
     25- Reworked the synchronization process to use the update date from the API instead of the publication dates. It allows to :
     26- Synchronize unpublished articles and articles published at a future date both ways
    2127
    2228## [1.10.6] - 2024-12-04
  • crowdaa-sync/trunk/README.txt

    r3218183 r3229463  
    66Requires PHP: 7.3
    77Tested up to: 5.9
    8 Stable tag: 1.10.8
     8Stable tag: 2.0.1
    99License: GPLv2 or later
    1010License URI: http://www.gnu.org/licenses/gpl-2.0.html
  • crowdaa-sync/trunk/admin/class-crowdaa-sync-add-info-api.php

    r3216233 r3229463  
    279279          ];
    280280        } else if (
    281           $synced_by_wp_id[$id]->permission_hash !== $permission->hash &&
     281          (
     282            $synced_by_wp_id[$id]->permission_hash !== $permission->hash ||
     283            $sync_db->get_version() !== $synced_by_wp_id[$id]->sync_version
     284          ) &&
    282285          isset($badges_by_id[$synced_by_wp_id[$id]->api_id])
    283286        ) {
     
    315318          ];
    316319        } else if (
    317           $synced_by_api_id[$id]->badge_hash !== $badge->hash &&
     320          (
     321            $synced_by_api_id[$id]->badge_hash !== $badge->hash ||
     322            $sync_db->get_version() !== $synced_by_api_id[$id]->sync_version
     323          ) &&
    318324          isset($permissions_by_id[$synced_by_api_id[$id]->wp_id])
    319325        ) {
     
    365371    $categories_by_id = [];
    366372    $sync_api         = new Crowdaa_Sync_API();
    367     $sync_db          = new Crowdaa_Sync_Syncdb('categories');
     373    $sync_db          = Crowdaa_Sync_Syncdb::instance('categories');
    368374    $synced           = $sync_db->get_synced_entries();
    369375    $all_categories   = $sync_api->get_categories();
     
    532538              ];
    533539            } else if (
    534               $synced_by_wp_id[$id]->term_hash !== $term->hash &&
     540              (
     541                $synced_by_wp_id[$id]->term_hash !== $term->hash ||
     542                $sync_db->get_version() !== $synced_by_wp_id[$id]->sync_version
     543              ) &&
    535544              isset($categories_by_id[$synced_by_wp_id[$id]->api_id])
    536545            ) {
     
    578587              ];
    579588            } else if (
    580               $synced_by_api_id[$id]->category_hash !== $category->hash &&
     589              (
     590                $synced_by_api_id[$id]->category_hash !== $category->hash ||
     591                $sync_db->get_version() !== $synced_by_api_id[$id]->sync_version
     592              ) &&
    581593              isset($terms_by_id[$synced_by_api_id[$id]->wp_id])
    582594            ) {
     
    648660        'start' => '0',
    649661        'limit' => $fetch_batch_count,
     662        'sortBy' => 'updatedAt',
    650663        'getAuthors' => 'false',
    651664        'getDrafts' => 'false',
    652665        'getOrphansArticles' => 'false',
    653666        'getPictures' => 'false',
    654         'onlyPublished' => 'true',
     667        'onlyPublished' => 'false',
    655668        'showHiddenOnFeed' => 'true',
    656669        'showWithHiddenCategories' => 'false',
     
    668681
    669682      foreach ($api_posts->articles as $api_data) {
    670         $update_date_unix = strtotime($api_data->publicationDate);
     683        $update_date_unix = strtotime($api_data->updatedAt);
    671684        if ($update_date_unix > $oldest_api_post) {
    672685          $oldest_api_post = $update_date_unix;
     
    690703            $posts_table.post_modified_gmt >= %s AND
    691704            $posts_table.post_type          = %s AND
    692             $posts_table.post_status        = %s
     705            $posts_table.post_status        IN (%s, %s, %s)
    693706          ORDER BY $posts_table.post_modified_gmt ASC
    694707          LIMIT 0, %d",
     
    696709        'post',
    697710        'publish',
     711        'future',
     712        'draft',
    698713        $fetch_batch_count
    699714      );
     
    733748    foreach ($all_api_posts as $api_post) {
    734749      $api_post_id = $api_post['api_id'];
    735       if (!array_key_exists($api_post_id, $all_wp_posts)) {
     750      if (array_key_exists($api_post_id, $all_wp_posts)) {
     751        $wp_post = $all_wp_posts[$api_post_id];
     752      } else {
    736753        $raw_wp_post = get_posts([
    737754          'post_type'    => 'post',
     
    753770        $wp_post['post_name']        = $raw_wp_post->post_title;
    754771        $wp_post['update_date_unix'] = strtotime($raw_wp_post->post_modified_gmt);
    755       } else {
    756         $wp_post = $all_wp_posts[$api_post_id];
    757       }
    758 
    759       if ($api_post['update_date_unix'] > $wp_post['update_date_unix']) {
    760         $last_sync = get_post_meta($wp_post['post_id'], 'crowdaa_last_wp_to_api_sync', true) ?: 0;
    761         if ($api_post['update_date_unix'] > $last_sync) {
     772      }
     773
     774      $last_api_sync = strtotime(get_post_meta($wp_post['post_id'], 'crowdaa_last_api_update', true));
     775      $last_wp_sync = strtotime(get_post_meta($wp_post['post_id'], 'crowdaa_last_wp_update', true));
     776
     777      if ($api_post['update_date_unix'] !== $last_api_sync && $wp_post['update_date_unix'] !== $last_wp_sync) {
     778        if ($api_post['update_date_unix'] >= $wp_post['update_date_unix']) {
    762779          $result['api_to_wp'][] = $api_post;
     780        } else {
     781          $result['wp_to_api'][] = $api_post;
    763782        }
    764783        unset($all_wp_posts[$api_post_id]);
    765784        unset($all_api_posts[$api_post_id]);
    766       } elseif ($api_post['update_date_unix'] <= $wp_post['update_date_unix']) {
     785      } else if ($api_post['update_date_unix'] !== $last_api_sync) {
     786        $result['api_to_wp'][] = $api_post;
     787        unset($all_wp_posts[$api_post_id]);
     788        unset($all_api_posts[$api_post_id]);
     789      } else if ($wp_post['update_date_unix'] !== $last_wp_sync) {
     790        $result['wp_to_api'][] = $api_post;
     791        unset($all_wp_posts[$api_post_id]);
     792        unset($all_api_posts[$api_post_id]);
     793      } else {
    767794        $need_sync = get_post_meta($wp_post['post_id'], 'crowdaa_need_sync', true);
    768795        $sync_version = get_post_meta($wp_post['post_id'], 'crowdaa_version', true);
     
    10621089    delete_post_meta($post_id, 'crowdaa_need_sync');
    10631090    delete_post_meta($post_id, 'crowdaa_version');
    1064     delete_post_meta($post_id, 'crowdaa_last_wp_to_api_sync');
     1091    delete_post_meta($post_id, 'crowdaa_last_api_update');
     1092    delete_post_meta($post_id, 'crowdaa_last_wp_update');
    10651093    delete_post_meta($post_id, 'api_post_id');
    10661094  }
     
    11511179    }
    11521180    $sync_api     = new Crowdaa_Sync_API();
    1153     $sync_db      = new Crowdaa_Sync_Syncdb('categories');
     1181    $sync_db      = Crowdaa_Sync_Syncdb::instance('categories');
    11541182    $errors       = [];
    11551183
     
    12441272    $errors             = [];
    12451273    $sync_api           = new Crowdaa_Sync_API();
    1246     $cat_sync_db        = new Crowdaa_Sync_Syncdb('categories');
     1274    $cat_sync_db        = Crowdaa_Sync_Syncdb::instance('categories');
    12471275    $cat_synced_entries = $cat_sync_db->get_synced_entries();
    12481276
     
    12701298
    12711299      // Get category. On multiple categories, pick childless ones first
    1272       $child_term = false;
    12731300      $post_terms = get_the_terms($post['post_id'], 'category');
    12741301      if (empty($post_terms)) {
     
    13701397      }
    13711398
     1399      $api_whole_post = $sync_api->get_article($post['api_id']);
     1400      $wp_whole_post = get_post($post['post_id']);
     1401
    13721402      update_post_meta($post['post_id'], 'crowdaa_need_sync', 'no');
    13731403      update_post_meta($post['post_id'], 'crowdaa_version', Crowdaa_Sync_Versions::get_version());
    1374       update_post_meta($post['post_id'], 'crowdaa_last_wp_to_api_sync', time());
     1404      update_post_meta($post['post_id'], 'crowdaa_last_api_update', $api_whole_post->updatedAt);
     1405      update_post_meta($post['post_id'], 'crowdaa_last_wp_update', $wp_whole_post->post_modified_gmt);
    13751406    }
    13761407
     
    13981429  {
    13991430    $missing = [];
    1400     $result_code = null;
    1401     $output = null;
    14021431
    14031432    $default_image = get_option('default_image');
  • crowdaa-sync/trunk/admin/class-crowdaa-sync-add-info-wp.php

    r3216233 r3229463  
    143143  ) {
    144144    $errors                = [];
    145     $sync_db               = new Crowdaa_Sync_Syncdb('categories');
     145    $sync_db               = Crowdaa_Sync_Syncdb::instance('categories');
    146146    $categories_sync_to_wp = array_merge($remove_wp, $api_to_wp, $only_api);
    147147
     
    261261  private function create_wp_post_from_api($api_data)
    262262  {
    263     $created_posts  = [];
    264     $cat_sync_db    = new Crowdaa_Sync_Syncdb('categories');
     263    $cat_sync_db    = Crowdaa_Sync_Syncdb::instance('categories');
    265264
    266265    if (isset($api_data->categories) && count($api_data->categories) > 0) {
     
    276275    }
    277276
    278     // $publicationTime = self::api_date_to_unix($api_data->publicationDate);
     277    $publicationTime = self::api_date_to_unix($api_data->publicationDate);
    279278    $post_data = [
    280279      'post_title'    => $api_data->title,
    281280      'post_content'  => $api_data->text,
    282       // 'post_date'     => date('Y-m-d H:i:s', $publicationTime),
    283       // 'post_date_gmt' => gmdate('Y-m-d H:i:s', $publicationTime),
     281      'post_date'     => date('Y-m-d H:i:s', $publicationTime),
     282      'post_date_gmt' => gmdate('Y-m-d H:i:s', $publicationTime),
    284283      'post_status'   => 'publish',
    285284      'post_type'     => 'post',
    286285      'post_author'   => get_current_user_id(),
    287286    ];
    288     // if ($publicationTime > time()) {
    289     //   $data['post_status'] = 'future';
    290     // }
     287    if ($publicationTime > time()) {
     288      $data['post_status'] = 'future';
     289    } else if (!$api_data->isPublished) {
     290      $data['post_status'] = 'draft';
     291    } else {
     292      $data['post_status'] = 'publish';
     293    }
    291294
    292295    $wp_post_id = wp_insert_post($post_data);
     
    315318    }
    316319
     320    $wp_whole_post = get_post($wp_post_id);
    317321    update_post_meta($wp_post_id, 'crowdaa_need_sync', 'no');
    318322    update_post_meta($wp_post_id, 'crowdaa_version', Crowdaa_Sync_Versions::get_version());
     323    update_post_meta($wp_post_id, 'crowdaa_last_api_update', $api_data->updatedAt);
     324    update_post_meta($wp_post_id, 'crowdaa_last_wp_update', $wp_whole_post->post_modified_gmt);
    319325
    320326    Crowdaa_Sync_Logs::log('Created WP post', $wp_post_id);
     
    323329  }
    324330
    325   // private static function api_date_to_unix($date) {
    326   //   $matches = [];
    327   //   preg_match('/^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)\.\d+Z/', $date, $matches);
    328   //   $time = gmmktime(
    329   //     intval($matches[4], 10),
    330   //     intval($matches[5], 10),
    331   //     intval($matches[6], 10),
    332   //     intval($matches[2], 10),
    333   //     intval($matches[3], 10),
    334   //     intval($matches[1], 10),
    335   //   );
    336   //   return ($time);
    337   // }
     331  private static function api_date_to_unix($date)
     332  {
     333    $matches = [];
     334    preg_match('/^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)\.\d+Z/', $date, $matches);
     335    $time = gmmktime(
     336      intval($matches[4], 10),
     337      intval($matches[5], 10),
     338      intval($matches[6], 10),
     339      intval($matches[2], 10),
     340      intval($matches[3], 10),
     341      intval($matches[1], 10),
     342    );
     343    return ($time);
     344  }
    338345
    339346  private function update_wp_post_from_api($api_data, $wp_post_id)
    340347  {
    341     $created_posts  = [];
    342     $cat_sync_db    = new Crowdaa_Sync_Syncdb('categories');
     348    $cat_sync_db    = Crowdaa_Sync_Syncdb::instance('categories');
    343349
    344350    if (isset($api_data->categories) && count($api_data->categories) > 0) {
     
    354360    }
    355361
    356     // $publicationTime = self::api_date_to_unix($api_data->publicationDate);
     362    $publicationTime = self::api_date_to_unix($api_data->publicationDate);
    357363    $data = [
    358364      'ID'            => $wp_post_id,
    359365      'post_title'    => $api_data->title,
    360366      'post_content'  => $api_data->text,
    361       // 'post_date'     => date('Y-m-d H:i:s', $publicationTime),
    362       // 'post_date_gmt' => gmdate('Y-m-d H:i:s', $publicationTime),
     367      'post_date'     => date('Y-m-d H:i:s', $publicationTime),
     368      'post_date_gmt' => gmdate('Y-m-d H:i:s', $publicationTime),
    363369    ];
    364     // if ($publicationTime > time()) {
    365     //   $data['post_status'] = 'future';
    366     // }
     370    if ($publicationTime > time()) {
     371      $data['post_status'] = 'future';
     372    } else if (!$api_data->isPublished) {
     373      $data['post_status'] = 'draft';
     374    } else {
     375      $data['post_status'] = 'publish';
     376    }
    367377
    368378    wp_set_post_terms($wp_post_id, $terms, 'category');
     
    391401    }
    392402
     403    $wp_whole_post = get_post($wp_post_id);
    393404    update_post_meta($wp_post_id, 'crowdaa_need_sync', 'no');
    394405    update_post_meta($wp_post_id, 'crowdaa_version', Crowdaa_Sync_Versions::get_version());
     406    update_post_meta($wp_post_id, 'crowdaa_last_api_update', $api_data->updatedAt);
     407    update_post_meta($wp_post_id, 'crowdaa_last_wp_update', $wp_whole_post->post_modified_gmt);
    395408
    396409    Crowdaa_Sync_Logs::log('Updated WP post', $wp_post_id, $api_data->_id);
     
    497510          ]));
    498511        } catch (\Throwable $e) {
    499           Crowdaa_Sync_Logs::log('Set WP term feed picture error', $e->getMessage());
    500512          throw new Crowdaa_Sync_Category_Error(__('Set WP term feed picture error : ', CROWDAA_SYNC_PLUGIN_NAME) . $e->getMessage());
    501513        }
     
    574586          $fetch_err = $this->get_uploads($feed_pic_url, $feed_pic_name);
    575587          if ($fetch_err) {
    576             $errors[] = $fetch_err;
     588            throw new Crowdaa_Sync_Post_Error(__('Feed image synchronization error (download) : ', CROWDAA_SYNC_PLUGIN_NAME) . $fetch_err);
    577589          }
    578590        }
     
    581593            $attachment_id = $this->set_uploads($wp_post_id, $feed_pic_name, true);
    582594          } catch (\Throwable $e) {
    583             Crowdaa_Sync_Logs::log('Set WP post feed picture error', $e->getMessage());
    584             $errors[] = $e->getMessage();
    585             return;
     595            throw new Crowdaa_Sync_Post_Error(__('Feed image synchronization error (storage) : ', CROWDAA_SYNC_PLUGIN_NAME) . $e->getMessage());
    586596          }
    587597          update_post_meta($wp_post_id, 'api_feedpicture_id', serialize([
     
    631641          $fetch_err = $this->get_uploads($image_url, $image_name);
    632642          if ($fetch_err) {
    633             $errors[] = $fetch_err;
    634             continue;
     643            throw new Crowdaa_Sync_Post_Error(__('Image synchronization error (download) : ', CROWDAA_SYNC_PLUGIN_NAME) . $fetch_err);
    635644          }
    636645        }
     
    640649          $images_map[$image_id] = $attachment_id;
    641650        } catch (\Throwable $e) {
    642           Crowdaa_Sync_Logs::log('Set WP post image error', $e->getMessage());
    643           $errors[] = $e->getMessage();
    644           continue;
     651          throw new Crowdaa_Sync_Post_Error(__('Image synchronization error (storage) : ', CROWDAA_SYNC_PLUGIN_NAME) . $e->getMessage());
    645652        }
    646653      }
     
    680687          $convert_error = $this->ffmpeg_video_converter($video->url, $video_name);
    681688          if ($convert_error) {
    682             $errors[] = $convert_error;
    683             continue;
     689            throw new Crowdaa_Sync_Post_Error(__('Video synchronization error (convert) : ', CROWDAA_SYNC_PLUGIN_NAME) . $convert_error);
    684690          }
    685691        }
     
    689695          $videos_map[$video_id] = $attachment_id;
    690696        } catch (\Throwable $e) {
    691           Crowdaa_Sync_Logs::log('Set WP post video error', $e->getMessage());
    692           $errors[] = $e->getMessage();
    693           continue;
     697          throw new Crowdaa_Sync_Post_Error(__('Video synchronization error (storage) : ', CROWDAA_SYNC_PLUGIN_NAME) . $e->getMessage());
    694698        }
    695699      }
     
    834838
    835839    try {
    836       wp_remote_get($img_url, [
     840      $ret = wp_remote_get($img_url, [
    837841        'method'          => 'GET',
    838842        'timeout'         => 45,
     
    841845        'sslcertificates' => CROWDAA_SYNC_CACERT_PATH,
    842846      ]);
     847
     848      if (is_wp_error($ret)) {
     849        return $ret->get_error_message();
     850      }
    843851
    844852      return (false);
  • crowdaa-sync/trunk/admin/class-crowdaa-sync-admin-display.php

    r3202416 r3229463  
    4141    Crowdaa_Sync_Permissions::reset();
    4242
    43     $sync_db = new Crowdaa_Sync_Syncdb('categories');
     43    $sync_db = Crowdaa_Sync_Syncdb::instance('categories');
    4444    $sync_db->reset();
    4545
  • crowdaa-sync/trunk/admin/class-crowdaa-sync-api.php

    r3169735 r3229463  
    254254      }
    255255
    256       $send_notification = (
    257         get_post_meta($wp_post_id, 'crowdaa_notification_send', true) === 'yes' &&
    258         get_post_meta($wp_post_id, 'crowdaa_notification_sent', true) !== 'yes'
    259       );
    260       $publish_error = $this->publish_post_draft_api(
    261         $json->draftId,
    262         $api_post_id,
    263         $publication_time,
    264         $send_notification,
    265         (get_post_meta($wp_post_id, 'crowdaa_notification_content', true) ?: null),
    266         (get_post_meta($wp_post_id, 'crowdaa_notification_title', true) ?: null),
    267       );
    268       if ($publish_error) {
    269         Crowdaa_Sync_Logs::log('Article publish error', $api_post_id, $publish_error);
    270         throw new Crowdaa_Sync_Post_Error(__('Post publish error : ', CROWDAA_SYNC_PLUGIN_NAME) . $publish_error);
    271       }
    272 
    273       if ($send_notification) {
    274         update_post_meta($wp_post_id, 'crowdaa_notification_sent', 'yes');
    275       }
    276 
    277       Crowdaa_Sync_Logs::log('Updated API article successfully', $api_post_id, $json->draftId);
    278     }
    279   }
    280 
     256      $post_status = get_post_status($wp_post_id);
     257      if ($post_status === 'draft') {
     258        Crowdaa_Sync_Logs::log('Updated API post (draft)', $json->articleId);
     259        $this->unpublish_api_article($json->articleId);
     260      } else {
     261        $send_notification = (
     262          get_post_meta($wp_post_id, 'crowdaa_notification_send', true) === 'yes' &&
     263          get_post_meta($wp_post_id, 'crowdaa_notification_sent', true) !== 'yes'
     264        );
     265        $publish_error = $this->publish_post_draft_api(
     266          $json->draftId,
     267          $api_post_id,
     268          $publication_time,
     269          $send_notification,
     270          (get_post_meta($wp_post_id, 'crowdaa_notification_content', true) ?: null),
     271          (get_post_meta($wp_post_id, 'crowdaa_notification_title', true) ?: null),
     272        );
     273        if ($publish_error) {
     274          Crowdaa_Sync_Logs::log('Article publish error', $api_post_id, $publish_error);
     275          throw new Crowdaa_Sync_Post_Error(__('Post publish error : ', CROWDAA_SYNC_PLUGIN_NAME) . $publish_error);
     276        }
     277
     278        if ($send_notification) {
     279          update_post_meta($wp_post_id, 'crowdaa_notification_sent', 'yes');
     280        }
     281
     282        Crowdaa_Sync_Logs::log('Updated API article successfully', $api_post_id, $json->draftId);
     283      }
     284    }
     285  }
     286
     287  public function unpublish_api_article($api_post_id)
     288  {
     289    $url = '/press/articles/' . rawurlencode($api_post_id) . '/unpublish';
     290    $response = $this->http_request('PUT', $url);
     291    $err    = is_wp_error($response) ? $response->get_error_message() : null;
     292    if (!$err) {
     293      $body = wp_remote_retrieve_body($response);
     294      $json = json_decode($body);
     295    }
     296
     297    if ($err) {
     298      Crowdaa_Sync_Logs::log('Unpublish article query error', $api_post_id, $err);
     299      return ((object) [
     300        'message' => $err,
     301      ]);
     302    }
     303
     304    if (isset($json->message)) {
     305      Crowdaa_Sync_Logs::log('Unpublish article error', $json->message);
     306    }
     307
     308    return ($json);
     309  }
    281310
    282311  /**
     
    541570      }
    542571
    543       $send_notification = (
    544         get_post_meta($wp_post_id, 'crowdaa_notification_send', true) === 'yes' &&
    545         get_post_meta($wp_post_id, 'crowdaa_notification_sent', true) !== 'yes'
    546       );
    547       $publish_error = $this->publish_post_draft_api(
    548         $json->draftId,
    549         $json->articleId,
    550         $publication_time,
    551         $send_notification,
    552         (get_post_meta($wp_post_id, 'crowdaa_notification_content', true) ?: null),
    553         (get_post_meta($wp_post_id, 'crowdaa_notification_title', true) ?: null),
    554       );
    555       if ($publish_error) {
    556         Crowdaa_Sync_Logs::log('Article first publish error', $json->articleId, $json->draftId, $publish_error);
    557         throw new Crowdaa_Sync_Post_Error(__('Post first publish error : ', CROWDAA_SYNC_PLUGIN_NAME) . $publish_error);
    558       }
    559 
    560       update_post_meta($wp_post_id, 'api_post_id', $json->articleId);
    561       if ($send_notification) {
    562         update_post_meta($wp_post_id, 'crowdaa_notification_sent', 'yes');
    563       }
    564       Crowdaa_Sync_Logs::log('Created API post', $json->articleId);
     572      $post_status = get_post_status($wp_post_id);
     573      if ($post_status === 'draft') {
     574        Crowdaa_Sync_Logs::log('Updated API post (draft)', $json->articleId);
     575        $this->unpublish_api_article($json->articleId);
     576      } else {
     577        $send_notification = (
     578          get_post_meta($wp_post_id, 'crowdaa_notification_send', true) === 'yes' &&
     579          get_post_meta($wp_post_id, 'crowdaa_notification_sent', true) !== 'yes'
     580        );
     581        $publish_error = $this->publish_post_draft_api(
     582          $json->draftId,
     583          $json->articleId,
     584          $publication_time,
     585          $send_notification,
     586          (get_post_meta($wp_post_id, 'crowdaa_notification_content', true) ?: null),
     587          (get_post_meta($wp_post_id, 'crowdaa_notification_title', true) ?: null),
     588        );
     589        if ($publish_error) {
     590          Crowdaa_Sync_Logs::log('Article first publish error', $json->articleId, $json->draftId, $publish_error);
     591          throw new Crowdaa_Sync_Post_Error(__('Post first publish error : ', CROWDAA_SYNC_PLUGIN_NAME) . $publish_error);
     592        }
     593
     594        update_post_meta($wp_post_id, 'api_post_id', $json->articleId);
     595        if ($send_notification) {
     596          update_post_meta($wp_post_id, 'crowdaa_notification_sent', 'yes');
     597        }
     598
     599        Crowdaa_Sync_Logs::log('Created API post', $json->articleId);
     600      }
     601
     602      return $json->articleId;
    565603    }
    566604  }
  • crowdaa-sync/trunk/admin/partials/crowdaa-sync-admin-display.php

    r3169735 r3229463  
    198198        <br />
    199199        <?php wp_nonce_field('crowdaa_cron_sync_enabled_data', 'crowdaa_cron_sync_enabled'); ?>
    200         <?php submit_button('Save parameters'); ?>
     200        <?php submit_button(__('Save parameters', CROWDAA_SYNC_PLUGIN_NAME)); ?>
    201201      </form>
    202202    </div>
     
    221221        <input type="file" required name="file" id="image_file" accept=".jpg, .jpeg, .png" />
    222222        <?php
    223         submit_button('Save picture');
     223        submit_button(__('Save picture', CROWDAA_SYNC_PLUGIN_NAME));
    224224        ?>
    225225      </form>
     
    275275        <?php wp_nonce_field('crowdaa_set_sync_categories_data', 'crowdaa_set_sync_categories'); ?>
    276276        <?php
    277         submit_button('Save mode & categories');
     277        submit_button(__('Save mode & categories', CROWDAA_SYNC_PLUGIN_NAME));
    278278        ?>
    279279      </form>
     
    323323        <?php wp_nonce_field('crowdaa_set_feed_categories_data', 'crowdaa_set_feed_categories'); ?>
    324324        <?php
    325         submit_button('Save feed categories');
     325        submit_button(__('Save feed categories', CROWDAA_SYNC_PLUGIN_NAME));
    326326        ?>
    327327      </form>
  • crowdaa-sync/trunk/crowdaa-sync.php

    r3218183 r3229463  
    1414 * Plugin URI:       
    1515 * Description:       Plugin for synchronizing WordPress site and Crowdaa CMS
    16  * Version:           1.10.8
     16 * Version:           2.0.1
    1717 * Requires at least: 5.5
    1818 * Requires PHP:      7.2
     
    3434 * Uses SemVer - https://semver.org
    3535 */
    36 define('CROWDAA_SYNC_VERSION', '1.10.8');
     36define('CROWDAA_SYNC_VERSION', '2.0.1');
    3737define('CROWDAA_SYNC_PLUGIN_DIR', __DIR__);
    3838define('CROWDAA_SYNC_PLUGIN_NAME', 'crowdaa-sync');
     
    4444 * Just bump the version, it will handle the rest.
    4545 */
    46 define('CROWDAA_SYNC_META_VERSION', '3');
     46define('CROWDAA_SYNC_META_VERSION', '4');
    4747
    4848$last_version = get_option('crowdaa_last_version', false);
  • crowdaa-sync/trunk/includes/class-crowdaa-sync-exception.php

    r3149200 r3229463  
    1111 */
    1212
     13class Crowdaa_Sync_Generic_Exception extends Exception
     14{
     15  public function __construct($message = 'NO_MESSAGE_GIVEN', ...$extra)
     16  {
     17    parent::__construct($message);
     18
     19    $to_log = $message;
     20    if ($extra) {
     21      foreach ($extra as $item) {
     22        if (!is_string($item)) {
     23          $to_log .= '|' . print_r($item, true);
     24        } else {
     25          $to_log .= '|' . $item;
     26        }
     27      }
     28    }
     29
     30    Crowdaa_Sync_Logs::log((new \ReflectionClass($this))->getShortName(), '__construct() called with', $to_log);
     31  }
     32}
     33
    1334/**
    1435 * The base project exception, when a fatal error occurs.
     
    2142 * @author     Crowdaa <contact@crowdaa.com>
    2243 */
    23 class Crowdaa_Sync_Error extends Exception
    24 {
    25 }
     44class Crowdaa_Sync_Error extends Crowdaa_Sync_Generic_Exception {}
    2645
    2746/**
     
    3352 * @author     Crowdaa <contact@crowdaa.com>
    3453 */
    35 class Crowdaa_Sync_Badge_Error extends Exception
    36 {
    37 }
     54class Crowdaa_Sync_Badge_Error extends Crowdaa_Sync_Generic_Exception {}
    3855
    3956/**
     
    4562 * @author     Crowdaa <contact@crowdaa.com>
    4663 */
    47 class Crowdaa_Sync_Category_Error extends Exception
    48 {
    49 }
     64class Crowdaa_Sync_Category_Error extends Crowdaa_Sync_Generic_Exception {}
    5065
    5166/**
     
    5772 * @author     Crowdaa <contact@crowdaa.com>
    5873 */
    59 class Crowdaa_Sync_Post_Error extends Exception
    60 {
    61 }
     74class Crowdaa_Sync_Post_Error extends Crowdaa_Sync_Generic_Exception {}
    6275
    6376/**
     
    6982 * @author     Crowdaa <contact@crowdaa.com>
    7083 */
    71 class Crowdaa_Sync_Post_Skip_Error extends Crowdaa_Sync_Post_Error
    72 {
    73 }
     84class Crowdaa_Sync_Post_Skip_Error extends Crowdaa_Sync_Post_Error {}
    7485
    7586/**
     
    8192 * @author     Crowdaa <contact@crowdaa.com>
    8293 */
    83 class Crowdaa_Sync_Timeout_Error extends Exception
    84 {
    85 }
     94class Crowdaa_Sync_Timeout_Error extends Crowdaa_Sync_Generic_Exception {}
  • crowdaa-sync/trunk/includes/class-crowdaa-sync-permissions.php

    r3179247 r3229463  
    129129  public static function sync_db()
    130130  {
    131     return (new Crowdaa_Sync_Syncdb('user_badges'));
     131    return (Crowdaa_Sync_Syncdb::instance('user_badges'));
    132132  }
    133133
  • crowdaa-sync/trunk/includes/class-crowdaa-sync-syncdb.php

    r3195042 r3229463  
    1616  private static $loaded = array();
    1717
     18  public static function instance($tableName)
     19  {
     20    switch ($tableName) {
     21      case 'categories':
     22      case 'user_badges':
     23        return new self($tableName, CROWDAA_SYNC_META_VERSION);
     24        break;
     25      default:
     26        return new self($tableName);
     27        break;
     28    }
     29  }
     30
    1831  /**
    1932   * Initialize the database.
     
    4962  }
    5063
     64  public function get_version()
     65  {
     66    return $this->version;
     67  }
     68
    5169  /**
    5270   * Returns an assoc array of synced elements, with the provided fields (null means all)
     
    151169      if (isset($v->sync_data)) {
    152170        $v->sync_data = unserialize($v->sync_data);
     171      } else {
     172        $v->sync_data = [];
    153173      }
    154174    }
     
    266286    return (array_pop($result));
    267287  }
     288
     289  /**
     290   * Delete an entry with the specified internal ID.
     291   */
     292  public function delete_entry_with_id($id)
     293  {
     294    global $wpdb;
     295
     296    list($whereStr, $whereArg) = self::prepare_wherein($id, 'id');
     297
     298    $wpdb->get_results($wpdb->prepare("DELETE FROM `$this->tableName` WHERE $whereStr", ...$whereArg), OBJECT_K);
     299  }
    268300}
  • crowdaa-sync/trunk/languages/crowdaa-sync-fr_FR.po

    r3169735 r3229463  
    33"Project-Id-Version: WpCrowdaaSyncTranslations\n"
    44"Report-Msgid-Bugs-To: \n"
    5 "POT-Creation-Date: 2024-10-15 17:46+0400\n"
    6 "PO-Revision-Date: 2024-10-15 17:47+0400\n"
     5"POT-Creation-Date: 2024-12-16 10:58+0400\n"
     6"PO-Revision-Date: 2024-12-16 11:05+0400\n"
    77"Last-Translator: \n"
    88"Language-Team: Français\n"
     
    1212"Content-Transfer-Encoding: 8bit\n"
    1313"Plural-Forms: nplurals=2; plural=(n > 1);\n"
    14 "X-Generator: Poedit 3.2.2\n"
     14"X-Generator: Poedit 3.4.2\n"
    1515"X-Poedit-Basepath: ..\n"
    1616"X-Poedit-KeywordsList: __;_e;esc_html_e;esc_attr_e\n"
     
    2424
    2525#: admin/class-crowdaa-sync-add-info-api.php:217
    26 #: admin/class-crowdaa-sync-add-info-api.php:630
     26#: admin/class-crowdaa-sync-add-info-api.php:643
    2727msgid "User is not connected"
    2828msgstr "Utilisateur non connecté"
    2929
    3030#: admin/class-crowdaa-sync-add-info-api.php:245
    31 #: admin/class-crowdaa-sync-add-info-api.php:372
    32 #: admin/class-crowdaa-sync-add-info-api.php:660
     31#: admin/class-crowdaa-sync-add-info-api.php:378
     32#: admin/class-crowdaa-sync-add-info-api.php:674
    3333msgid "API query error : "
    3434msgstr "Erreur de requête d'API :"
    3535
    36 #: admin/class-crowdaa-sync-add-info-api.php:827
     36#: admin/class-crowdaa-sync-add-info-api.php:855
    3737msgid "The synchronization cannot be done, missing dependencies : "
    3838msgstr "La synchronisation ne peut se faire, dépendances manquantes :"
    3939
    40 #: admin/class-crowdaa-sync-add-info-api.php:832
     40#: admin/class-crowdaa-sync-add-info-api.php:860
    4141msgid "Cannot run : a synchronization is already running"
    4242msgstr "Une synchronisation est déjà en cours, merci de réessayer plus tard"
    4343
    44 #: admin/class-crowdaa-sync-add-info-api.php:966
     44#: admin/class-crowdaa-sync-add-info-api.php:994
    4545msgid "Some errors happened during synchronization : "
    4646msgstr "Des erreurs ont eu lieu pendant la synchronisation :"
    4747
    48 #: admin/class-crowdaa-sync-add-info-api.php:969
     48#: admin/class-crowdaa-sync-add-info-api.php:997
    4949msgid "All data synced successfully"
    5050msgstr "Données synchronisées avec succès"
    5151
    52 #: admin/class-crowdaa-sync-add-info-api.php:974
     52#: admin/class-crowdaa-sync-add-info-api.php:1002
    5353msgid ""
    5454"The synchronization process timed out, please retry it until it succeeds."
     
    5757"relancer jusqu'à ce que qu'elle se termine entièrement."
    5858
    59 #: admin/class-crowdaa-sync-add-info-api.php:976
     59#: admin/class-crowdaa-sync-add-info-api.php:1004
    6060msgid "Uncaught Post synchronization error : "
    61 msgstr ""
    62 
    63 #: admin/class-crowdaa-sync-add-info-api.php:978
     61msgstr "Erreur non rattrapée de synchronsation de post : "
     62
     63#: admin/class-crowdaa-sync-add-info-api.php:1006
    6464msgid "Category synchronization error : "
    65 msgstr ""
    66 
    67 #: admin/class-crowdaa-sync-add-info-api.php:980
     65msgstr "Erreur de synchronisation de catégorie : "
     66
     67#: admin/class-crowdaa-sync-add-info-api.php:1008
    6868msgid "Badge synchronization error : "
    69 msgstr ""
    70 
    71 #: admin/class-crowdaa-sync-add-info-api.php:982
     69msgstr "Erreur de synchronisation de badge : "
     70
     71#: admin/class-crowdaa-sync-add-info-api.php:1010
    7272msgid "Fatal synchronization error : "
    73 msgstr ""
    74 
    75 #: admin/class-crowdaa-sync-add-info-api.php:984
     73msgstr "Erreur de synchronisation fatale : "
     74
     75#: admin/class-crowdaa-sync-add-info-api.php:1012
    7676msgid "Unknown synchronzation error : "
    77 msgstr ""
    78 
    79 #: admin/class-crowdaa-sync-add-info-wp.php:490
     77msgstr "Erreur de synchronisation inconnue : "
     78
     79#: admin/class-crowdaa-sync-add-info-wp.php:501
    8080msgid "Errors when downloading term image for "
    81 msgstr ""
    82 
    83 #: admin/class-crowdaa-sync-add-info-wp.php:502
     81msgstr "Erreur de téléchargement de l'image de catégorie pour "
     82
     83#: admin/class-crowdaa-sync-add-info-wp.php:512
    8484msgid "Set WP term feed picture error : "
    85 msgstr ""
    86 
    87 #: admin/class-crowdaa-sync-add-info-wp.php:869
     85msgstr "Erreur de définition de l'image du feed :"
     86
     87#: admin/class-crowdaa-sync-add-info-wp.php:588
     88msgid "Feed image synchronization error (download) : "
     89msgstr "Erreur de synchronisation de l'image du feed (téléchargement) :"
     90
     91#: admin/class-crowdaa-sync-add-info-wp.php:595
     92msgid "Feed image synchronization error (storage) : "
     93msgstr "Erreur de synchronisation de l'image du feed (stockage) :"
     94
     95#: admin/class-crowdaa-sync-add-info-wp.php:643
     96msgid "Image synchronization error (download) : "
     97msgstr "Erreur de synchronisation d'image (téléchargement) :"
     98
     99#: admin/class-crowdaa-sync-add-info-wp.php:651
     100msgid "Image synchronization error (storage) : "
     101msgstr "Erreur de synchronisation d'image (stockage) :"
     102
     103#: admin/class-crowdaa-sync-add-info-wp.php:689
     104msgid "Video synchronization error (convert) : "
     105msgstr "Erreur de synchronisation de vidéo (conversion) :"
     106
     107#: admin/class-crowdaa-sync-add-info-wp.php:697
     108msgid "Video synchronization error (storage) : "
     109msgstr "Erreur de synchronisation de vidéo (stockage) :"
     110
     111#: admin/class-crowdaa-sync-add-info-wp.php:875
    88112msgid ""
    89113"You don't have ffmpeg installed on your server to download videos, please "
     
    94118"hébergeur"
    95119
    96 #: admin/class-crowdaa-sync-admin-display.php:197
    97 #: admin/class-crowdaa-sync-admin-display.php:208
     120#: admin/class-crowdaa-sync-admin-display.php:205
     121#: admin/class-crowdaa-sync-admin-display.php:216
    98122msgid "Failed to get data. Please try again later"
    99123msgstr "Communication réseau impossible, merci de réessayer ultérieurement"
    100124
    101 #: admin/class-crowdaa-sync-admin-display.php:219
     125#: admin/class-crowdaa-sync-admin-display.php:227
    102126msgid "Data is incorrect please double-check and try again"
    103127msgstr "Les données sont incorrectes, merci de vérifier les paramètres fournis"
    104128
    105 #: admin/class-crowdaa-sync-admin-display.php:247
     129#: admin/class-crowdaa-sync-admin-display.php:255
    106130msgid "Failed to complete login initialization process"
    107131msgstr "Échec d'initialisation du plugin, merci de réessayer"
    108132
    109 #: admin/class-crowdaa-sync-admin-display.php:254
     133#: admin/class-crowdaa-sync-admin-display.php:262
    110134msgid "You are successfully logged in"
    111135msgstr "Vous êtes connecté!"
    112136
    113 #: admin/class-crowdaa-sync-admin-display.php:265
     137#: admin/class-crowdaa-sync-admin-display.php:273
    114138msgid "Please, provide all user data"
    115139msgstr "Merci de remplir tous les champs demandés"
    116140
    117 #: admin/class-crowdaa-sync-api.php:184 admin/class-crowdaa-sync-api.php:336
    118 #: admin/class-crowdaa-sync-api.php:398 admin/class-crowdaa-sync-api.php:466
     141#: admin/class-crowdaa-sync-api.php:184 admin/class-crowdaa-sync-api.php:341
     142#: admin/class-crowdaa-sync-api.php:403 admin/class-crowdaa-sync-api.php:471
    119143msgid "Not connected to the API"
    120144msgstr "Non connecté"
    121145
    122 #: admin/class-crowdaa-sync-api.php:195 admin/class-crowdaa-sync-api.php:478
     146#: admin/class-crowdaa-sync-api.php:195 admin/class-crowdaa-sync-api.php:483
    123147msgid "Cannot sync article without any image or video!"
    124148msgstr "Impossible de synchroniser un article sans image ou vidéo!"
    125149
    126 #: admin/class-crowdaa-sync-api.php:206 admin/class-crowdaa-sync-api.php:489
     150#: admin/class-crowdaa-sync-api.php:206 admin/class-crowdaa-sync-api.php:494
    127151msgid "Without title"
    128152msgstr "Sans titre"
    129153
    130 #: admin/class-crowdaa-sync-api.php:213 admin/class-crowdaa-sync-api.php:495
     154#: admin/class-crowdaa-sync-api.php:213 admin/class-crowdaa-sync-api.php:500
    131155msgid "Without content"
    132156msgstr "Sans contenu"
     
    140164msgstr ""
    141165
    142 #: admin/class-crowdaa-sync-api.php:270 admin/class-crowdaa-sync-api.php:441
     166#: admin/class-crowdaa-sync-api.php:274 admin/class-crowdaa-sync-api.php:446
    143167msgid "Post publish error : "
    144168msgstr ""
    145169
    146 #: admin/class-crowdaa-sync-api.php:340
     170#: admin/class-crowdaa-sync-api.php:345
    147171msgid "Unable to create article without Category"
    148172msgstr ""
    149173
    150 #: admin/class-crowdaa-sync-api.php:344 admin/class-crowdaa-sync-api.php:406
     174#: admin/class-crowdaa-sync-api.php:349 admin/class-crowdaa-sync-api.php:411
    151175msgid "Cannot sync article without any image and video!"
    152176msgstr ""
    153177
    154 #: admin/class-crowdaa-sync-api.php:348 admin/class-crowdaa-sync-api.php:410
     178#: admin/class-crowdaa-sync-api.php:353 admin/class-crowdaa-sync-api.php:415
    155179msgid "Cannot sync article without any title or content!"
    156180msgstr ""
    157181
    158 #: admin/class-crowdaa-sync-api.php:362
     182#: admin/class-crowdaa-sync-api.php:367
    159183#, php-format
    160184msgid "Custom article creation error, query response : %s"
    161185msgstr ""
    162186
    163 #: admin/class-crowdaa-sync-api.php:365
     187#: admin/class-crowdaa-sync-api.php:370
    164188#, php-format
    165189msgid "Custom article creation error, response : %s"
    166190msgstr ""
    167191
    168 #: admin/class-crowdaa-sync-api.php:368
     192#: admin/class-crowdaa-sync-api.php:373
    169193#, php-format
    170194msgid "Custom article creation error, API response : %s"
    171195msgstr ""
    172196
    173 #: admin/class-crowdaa-sync-api.php:379 admin/class-crowdaa-sync-api.php:557
     197#: admin/class-crowdaa-sync-api.php:384 admin/class-crowdaa-sync-api.php:566
    174198msgid "Post first publish error : "
    175199msgstr ""
    176200
    177 #: admin/class-crowdaa-sync-api.php:402
     201#: admin/class-crowdaa-sync-api.php:407
    178202msgid "Unable to update article without Category"
    179203msgstr ""
    180204
    181 #: admin/class-crowdaa-sync-api.php:424
     205#: admin/class-crowdaa-sync-api.php:429
    182206#, php-format
    183207msgid "Custom article update error, query response : %s"
    184208msgstr ""
    185209
    186 #: admin/class-crowdaa-sync-api.php:427
     210#: admin/class-crowdaa-sync-api.php:432
    187211#, php-format
    188212msgid "Custom article update error, response : %s"
    189213msgstr ""
    190214
    191 #: admin/class-crowdaa-sync-api.php:430
     215#: admin/class-crowdaa-sync-api.php:435
    192216#, php-format
    193217msgid "Custom article update error, API response : %s"
    194218msgstr ""
    195219
    196 #: admin/class-crowdaa-sync-api.php:461
     220#: admin/class-crowdaa-sync-api.php:466
    197221msgid "Unable to sync article without Category or Media in Gallery"
    198222msgstr ""
    199223
    200 #: admin/class-crowdaa-sync-api.php:533
     224#: admin/class-crowdaa-sync-api.php:538
    201225#, php-format
    202226msgid "Post creation error for wp post %d, query response : %s"
    203227msgstr ""
    204228
    205 #: admin/class-crowdaa-sync-api.php:536
     229#: admin/class-crowdaa-sync-api.php:541
    206230#, php-format
    207231msgid "Post creation error for wp post %d, response : %s"
    208232msgstr ""
    209233
    210 #: admin/class-crowdaa-sync-api.php:540
     234#: admin/class-crowdaa-sync-api.php:545
    211235#, php-format
    212236msgid "Post creation error for wp post %d, API response : %s"
    213237msgstr ""
    214238
    215 #: admin/class-crowdaa-sync-api.php:587
     239#: admin/class-crowdaa-sync-api.php:600
    216240msgid "Default article image not set"
    217241msgstr "L'image par défaut n'est pas définie"
    218242
    219 #: admin/class-crowdaa-sync-api.php:607
     243#: admin/class-crowdaa-sync-api.php:620
    220244msgid "Missing featured image on post, skipping"
    221245msgstr ""
    222246
    223 #: admin/class-crowdaa-sync-api.php:611 admin/class-crowdaa-sync-api.php:672
     247#: admin/class-crowdaa-sync-api.php:624 admin/class-crowdaa-sync-api.php:685
    224248msgid "Image synchronization error : "
    225249msgstr ""
    226250
    227 #: admin/class-crowdaa-sync-api.php:667
     251#: admin/class-crowdaa-sync-api.php:680
    228252msgid "Missing gallery image/video on post, skipping"
    229253msgstr ""
    230254
    231 #: admin/class-crowdaa-sync-api.php:697
     255#: admin/class-crowdaa-sync-api.php:710
    232256msgid "No picture could be synchronized for post "
    233257msgstr ""
    234258
    235 #: admin/class-crowdaa-sync-api.php:743
     259#: admin/class-crowdaa-sync-api.php:756
    236260msgid "Not logged in"
    237261msgstr "Non connecté"
    238262
    239 #: admin/class-crowdaa-sync-api.php:908
     263#: admin/class-crowdaa-sync-api.php:921
    240264msgid "Query error during badge creation : "
    241265msgstr ""
    242266
    243 #: admin/class-crowdaa-sync-api.php:912
     267#: admin/class-crowdaa-sync-api.php:925
    244268msgid "API error during badge creation : "
    245269msgstr ""
    246270
    247 #: admin/class-crowdaa-sync-api.php:942
     271#: admin/class-crowdaa-sync-api.php:955
    248272msgid "Query error during badge update : "
    249273msgstr ""
    250274
    251 #: admin/class-crowdaa-sync-api.php:946
     275#: admin/class-crowdaa-sync-api.php:959
    252276msgid "API error during badge update : "
    253277msgstr ""
    254278
    255 #: admin/class-crowdaa-sync-api.php:966
     279#: admin/class-crowdaa-sync-api.php:979
    256280msgid "Query error during badge delete : "
    257281msgstr ""
    258282
    259 #: admin/class-crowdaa-sync-api.php:970
     283#: admin/class-crowdaa-sync-api.php:983
    260284msgid "API error during badge delete : "
    261285msgstr ""
    262286
    263 #: admin/class-crowdaa-sync-api.php:1000
     287#: admin/class-crowdaa-sync-api.php:1013
    264288msgid "Errors when uploading category image for "
    265289msgstr ""
    266290
    267 #: admin/class-crowdaa-sync-api.php:1061
     291#: admin/class-crowdaa-sync-api.php:1074
    268292msgid "Query error during category creation : "
    269293msgstr ""
    270294
    271 #: admin/class-crowdaa-sync-api.php:1065
     295#: admin/class-crowdaa-sync-api.php:1078
    272296msgid "API error during category creation : "
    273297msgstr ""
    274298
    275 #: admin/class-crowdaa-sync-api.php:1119
     299#: admin/class-crowdaa-sync-api.php:1132
    276300msgid "Query error during category update : "
    277301msgstr ""
    278302
    279 #: admin/class-crowdaa-sync-api.php:1123
     303#: admin/class-crowdaa-sync-api.php:1136
    280304msgid "API error during category update : "
    281305msgstr ""
    282306
    283 #: admin/class-crowdaa-sync-api.php:1158
     307#: admin/class-crowdaa-sync-api.php:1171
    284308msgid "Query error during category delete : "
    285309msgstr ""
    286310
    287 #: admin/class-crowdaa-sync-api.php:1162
     311#: admin/class-crowdaa-sync-api.php:1175
    288312msgid "API error during category delete : "
    289313msgstr ""
     
    457481#: admin/class-crowdaa-sync-wp-hooks.php:95
    458482msgid "Event category"
    459 msgstr ""
     483msgstr "Catégorie d'événements"
    460484
    461485#: admin/class-crowdaa-sync-wp-hooks.php:83
     
    465489"dates)"
    466490msgstr ""
     491"Si cette catégorie contient des événements (posts avec une date de début et "
     492"de fin d'événement)"
    467493
    468494#: admin/class-crowdaa-sync-wp-hooks.php:152
     
    590616msgstr "Plugin de permissions utilisé"
    591617
     618#: admin/partials/crowdaa-sync-admin-display.php:200
     619msgid "Save parameters"
     620msgstr "Enregistrer les paramètres"
     621
    592622#: admin/partials/crowdaa-sync-admin-display.php:206
    593623msgid "Add default picture to the Gallery"
    594624msgstr "Ajouter une image par défaut"
    595625
     626#: admin/partials/crowdaa-sync-admin-display.php:223
     627msgid "Save picture"
     628msgstr "Enregistrer l'image"
     629
    596630#: admin/partials/crowdaa-sync-admin-display.php:231
    597631msgid "Set categories to synchronize"
     
    631665msgstr ""
    632666
     667#: admin/partials/crowdaa-sync-admin-display.php:277
     668msgid "Save mode & categories"
     669msgstr "Enregistrer le mode et les catégories"
     670
    633671#: admin/partials/crowdaa-sync-admin-display.php:285
    634672msgid "Set feed (front-page) categories"
     
    645683"principale."
    646684
     685#: admin/partials/crowdaa-sync-admin-display.php:325
     686msgid "Save feed categories"
     687msgstr "Enregistrer les catégories du feed"
     688
    647689#: admin/partials/crowdaa-sync-admin-display.php:334
    648690msgid "Synchronization"
Note: See TracChangeset for help on using the changeset viewer.