├── README.md ├── composer.json ├── lib ├── mesh-command.php ├── mesh-image.php ├── mesh-json-loader.php ├── mesh-object.php ├── mesh-post.php ├── mesh-term.php └── mesh-user.php ├── mesh.php └── sample-data.json /README.md: -------------------------------------------------------------------------------- 1 | # Mesh 2 | Bootstrap content into a WordPress site 3 | 4 | ### Add a Post 5 | ```php 6 | /* functions.php */ 7 | $post = new Mesh\Post('Hello World', 'post'); 8 | // add content... 9 | $post->set('post_content', 'This is your first WordPress post'); 10 | // add custom fields... 11 | $post->set('my_foo', 'bar'); 12 | // "thumbnail" is a reserved key to add post thumbnails 13 | $post->set_image('thumbnail', 'http://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/STS120LaunchHiRes-edit1.jpg/490px-STS120LaunchHiRes-edit1.jpg'); 14 | ``` 15 | 16 | ### Add a User 17 | ```php 18 | /* functions.php */ 19 | $user = new Mesh\User('Jared Novack', 'subscriber'); 20 | // add content... 21 | $user->set('description', 'Jared is cool'); 22 | // add custom fields... 23 | $user->set('my_foo', 'bar'); 24 | // add images 25 | $user->set_image('headshot', 'http://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/STS120LaunchHiRes-edit1.jpg/490px-STS120LaunchHiRes-edit1.jpg'); 26 | ``` 27 | 28 | ### Import JSON 29 | See the [sample data](https://github.com/jarednova/mesh/blob/master/sample-data.json) for an example of what this should look like. 30 | ```php 31 | $loader = new Mesh\JSON_Loader(__DIR__.'/../static/data/mesh-data.json'); 32 | ``` 33 | 34 | ### WP-CLI 35 | 36 | Load your JSON file: 37 | 38 | ```sh 39 | wp mesh load_json mesh.json 40 | ``` 41 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jarednova/mesh", 3 | "description": "package to programitcaily create content for WordPress", 4 | "keywords": ["mesh", "content", "bootstrapping"], 5 | "homepage": "http://upstatement.com", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Jared Novack", 10 | "email": "jared@upstatement.com", 11 | "homepage": "http://upstatement.com" 12 | } 13 | ], 14 | "support": { 15 | "issues": "https://github.com/jarednova/timber/issues", 16 | "wiki": "https://github.com/jarednova/timber/wiki", 17 | "source": "https://github.com/jarednova/timber" 18 | }, 19 | "require": { 20 | "php": ">=5.3.0" 21 | }, 22 | "autoload": { 23 | "classmap": [ 24 | "lib/" 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/mesh-command.php: -------------------------------------------------------------------------------- 1 | 18 | * : File to load 19 | * 20 | * ## EXAMPLES 21 | * 22 | * wp mesh load_json 23 | * 24 | * @synopsis 25 | */ 26 | function load_json( $args = array('mesh.json'), $assoc_args ) { 27 | list( $filename ) = $args; 28 | $filename = trailingslashit(get_stylesheet_directory()).$filename; 29 | $loader = new Mesh\JSON_Loader(); 30 | $success = $loader->import_json_file($filename); 31 | if ($success) { 32 | return WP_CLI::success( "Loaded JSON file ".$filename ); 33 | } else { 34 | return WP_CLI::error( "Failed to load JSON file ".$filename ); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/mesh-image.php: -------------------------------------------------------------------------------- 1 | check_if_image_exists( $url ); 11 | if ($image_exists) { 12 | $upload_info = $this->get_image_data( $url ); 13 | $id = $this->create( $upload_info ); 14 | } else { 15 | $url = str_replace(' ', '%20', $url); 16 | $upload_info = $this->upload_image( $url ); 17 | $id = $this->create( $upload_info ); 18 | } 19 | return $id; 20 | } 21 | 22 | protected function create( $image_info, $post_type = 'attachment' ) { 23 | $filename = $image_info['file']; 24 | $pathinfo = pathinfo( $filename ); 25 | $filetype = wp_check_filetype( basename( $filename ), null ); 26 | $data = array( 27 | 'post_title' => $pathinfo['basename'], 28 | 'post_mime_type' => $filetype['type'], 29 | 'guid' => $image_info['url'], 30 | 'post_type' => $post_type, 31 | 'post_content' => '', 32 | 'post_status' => 'inherit' 33 | ); 34 | $pid = wp_insert_attachment( $data, $filename, 1 ); 35 | if ( !function_exists( 'wp_generate_attachment_metadata' ) ) { 36 | require_once( ABSPATH . 'wp-admin/includes/image.php' ); 37 | } 38 | $metadata = wp_generate_attachment_metadata( $pid, $image_info['file'] ); 39 | wp_update_attachment_metadata( $pid, $metadata ); 40 | return $pid; 41 | } 42 | 43 | protected function get_image_data( $url ) { 44 | $location = self::get_sideloaded_file_loc( $url ); 45 | $new_url = str_replace(ABSPATH, '', $location); 46 | $new_url = get_site_url().'/'.$new_url; 47 | $data = array('file' => $location, 'url' => $new_url); 48 | return $data; 49 | } 50 | 51 | protected function upload_image( $url ) { 52 | $location = self::get_sideloaded_file_loc( $url ); 53 | if ( !function_exists( 'download_url' ) ) { 54 | require_once ABSPATH . '/wp-admin/includes/file.php'; 55 | } 56 | $tmp = download_url( $url ); 57 | $file_array = array(); 58 | $file_array['tmp_name'] = $tmp; 59 | // If error storing temporarily, unlink 60 | if ( is_wp_error( $tmp ) ) { 61 | @unlink( $file_array['tmp_name'] ); 62 | $file_array['tmp_name'] = ''; 63 | } 64 | // do the validation and storage stuff 65 | $locinfo = pathinfo( $location ); 66 | return wp_upload_bits( $locinfo['basename'], null, file_get_contents( $file_array['tmp_name'] ) ); 67 | 68 | } 69 | 70 | protected function check_if_image_exists( $url ) { 71 | $file_name_in_fs = self::get_sideloaded_file_loc( $url ); 72 | if ( file_exists( $file_name_in_fs ) ) { 73 | return true; 74 | } 75 | return false; 76 | } 77 | 78 | //Image utils 79 | 80 | public static function get_sideloaded_file_loc( $url ) { 81 | $upload = wp_upload_dir(); 82 | $dir = $upload['path']; 83 | $file = parse_url( $url ); 84 | $path_parts = pathinfo( $file['path'] ); 85 | $basename = md5( $url ); 86 | $ext = 'jpg'; 87 | if ( isset( $path_parts['extension'] ) ) { 88 | $ext = $path_parts['extension']; 89 | } 90 | return $dir . '/' . $basename . '.' . $ext; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /lib/mesh-json-loader.php: -------------------------------------------------------------------------------- 1 | import_json_file($file); 8 | } 9 | } 10 | 11 | public function import_json_file($file) { 12 | $data = file_get_contents($file); 13 | if ($data) { 14 | $json = json_decode($data); 15 | if (isset($json->users)) { 16 | $this->import_users($json->users); 17 | } 18 | if (isset($json->posts)) { 19 | $this->import_posts($json->posts); 20 | } 21 | if (isset($json->terms)) { 22 | $this->import_terms($json->terms); 23 | } 24 | if (json_last_error()) { 25 | trigger_error( 'Mesh: There is an error in your JSON file : '.$file ); 26 | return false; 27 | } 28 | return true; 29 | } 30 | return false; 31 | } 32 | 33 | protected function import_users($array) { 34 | foreach($array as $user_data) { 35 | $user = new User($user_data->display_name); 36 | foreach($user_data as $key => $value) { 37 | if (strstr($key, ':image')) { 38 | //insert image 39 | $image_key = explode(':', $key); 40 | $user->set_image($image_key[0], $value); 41 | } elseif (strstr($key, ':repeater')) { 42 | $rep_key = explode(':', $key); 43 | $user->set_repeater($rep_key[0], $value); 44 | } else { 45 | $user->set($key, $value); 46 | } 47 | 48 | } 49 | } 50 | } 51 | 52 | protected function import_posts($array) { 53 | foreach( $array as $post_data ) { 54 | $post = new Post( $post_data->post_title, 'post' ); 55 | foreach( $post_data as $key => $value ) { 56 | if ( $key === "thumbnail" ) { 57 | $post->set_image( $key, $value ); 58 | } else if ( $key === "terms" ) { 59 | $post->set_terms( $key, $value ); 60 | } else { 61 | $post->set( $key, $value ); 62 | } 63 | } 64 | } 65 | } 66 | 67 | protected function import_terms($array) { 68 | foreach( $array as $term_data ) { 69 | $term = new Term( $term_data->name, $term_data->taxonomy ); 70 | if( $term->id ) { 71 | foreach( $term_data as $key => $value ) { 72 | $term->set( $key, $value ); 73 | } 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/mesh-object.php: -------------------------------------------------------------------------------- 1 | id = $maybe_id; 11 | return; 12 | } 13 | $this->id = $this->maybe_create( $title, $post_type ); 14 | } 15 | 16 | protected function get_recognized_fields() { 17 | return array( 'ID', 'post_title', 'post_content', 'post_name', 'post_status', 'post_type', 'post_author', 'ping_status', 'post_parent', 'menu_order', 'to_ping', 'pinged', 'post_password', 'guid', 'post_excerpt', 'post_date', 'post_date_gmt', 'comment_status', 'post_content_filtered' ); 18 | } 19 | 20 | protected function maybe_create( $title, $post_type ) { 21 | $slug = sanitize_title( $title ); 22 | $id = $this->check_if_post_exists( $slug, $post_type ); 23 | if ( !$id ) { 24 | $id = $this->create( $title, $post_type ); 25 | } 26 | return $id; 27 | 28 | } 29 | 30 | protected function create( $title, $post_type ) { 31 | //insert post 32 | $data = array( 'post_title' => $title, 'post_type' => $post_type, 'post_status' => 'publish' ); 33 | return wp_insert_post( $data ); 34 | } 35 | 36 | protected function check_if_post_exists( $slug, $post_type ) { 37 | global $wpdb; 38 | $row = $wpdb->get_row( "SELECT * FROM $wpdb->posts WHERE post_name = '$slug'" ); 39 | if ( $row && isset( $row->ID ) ) { 40 | return $row->ID; 41 | } 42 | return false; 43 | } 44 | 45 | protected function update_meta( $key, $value, $override ) { 46 | if ( $override ) { 47 | update_post_meta( $this->id, $key, $value ); 48 | return; 49 | } 50 | add_post_meta( $this->id, $key, $value, true ); 51 | } 52 | 53 | protected function update_recognized_field( $key, $value, $override = false ) { 54 | $post = get_post( $this->id ); 55 | if ( !$override && isset( $post->$key ) && strlen( $post->$key ) ) { 56 | return; 57 | } 58 | $update_data = array( 'ID' => $this->id, $key => $value ); 59 | wp_update_post( $update_data ); 60 | } 61 | 62 | protected function update_thumbnail( $url, $override = false ) { 63 | $thumbnail_id = get_post_meta( $this->id, '_thumbnail_id', true ); 64 | if ( $thumbnail_id && !$override ) { 65 | return; 66 | } 67 | $image = new Image( $url ); 68 | $this->set( '_thumbnail_id', $image->id ); 69 | $image->set( 'post_parent', $this->id ); 70 | } 71 | 72 | public function set_image( $key, $url, $override = false ) { 73 | if ($key === 'thumbnail') { 74 | $this->update_thumbnail( $url, $override ); 75 | } else { 76 | $image = new Image( $url ); 77 | $this->set( $key, $image->id ); 78 | } 79 | } 80 | 81 | public function set_terms( $key, $terms ) { 82 | foreach( $terms as $term_data ) { 83 | $term = new Term($term_data->name, $term_data->taxonomy); 84 | wp_set_object_terms( $this->id, intval($term->id), $term_data->taxonomy, true ); 85 | } 86 | } 87 | 88 | public function set( $key, $value, $override = false ) { 89 | if ( in_array( $key, self::get_recognized_fields() ) ) { 90 | $this->update_recognized_field( $key, $value, $override = true ); 91 | } else { 92 | $this->update_meta( $key, $value, $override ); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /lib/mesh-term.php: -------------------------------------------------------------------------------- 1 | id = $this->maybe_create( $term_name, $taxonomy ); 8 | $this->taxonomy = $taxonomy; 9 | } 10 | } 11 | 12 | /* 13 | * @return int 14 | */ 15 | protected function maybe_create( $term_name, $taxonomy ) { 16 | if (!taxonomy_exists($taxonomy)) { 17 | register_taxonomy($taxonomy, 'post'); 18 | } 19 | if( taxonomy_exists( $taxonomy ) && !term_exists( $term_name ) ) { 20 | return $this->create( $term_name, $taxonomy ); 21 | } 22 | return term_exists($term_name, $taxonomy); 23 | } 24 | 25 | protected function create( $term_name, $taxonomy ) { 26 | return wp_insert_term( $term_name, $taxonomy ); 27 | } 28 | 29 | public function set( $key, $value, $override = false ) { 30 | if( $key !== "name" && $key !== "taxonomy" ) { 31 | $data = array( $key => $value ); 32 | wp_update_term( $this->id["term_id"], $this->taxonomy, $data ); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/mesh-user.php: -------------------------------------------------------------------------------- 1 | id = $maybe_id; 12 | return; 13 | } 14 | $this->id = $this->maybe_create( $display_name, $role ); 15 | } 16 | 17 | protected function get_recognized_fields() { 18 | return array( 'ID', 'user_login', 'user_pass', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'user_activation_key', 'user_status', 'display_name' ); 19 | } 20 | 21 | protected function maybe_create( $display_name, $role ) { 22 | $slug = sanitize_title( $display_name ); 23 | $id = username_exists( $slug ); 24 | if ( !$id || $id == null ) { 25 | $id = $this->create( $display_name, $role ); 26 | } 27 | return $id; 28 | } 29 | 30 | protected function create( $display_name, $role ) { 31 | $slug = sanitize_title( $display_name ); 32 | $names = explode( ' ', trim( $display_name ) ); 33 | $first_name = $names[0]; 34 | $non_first_names = $names; 35 | array_shift( $non_first_names ); 36 | $last_name = implode( ' ', $non_first_names ); 37 | $data = array( 'display_name' => $display_name, 'user_pass' => $this->default_password, 'first_name' => $first_name, 'last_name' => $last_name, 'role' => $role, 'user_login' => $slug, 'user_email' => $slug.'@example.org' ); 38 | $uid = wp_insert_user( $data ); 39 | return $uid; 40 | } 41 | 42 | public function set_repeater( $key, $array ) { 43 | $this->set( $key, count( $array ) ); 44 | $i = 0; 45 | foreach ( $array as $entry ) { 46 | foreach ( $entry as $ekey => $eval ) { 47 | $this->set( $key.'_'.$i.'_'.$ekey, $eval ); 48 | } 49 | $i++; 50 | } 51 | } 52 | 53 | public function set_image( $key, $url ) { 54 | $image = new Image( $url ); 55 | $this->set( $key, $image->id ); 56 | } 57 | 58 | public function set( $key, $value, $override = false ) { 59 | if ( in_array( $key, self::get_recognized_fields() ) ) { 60 | $this->update_recognized_field( $key, $value, $override ); 61 | } else { 62 | $this->update_meta( $key, $value, $override ); 63 | } 64 | } 65 | 66 | protected function update_recognized_field( $key, $value, $override ) { 67 | $user = get_user_by( 'id', $this->id ); 68 | if ( !$override && isset( $post->$key ) && strlen( $post->$key ) ) { 69 | return; 70 | } 71 | //this causes plugin conflicts with ACF: 72 | //$update_data = array( 'ID' => $this->id, $key => $value ); 73 | //wp_update_user($update_data); 74 | //so let's do a brute-force version 75 | global $wpdb; 76 | $query = "UPDATE $wpdb->users SET $key = '$value' WHERE ID = $this->id LIMIT 1"; 77 | $wpdb->query( $query ); 78 | } 79 | 80 | protected function update_meta( $key, $value, $override ) { 81 | update_user_meta( $this->id, $key, $value ); 82 | return; 83 | if ( $override ) { 84 | update_user_meta( $this->id, $key, $value ); 85 | return; 86 | } 87 | add_user_meta( $this->id, $key, $value, true ); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /mesh.php: -------------------------------------------------------------------------------- 1 |