web-dev-qa-db-ja.com

JSON:jsonファイルの作成スケジュール

いくつかの調査の結果、私はTwitterの先行入力用の入力として使用するjsonファイルを作成することに成功しました(プリフェッチ)。私のウェブサイトには、数百のイベントと数千のアーティストがいます(どちらもカス​​タム投稿タイプ)。

Jsonファイルは、以下の機能を使用して作成されます(アーティストの機能は異なる投稿タイプであることを除いて同じですので、1つの機能のみを投稿します)。イベントやアーティストを更新し続けているので、そしてその両方をたくさん持っているので、私はどのようにして関数を実行することになるべきかと思っていました。私の考えはこの機能をスケジュールすることでした、それでそれは毎日かそこら実行するでしょう。もう少し調べてみると( this post を使って)これを直せるはずです。

今私の質問はこれが良い習慣であるかどうかです。毎晩実行するように機能をスケジュールすることは素晴らしいことだと思いました(私たちには8000人以上のアーティストがいるので訪問者のために機能を遅くしたくはありません)。

関数:

function json_events() {

  $args = array( 
    'post_type' => 'events',
    'posts_per_page' => -1,
    'post_status' => 'publish'
  );

  $query = new WP_Query($args);

  $json = array();

  while ($query->have_posts()): $query->the_post();
    $json[] = get_the_title();
  endwhile;
  wp_reset_query();

  $fp = fopen('events.json', 'w');
  fwrite($fp, json_encode($json));
  fclose($fp);
}
2
eskimo

私の考えはこの機能をスケジュールすることでした、それでそれは毎日かそこら実行するでしょう。もう少し調査した後、私はこれを直すことができるはずです(この記事を使って)。

WP_Cron daily に設定した場合、作成が行われる時点でexactlyを制御することは不可能です。だれも夜間にあなたのサイトにアクセスしなければ、朝の最初のユーザーは非常に長いページロード時間を経験するでしょう。 shutdownアクションにフックする関数を作成し、その関数から ヘビーワーク を実行するURLをcurlを介して呼び出すという回避策があります。

ただし、 cronテーブル にアクセスできる場合は、この機能を使用してください。

また、検索エンジンもWP_Cronをトリガーするため、検索エンジンの訪問時に作業が遅くなり、ページの読み込みが遅くなり、SEOに影響を与える可能性があります。

..しかし、そのような大きなデータセットを構築するための別の効率的な方法があるかもしれません。

allファイルの内容を毎日更新する必要がある場合は、それほどチャンスはありません。allアーティスト/イベントのCPT投稿のタイトルが毎日変わらない場合は、

  1. ファイル作成を一度実行する
  2. save_postpost_updatedおよびdelete_postにフックし、新しいアーティストまたはイベントが追加されると、プリフェッチファイルを増分します(つまり、ファイル全体を構築する代わりに新しいタイトルを追加する)タイトルが更新されたとき、または投稿が削除された(またはゴミ箱から復元された)ときに、ファイルを再作成します。

このようにして、あなたはdon'tどんな重いスケジュールされたタスクも実行する必要があります、そして、ウェブサイトの減速は起こりません。

私はインクリメンタルセービングのものを行う簡単なプラグインを書きました。プラグインは、jsonファイルを/jsonサブフォルダーの下のWP uploadsディレクトリーに保存します。

<?php 
/**
 * Plugin Name: Json Posts Incremental
 * http://wordpress.stackexchange.com/questions/113198/json-schedule-creation-of-json-file
 * Author: G. M.
 * Author URI: http://wordpress.stackexchange.com/users/35541/
 */

class Json_Posts_Incremental {

  static $types = array('artists', 'events');

  static $path;

  static $url;

  static function init() {
    self::set_path();
    add_action('admin_init', array( __CLASS__, 'build_all') );
    add_action('delete_post', array( __CLASS__, 'update'), 20, 1 );
    add_action('post_updated', array( __CLASS__, 'update'), 20, 3 );
  }

  static function build_all() {
    foreach ( self::$types as $type ) self::build($type, false);
  }

  static function update( $post_ID = 0, $post_after = null, $post_before = null) {
    if ( ! empty($post_after) && ! empty($post_before) ) {
      $new = $post_before->post_status == 'auto-draft' || $post_before->post_status == 'new';
      if ( $new ) return self::increment($post_ID, $post_after, false);
      $skip = $post_after->post_status != 'publish' && $post_before->post_status != 'publish';
      if ( $skip ) return;
      $trash = ( $post_after->post_status == 'trash' && $post_before->post_status == 'publish' ) || // trash
        ( $post_after->post_status == 'publish' && $post_before->post_status == 'trash' ); // restore
      if ( ! $trash && ( $post_after->post_title == $post_before->post_title ) ) return;
    } else {
      $post_after = get_post($post_ID);
      if ( ! is_object($post_after) || ! isset($post_after->post_type) || $post_after->post_status == 'trash' ) return;
    }
    if ( in_array($post_after->post_type, self::$types) ) self::build( $post_after->post_type, true );
  }

  static function increment( $post_ID, $post, $update ) {
    if ( $update || ! in_array($post->post_type, self::$types) ) return;
    $file = trailingslashit(self::$path) . $post->post_type . '.json';
    $content = file_exists($file) ? file_get_contents($file) : '[]';
    $content = rtrim($content, ']');
    if ( $content != '[') $content .= ',';
    $content .= json_encode($post->post_title) . ']';
    self::write($file, $content);
  }

  static function get_json( $type ) {
    $file = trailingslashit(self::$path) . $type . '.json';
    return ( file_exists($file) ) ? file_get_contents($file) : '';
  }

  static function get_json_file( $type ) {
    $file = trailingslashit(self::$path) . $type . '.json';
    return ( file_exists($file) ) ? $file : '';
  }

  static function get_json_url( $type ) {
    $file = trailingslashit(self::$path) . $type . '.json';
    return ( file_exists($file) ) ? trailingslashit(self::$url) . $type . '.json' : '';
  }   

  private static function build( $type = '', $force = false ) {
    if ( ! in_array($type, self::$types) ) return;
    $file = trailingslashit(self::$path) . $type . '.json';
    if ( file_exists($file) && ! $force ) return;
    $titles = array();
    $posts = get_posts("post_type=$type&nopaging=1");
    if ( ! empty($posts) ) {
      foreach ( $posts as $post )
        $titles[] = apply_filters('the_title', $post->post_title);
      $content = json_encode( $titles );
      self::write($file, $content);
    }
  }

  private static function set_path() {
    $upload_dir = wp_upload_dir();
    self::$path = $upload_dir['basedir'] . '/json';
    self::$url = $upload_dir['baseurl'] . '/json';
    if ( ! file_exists(self::$path) ) mkdir(self::$path, 0775);
  }

  private static function write( $file = '', $content = '' ) {
    $fp = fopen($file, 'w');
    fwrite($fp, $content);
    fclose($fp);
  }

}

add_action('init', array('Json_Posts_Incremental', 'init') );

JsonファイルのURLを取得するには、例えばjsに渡すにはJson_Posts_Incremental::get_json_url($type)を使います。ここで$typeは投稿タイプです。 events

その他のユーティリティ機能は次のとおりです。

ファイルパスを取得するJson_Posts_Incremental::get_json_file($type)

jsonコンテンツを文字列として取得するJson_Posts_Incremental::get_json($type)

6
gmazzap