JSON: programar la creación del archivo json

2

Después de algunas investigaciones, logré crear un archivo json que uso como entrada para el typeahead de Twitter (búsqueda previa). En mi sitio web tengo varios cientos de eventos y varios miles de artistas (ambos tipos de publicaciones personalizadas).

Los archivos json se crean utilizando la función siguiente (solo se publicó una función ya que la función para los artistas es la misma, excepto que es un tipo de publicación diferente). Dado que seguimos actualizando los eventos y los artistas, y dado que tenemos tanto de ambos, me preguntaba cómo debería ejecutar las funciones. Mi idea era programar esta función, por lo que se ejecutará una vez cada día. Después de un poco más de investigación, debería poder arreglar esto (utilizando esta publicación ).

Ahora mi pregunta es si esto es una buena práctica. Pensé que sería genial programar las funciones para que se ejecuten todas las noches (tenemos más de 8000 artistas, así que no quiero que las funciones reduzcan la velocidad del sitio web para los visitantes), pero tal vez haya otra forma eficiente de crear conjuntos de datos tan grandes. / p>

La función:

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);
}
    
pregunta eskimo 06.09.2013 - 16:13

1 respuesta

6
  

Mi idea era programar esta función, por lo que se ejecutará una vez al día.   más o menos. Después de un poco más de investigación, debería poder arreglar esto (usando   este post).

Tenga en cuenta que WP_Cron configurado para diario es imposible controlar exactly en el momento en que se produce la creación. Si nadie visita su sitio en la noche, el primer usuario en la mañana experimentará un tiempo de carga de página muy largo. Hay algunas soluciones, algunas veces he usado una: cree una función que se enganche en la acción shutdown y luego, desde esa función, llame a la url que ejecuta el trabajo pesado a través de curl .

Sin embargo, si tiene acceso a la tabla cron es mejor usar esta función.

También porque los motores de búsqueda activarán el WP_Cron también, por lo que hay posibilidades de que el trabajo lento comience en la visita al motor de búsqueda, lo que resultará en una carga lenta de la página que afectará el SEO.

  

.. pero tal vez haya otra forma eficiente de construir tan grande   conjuntos de datos.

Si necesita actualizar todos el contenido del archivo todos los días, hay pocas posibilidades. Pero si todos sus títulos / post de CPT de artistas / eventos no cambian todos los días, puede

  1. Ejecutar la creación del archivo una vez
  2. se engancha a save_post , post_updated y delete_post y cuando se agrega un nuevo artista o evento, incrementa el archivo de captación previa (es decir, solo agrega el nuevo título en lugar de compilar el archivo completo) con el nuevo título. Cuando se actualiza un título o se elimina una publicación (o se restaura de la papelera), vuelva a crear el archivo

De esta manera, no necesita ejecutar ninguna tarea pesada programada, y no se producirá una ralentización del sitio web.

He escrito un complemento simple que hace las cosas de ahorro incrementales. El complemento guarda los archivos json en el directorio WP uploads bajo una subcarpeta /json .

<?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') );

Para recuperar la url del archivo json, p. ej. para pasarlo a js puedes usar Json_Posts_Incremental::get_json_url($type) donde $type es el tipo de publicación, por ejemplo. events .

Otras funciones de utilidad son:

Json_Posts_Incremental::get_json_file($type) para recuperar la ruta del archivo.

Json_Posts_Incremental::get_json($type) para recuperar el contenido json como una cadena.

    
respondido por el gmazzap 06.09.2013 - 23:32

Lea otras preguntas en las etiquetas