├── .cursor └── rules │ └── fakerpress-core.mdc ├── .distfiles ├── .distignore ├── .puprc ├── bun.lock ├── fakerpress.php ├── index.php ├── languages ├── fakerpress.pot └── index.php ├── license.txt ├── phpcs.xml ├── readme.txt ├── src ├── FakerPress │ ├── Admin.php │ ├── Admin │ │ ├── Menu.php │ │ └── View │ │ │ ├── Abstract_View.php │ │ │ ├── Attachment_View.php │ │ │ ├── Changelog_View.php │ │ │ ├── Comment_View.php │ │ │ ├── Error_View.php │ │ │ ├── Factory.php │ │ │ ├── Interface_View.php │ │ │ ├── Post_View.php │ │ │ ├── Settings_View.php │ │ │ ├── Term_View.php │ │ │ └── User_View.php │ ├── Ajax.php │ ├── Assets.php │ ├── Contracts │ │ ├── Container.php │ │ └── Service_Provider.php │ ├── Dates.php │ ├── Exceptions │ │ ├── Container_Exception.php │ │ └── Not_Bound_Exception.php │ ├── Field.php │ ├── Fields │ │ ├── Factory.php │ │ ├── Field_Abstract.php │ │ ├── Field_Interface.php │ │ ├── Fieldset_Field.php │ │ └── Raw_Field.php │ ├── Hooks.php │ ├── Module │ │ ├── Abstract_Module.php │ │ ├── Attachment.php │ │ ├── Comment.php │ │ ├── Factory.php │ │ ├── Interface_Module.php │ │ ├── Meta.php │ │ ├── Post.php │ │ ├── Term.php │ │ └── User.php │ ├── Plugin.php │ ├── Provider │ │ ├── HTML.php │ │ ├── Image │ │ │ ├── LoremPicsum.php │ │ │ └── Placeholder.php │ │ ├── Text │ │ │ └── Base.php │ │ ├── WP_Attachment.php │ │ ├── WP_Comment.php │ │ ├── WP_Meta.php │ │ ├── WP_Post.php │ │ ├── WP_Term.php │ │ └── WP_User.php │ ├── Template.php │ ├── Utils.php │ └── Utils │ │ └── Assets.php ├── data │ └── readme.php ├── functions │ ├── assets.php │ ├── conditionals.php │ ├── container.php │ ├── date.php │ ├── load.php │ ├── sorting.php │ └── variables.php ├── resources │ ├── font │ │ ├── fakerpress.eot │ │ ├── fakerpress.svg │ │ ├── fakerpress.ttf │ │ └── fakerpress.woff │ ├── img │ │ ├── select2-spinner.gif │ │ ├── select2.png │ │ └── select2x2.png │ ├── js │ │ ├── field.dependency.js │ │ ├── fields.js │ │ ├── module.js │ │ ├── qs.js │ │ └── select2.js │ └── pcss │ │ ├── admin.pcss │ │ ├── datepicker.pcss │ │ ├── font.pcss │ │ ├── jquery-ui.pcss │ │ ├── messages.pcss │ │ ├── select2-wordpress.pcss │ │ └── select2.pcss └── templates │ ├── fields │ ├── components │ │ ├── container │ │ │ ├── end.php │ │ │ └── start.php │ │ ├── field.php │ │ ├── form │ │ │ ├── end.php │ │ │ └── start.php │ │ ├── label.php │ │ ├── table │ │ │ ├── end.php │ │ │ └── start.php │ │ └── wrap │ │ │ ├── end.php │ │ │ └── start.php │ ├── fieldset.php │ ├── fieldset │ │ └── children.php │ └── raw.php │ └── pages │ ├── attachments.php │ ├── changelog.php │ ├── comments.php │ ├── error.php │ ├── posts.php │ ├── settings.php │ ├── terms.php │ └── users.php └── webpack.config.js /.distfiles: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bordoni/fakerpress/9d7a27014e1fb700e0bad8a863678ed42216ed73/.distfiles -------------------------------------------------------------------------------- /.distignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | gulpfile.babel.js 3 | .distignore 4 | .distfiles 5 | package-lock.json 6 | bun.lock 7 | .git -------------------------------------------------------------------------------- /.puprc: -------------------------------------------------------------------------------- 1 | { 2 | "build": [ 3 | "@composer install --no-dev --no-scripts", 4 | "@composer run strauss-release", 5 | "bun install", 6 | "bun run build" 7 | ], 8 | "build_dev": [ 9 | "@composer install --no-scripts", 10 | "@composer run strauss-release", 11 | "bun install", 12 | "bun run build" 13 | ], 14 | "checks": { 15 | "version-conflict": { 16 | "fail_method": "error", 17 | "fail_method_dev": "warn" 18 | } 19 | }, 20 | "i18n": { 21 | "path": "languages", 22 | "formats": ["mo"], 23 | "slug": "wp-plugins/fakerpress/stable", 24 | "textdomain": "fakerpress", 25 | "url": "https://translate.wordpress.org" 26 | }, 27 | "paths": { 28 | "build_dir": ".pup-build", 29 | "changelog": "readme.txt", 30 | "css": [], 31 | "js": [], 32 | "versions": [ 33 | { 34 | "file": "src/FakerPress/Plugin.php", 35 | "regex": "(const[ ]*VERSION[ ]*={1}[ ]*['\"]{1})([^'\"]+)" 36 | }, 37 | { 38 | "file": "fakerpress.php", 39 | "regex": "(Version: +)(.+)" 40 | }, 41 | { 42 | "file": "readme.txt", 43 | "regex": "(Stable tag: +)(.+)" 44 | } 45 | ], 46 | "zip_dir": ".pup-zip" 47 | }, 48 | "repo": "bordoni/fakerpress", 49 | "zip_use_default_ignore": false, 50 | "zip_name": "fakerpress" 51 | } 52 | -------------------------------------------------------------------------------- /fakerpress.php: -------------------------------------------------------------------------------- 1 | 94 |
95 |

96 | FakerPress' 101 | ); 102 | ?> 103 |
104 | 105 |
106 | 107 |

108 |
109 | 2 | 3 | 4 | 5 | 6 | 7 | */tests/* 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | src/Test.php 18 | 19 | 20 | */tests/* 21 | */vendor/* 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/FakerPress/Admin.php: -------------------------------------------------------------------------------- 1 | set_template_origin( make( Plugin::class ) ) 55 | ->set_template_folder( 'src/templates/pages' ); 56 | } 57 | 58 | /** 59 | * Creating messages in a standard way 60 | * 61 | * @todo Move to the Page Abstract. 62 | * 63 | * @since 0.1.2 64 | * 65 | * @param string $type The type of the Message 66 | * @param integer $priority The priority to show this message 67 | * 68 | * @param string $html HTML or text of the message 69 | */ 70 | public static function add_message( $html, $type = 'success', $priority = 10 ) { 71 | $priority = absint( $priority ); 72 | 73 | /** 74 | * @filter fakerpress.messages.allowed_html 75 | * @since 0.1.2 76 | */ 77 | self::$messages[] = $message = (object) [ 78 | 'html' => wp_kses( wpautop( $html ), apply_filters( 'fakerpress.messages.allowed_html', [] ), [ 'http', 'https' ] ), 79 | 'type' => esc_attr( $type ), 80 | 'priority' => $priority === 0 ? $priority + 1 : $priority, 81 | ]; 82 | 83 | usort( self::$messages, 'FakerPress\sort_by_priority' ); 84 | 85 | return $message; 86 | } 87 | 88 | /** 89 | * Method triggered to add messages recorded in this request to the admin front-end 90 | * 91 | * @todo Move to the Page Abstract. 92 | * 93 | * @since 0.1.2 94 | * @return null Actions do not return 95 | */ 96 | public function _action_admin_notices() { 97 | foreach ( self::$messages as $k => $message ) { 98 | $classes = [ 99 | // Plugin class to give the styling 100 | 'fakerpress-message', 101 | // This is to use WordPress JS to move them above the h2 102 | 'notice', 103 | ]; 104 | 105 | if ( 0 === $k ) { 106 | $classes[] = 'first'; 107 | } 108 | 109 | if ( $k + 1 === count( self::$messages ) ) { 110 | $classes[] = 'last'; 111 | } 112 | 113 | switch ( $message->type ) { 114 | case 'error': 115 | $classes[] = 'fakerpress-message-error'; 116 | break; 117 | case 'success': 118 | $classes[] = 'fakerpress-message-success'; 119 | break; 120 | case 'warning': 121 | $classes[] = 'fakerpress-message-warning'; 122 | break; 123 | default: 124 | break; 125 | } 126 | 127 | ?> 128 |
html, apply_filters( 'fakerpress.messages.allowed_html', [] ), [ 129 | 'http', 130 | 'https' 131 | ] ); ?>
132 | is_active() ) { 160 | return $admin_title; 161 | } 162 | $view = make( Factory::class )->get_current_view(); 163 | 164 | $pos = strpos( $admin_title, $title ); 165 | if ( false !== $pos ) { 166 | $admin_title = substr_replace( $admin_title, sprintf( $this->get_base_title(), $view->get_title() ), $pos, strlen( $title ) ); 167 | } 168 | 169 | return $admin_title; 170 | } 171 | 172 | public function _filter_messages_allowed_html() { 173 | return [ 174 | 'a' => [ 175 | 'class' => [], 176 | 'href' => [], 177 | 'title' => [] 178 | ], 179 | 'br' => [ 180 | 'class' => [], 181 | ], 182 | 'p' => [ 183 | 'class' => [], 184 | ], 185 | 'em' => [ 186 | 'class' => [], 187 | ], 188 | 'strong' => [ 189 | 'class' => [], 190 | ], 191 | 'b' => [ 192 | 'class' => [], 193 | ], 194 | 'i' => [ 195 | 'class' => [], 196 | ], 197 | 'ul' => [ 198 | 'class' => [], 199 | ], 200 | 'ol' => [ 201 | 'class' => [], 202 | ], 203 | 'li' => [ 204 | 'class' => [], 205 | ], 206 | ]; 207 | } 208 | 209 | /** 210 | * Filter the WordPress Version on plugins pages to display plugin version 211 | * 212 | * @since 0.1.0 213 | * @uses __ 214 | * 215 | * @uses \FakerPress\Plugin::$slug 216 | * @return string 217 | */ 218 | public function _filter_admin_footer_text( $text ) { 219 | if ( ! $this->is_active() ) { 220 | return $text; 221 | } 222 | 223 | return 224 | '' . esc_attr__( 'Contact Support', 'fakerpress' ) . ' | ' . 225 | str_replace( 226 | [ '[stars]', '[wp.org]' ], 227 | [ 228 | '★★★★★', 229 | 'wordpress.org' 230 | ], 231 | __( 'Add your [stars] on [wp.org] to spread the love.', 'fakerpress' ) 232 | ); 233 | } 234 | 235 | /** 236 | * Filter the WordPress Version on plugins pages to display the plugin version 237 | * 238 | * @since 0.1.0 239 | * @uses \FakerPress\Plugin::admin_url 240 | * @uses \FakerPress\Plugin::VERSION 241 | * @uses __ 242 | * 243 | * @uses \FakerPress\Plugin::$slug 244 | * @return string 245 | */ 246 | public function _filter_update_footer( $text ) { 247 | if ( ! $this->is_active() ) { 248 | return $text; 249 | } 250 | 251 | $sponsor = sprintf( 252 | ' %1$s | ', 253 | esc_html__( 'Sponsor the project on GitHub', 'fakerpress' ), 254 | Plugin::ext_site_url( '/r/sponsor' ), 255 | esc_attr__( 'Help by sponsoring the Project on GitHub', 'fakerpress' ) 256 | ); 257 | $translate = sprintf( 258 | ' %1$s | ', 259 | esc_html__( 'Translate', 'fakerpress' ), 260 | Plugin::ext_site_url( '/r/translate' ), 261 | esc_attr__( 'Help us with Translations for the FakerPress project', 'fakerpress' ) 262 | ); 263 | $version = sprintf( 264 | '%1$s', 265 | esc_html__( 'Version: ', 'fakerpress' ) . esc_attr( Plugin::VERSION ), 266 | esc_url( Plugin::admin_url( 'view=changelog&version=' . esc_attr( Plugin::VERSION ) ) ), 267 | esc_attr__( 'View what changed in this version', 'fakerpress' ) 268 | ); 269 | 270 | return $sponsor . $translate . $version; 271 | } 272 | 273 | public function _filter_body_class( $classes ) { 274 | $more = [ 275 | $classes, 276 | '__fakerpress', 277 | ]; 278 | 279 | return implode( ' ', $more ); 280 | } 281 | 282 | /** 283 | * Filters the array of row meta for each plugin in the Plugins list table. 284 | * 285 | * @since 0.6.3 286 | * 287 | * @param array $plugin_meta An array of the plugin's metadata. 288 | * @param string $plugin_file Path to the plugin file relative to the plugins directory. 289 | * 290 | * @return array Updated array of the plugin's metadata. 291 | */ 292 | public function filter_plugin_row_meta( array $plugin_meta, $plugin_file ) { 293 | if ( 'fakerpress/fakerpress.php' !== $plugin_file ) { 294 | return $plugin_meta; 295 | } 296 | 297 | $plugin_meta[] = sprintf( 298 | '%2$s', 299 | 'https://fakerpress.com/r/sponsor', 300 | esc_html_x( 'Sponsor', 'verb', 'fakerpress' ) 301 | ); 302 | 303 | return $plugin_meta; 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/Menu.php: -------------------------------------------------------------------------------- 1 | $slug, 56 | 'title' => esc_attr( $title ), 57 | 'hook' => null, // Will be set later from WP. 58 | 'label' => esc_attr( $label ), 59 | 'capability' => sanitize_key( $capability ), 60 | 'priority' => absint( $priority ),// Used to set up error page. 61 | 'callback' => $callback, // Used to set up error page. 62 | 'parent' => $parent, // Used to set up error page. 63 | ]; 64 | 65 | if ( ! is_callable( $menu->callback ) ) { 66 | $menu->callback = static function () use ( $menu ) { 67 | $menu = make( Menu::class )->get_current(); 68 | 69 | return make( Admin::class )->render( $menu->slug, [ 'view' => $menu ] ); 70 | }; 71 | } 72 | 73 | static::$needs_sorting = true; 74 | } 75 | 76 | /** 77 | * Given a slug updates that menu object with the new variables. 78 | * 79 | * @since 0.6.0 80 | * 81 | * @param string $slug 82 | * @param array $update_with 83 | * 84 | * @return bool 85 | */ 86 | public function update( string $slug, array $update_with ) { 87 | $menu = $this->get( $slug ); 88 | 89 | if ( empty( $menu ) ) { 90 | return false; 91 | } 92 | 93 | $menu = (object) array_merge( (array) $menu, (array) $update_with ); 94 | 95 | static::$items[ $slug ] = $menu; 96 | 97 | return true; 98 | } 99 | 100 | /** 101 | * Gets all the menu items sorted by their priority. 102 | * 103 | * @since 0.6.0 104 | * 105 | * @return array 106 | */ 107 | public function get_all(): array { 108 | if ( static::$needs_sorting ) { 109 | uasort( static::$items, 'FakerPress\sort_by_priority' ); 110 | static::$needs_sorting = false; 111 | } 112 | 113 | return static::$items; 114 | } 115 | 116 | /** 117 | * Gets a specific item from the menu, using its slug. 118 | * 119 | * @since 0.6.0 120 | * 121 | * @param string $slug 122 | * 123 | * @return object|null 124 | */ 125 | public function get( string $slug ) { 126 | $all = $this->get_all(); 127 | 128 | return $all[ $slug ] ?? null; 129 | } 130 | 131 | /** 132 | * Filter the `$submenu_file` global right before WordPress builds the Administration Menu 133 | * 134 | * @since 0.6.0 135 | * 136 | * @param string $submenu_file Which is the current submenu file. 137 | * 138 | * @return string 139 | */ 140 | public function filter_submenu_file( $submenu_file ) { 141 | if ( ! make( Admin::class )->is_active() ) { 142 | return $submenu_file; 143 | } 144 | 145 | $view = make( Admin\View\Factory::class )->get_current_view(); 146 | 147 | if ( 148 | 0 !== $view->get_menu_priority() 149 | ) { 150 | $submenu_file = Plugin::$slug . '&view=' . $view::get_slug(); 151 | } 152 | 153 | return $submenu_file; 154 | } 155 | 156 | /** 157 | * Method triggered to add the menu to WordPress administration 158 | * 159 | * @since 0.6.0 160 | * 161 | * @uses \FakerPress\Plugin::$slug 162 | * @uses esc_attr__ 163 | * @uses add_menu_page 164 | * @uses add_submenu_page 165 | * @uses current_user_can 166 | * 167 | * @return null Actions do not return 168 | */ 169 | public function register_menus_to_wp() { 170 | foreach ( $this->get_all() as $menu ) { 171 | if ( ! current_user_can( $menu->capability ) ) { 172 | continue; 173 | } 174 | 175 | $update = []; 176 | 177 | if ( empty( $menu->parent ) ) { 178 | $update['hook'] = add_menu_page( 179 | $menu->title, 180 | $menu->label, 181 | $menu->capability, 182 | $menu->slug, 183 | $menu->callback, 184 | 'none' 185 | ); 186 | } else { 187 | $update['hook'] = add_submenu_page( 188 | $menu->parent, 189 | $menu->title, 190 | $menu->label, 191 | $menu->capability, 192 | "{$menu->parent}&view={$menu->slug}", 193 | $menu->callback // The submenus will likely never be called due to howe register. 194 | ); 195 | } 196 | 197 | $this->update( $menu->slug, $update ); 198 | } 199 | 200 | // Change the Default Submenu for FakerPress menus 201 | if ( ! empty( $GLOBALS['submenu'][ Plugin::$slug ] ) ) { 202 | $GLOBALS['submenu'][ Plugin::$slug ][0][0] = esc_attr__( 'Settings', 'fakerpress' ); 203 | } 204 | } 205 | 206 | /** 207 | * Properly sets the current screen, this is a hacky solution because of how poorly WordPress handles Admin menus not 208 | * using the page param. 209 | * 210 | * @since 0.6.4 211 | * 212 | * @param \WP_Screen $screen Which screen are we in? 213 | * 214 | * @return void 215 | */ 216 | public function correctly_set_current_screen( $screen ) { 217 | $view = make( View_Factory::class )->get_current_view(); 218 | if ( ! $view ) { 219 | return; 220 | } 221 | 222 | if ( ! $view->has_menu() ) { 223 | return; 224 | } 225 | 226 | $menu = $view->get_menu(); 227 | 228 | set_current_screen( $menu->hook ); 229 | 230 | global $page_hook; 231 | 232 | $page_hook = $menu->hook; 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/View/Abstract_View.php: -------------------------------------------------------------------------------- 1 | has_menu() ) { 69 | return; 70 | } 71 | 72 | make( Menu::class )->add( 73 | static::get_menu_slug(), 74 | $this->get_title(), 75 | $this->get_label(), 76 | $this->get_capability_required(), 77 | $this->get_menu_priority(), 78 | [ $this, 'render_view' ], 79 | $this->get_menu_parent() 80 | ); 81 | } 82 | 83 | /** 84 | * @inheritDoc 85 | */ 86 | public function has_menu(): bool { 87 | return false; 88 | } 89 | 90 | /** 91 | * @inheritDoc 92 | */ 93 | public function is_top_menu(): bool { 94 | return false; 95 | } 96 | 97 | /** 98 | * @inheritDoc 99 | */ 100 | public function get_menu_parent() { 101 | if ( $this->is_top_menu() ) { 102 | return null; 103 | } 104 | 105 | return Settings_View::get_menu_slug(); 106 | } 107 | 108 | /** 109 | * @inheritDoc 110 | */ 111 | public function get_menu() { 112 | return make( Menu::class )->get( static::get_menu_slug() ); 113 | } 114 | 115 | /** 116 | * @inheritDoc 117 | */ 118 | public function get_capability_required(): string { 119 | return 'publish_posts'; 120 | } 121 | 122 | /** 123 | * @inheritDoc 124 | */ 125 | public function get_menu_priority(): int { 126 | return 10; 127 | } 128 | 129 | /** 130 | * @inheritDoc 131 | */ 132 | protected function get_rendering_arguments(): array { 133 | return []; 134 | } 135 | 136 | /** 137 | * @inheritDoc 138 | */ 139 | public function render_view(): string { 140 | // WordPress bug forces us to check if we are in a top view since unregistered menu items won't use the correct filtering method. 141 | if ( $this->is_top_menu() ) { 142 | $view = make( Factory::class )->get_current_view(); 143 | 144 | // Only do anything in case we are in a diff view from the current one. 145 | if ( $view::get_slug() !== static::get_slug() ) { 146 | return $view->render_view(); 147 | } 148 | } 149 | 150 | return $this->render( static::get_slug(), $this->get_rendering_arguments() ); 151 | } 152 | 153 | /** 154 | * @inheritDoc 155 | */ 156 | public function setup_template(): void { 157 | // Builds the template object for usage. 158 | $this->set_template_origin( make( Plugin::class ) ) 159 | ->set_template_folder( 'src/templates/pages' ) 160 | ->set_template_context_extract( true ); 161 | } 162 | 163 | /** 164 | * @inheritDoc 165 | */ 166 | public function hook(): void { 167 | add_action( 'admin_menu', [ $this, 'register_menu' ] ); 168 | } 169 | 170 | /** 171 | * @inheritDoc 172 | */ 173 | public function parse_request() { 174 | // When dealing with a GET request return true since a nonce check is not required. 175 | if ( ! is_post_request() ) { 176 | return false; 177 | } 178 | 179 | $nonce_slug = Plugin::$slug . '.request.' . static::get_slug(); 180 | 181 | if ( ! check_admin_referer( $nonce_slug ) ) { 182 | return false; 183 | } 184 | 185 | return true; 186 | } 187 | 188 | } 189 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/View/Attachment_View.php: -------------------------------------------------------------------------------- 1 | parse_request( null, get_request_var( Plugin::$slug, [] ) ); 60 | 61 | if ( ! empty( $results ) ) { 62 | return Admin::add_message( 63 | sprintf( 64 | __( 'Faked %d new %s: [ %s ]', 'fakerpress' ), 65 | count( $results ), 66 | _n( 'user', 'users', count( $results ), 'fakerpress' ), 67 | implode( ', ', array_map( [ $this, 'format_link' ], $results ) ) 68 | ) 69 | ); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/View/Changelog_View.php: -------------------------------------------------------------------------------- 1 | ' . absint( $id ) . ''; 59 | } 60 | 61 | /** 62 | * @inheritDoc 63 | */ 64 | public function parse_request() { 65 | // The Abstract just checks for a nonce actually super handy. 66 | if ( ! parent::parse_request() ) { 67 | return; 68 | } 69 | 70 | // After this point we are safe to say that we have a good POST request 71 | $results = (array) make( Comment::class )->parse_request( null, get_request_var( Plugin::$slug, [] ) ); 72 | 73 | if ( ! empty( $results ) ) { 74 | return Admin::add_message( 75 | sprintf( 76 | __( 'Faked %d new %s: [ %s ]', 'fakerpress' ), 77 | count( $results ), 78 | _n( 'comment', 'comments', count( $results ), 'fakerpress' ), 79 | implode( ', ', array_map( [ $this, 'format_link' ], $results ) ) 80 | ) 81 | ); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/View/Error_View.php: -------------------------------------------------------------------------------- 1 | views ) ) { 35 | $views_classes = [ 36 | Attachment_View::class, 37 | Comment_View::class, 38 | Post_View::class, 39 | Settings_View::class, 40 | Error_View::class, 41 | Changelog_View::class, 42 | Term_View::class, 43 | User_View::class, 44 | ]; 45 | foreach ( $views_classes as $view_class ) { 46 | $this->container->singleton( $view_class, $view_class, [ 'setup_template', 'hook' ] ); 47 | $this->views[] = $this->container->make( $view_class ); 48 | } 49 | } 50 | 51 | /** 52 | * Allows the filtering of the FakerPress available modules. 53 | * 54 | * @since 0.6.0 55 | * 56 | * @param Abstract_View[] $views Which modules are available. 57 | */ 58 | return apply_filters( 'fakerpress.admin.views', $this->views ); 59 | } 60 | 61 | /** 62 | * Register all the Admin Views as Singletons and initializes them. 63 | * 64 | * @since 0.6.0 65 | */ 66 | public function register() { 67 | // Register the provider as a singleton. 68 | $this->container->singleton( static::class, $this ); 69 | 70 | // When fetching all items it will initialize. 71 | $this->get_all(); 72 | } 73 | 74 | /** 75 | * Fetches the current FakerPress view. 76 | * 77 | * @since 0.6.4 78 | * 79 | * @return Abstract_View|null 80 | */ 81 | public function get_current_view() { 82 | $page = get_request_var( 'page' ); 83 | if ( Plugin::$slug !== $page ) { 84 | return null; 85 | } 86 | 87 | $views = array_filter( $this->get_all(), static function( $view ) { 88 | return $view->is_current_view(); 89 | } ); 90 | 91 | if ( empty( $views ) ) { 92 | return null; 93 | } 94 | 95 | // Return the first view that has current view as true. 96 | return reset( $views ); 97 | } 98 | 99 | /** 100 | * Gets a specific view based on its slug. 101 | * 102 | * @since 0.6.4 103 | * 104 | * @param string $slug Which view we are looking for. 105 | * 106 | * @return Abstract_View|null 107 | */ 108 | public function get( string $slug ) { 109 | $views = array_filter( $this->get_all(), static function( $view ) use ( $slug ) { 110 | return $view::get_slug() === $slug; 111 | } ); 112 | 113 | if ( empty( $views ) ) { 114 | return null; 115 | } 116 | 117 | return reset( $views ); 118 | } 119 | 120 | /** 121 | * If we are in a particular view of FakerPress we trigger the parse of that request. 122 | * 123 | * @since 0.6.4 124 | */ 125 | public function parse_current_view_request(): void { 126 | $view = $this->get_current_view(); 127 | 128 | if ( empty( $view ) ) { 129 | return; 130 | } 131 | 132 | $slug = $view::get_slug(); 133 | 134 | /** 135 | * Allow third-party hooking of the admin view request level. 136 | * 137 | * @since 0.6.0 138 | * 139 | * @param Abstract_View $view Which view we are parsing the request from. 140 | */ 141 | do_action( 'fakerpress.admin.view.request', $view ); 142 | 143 | /** 144 | * Allow third-party hooking of the admin view request level. 145 | * 146 | * @since 0.6.0 147 | * 148 | * @param Abstract_View $view Which view we are parsing the request from. 149 | */ 150 | do_action( "fakerpress.admin.view.{$slug}.request", $view ); 151 | 152 | // Parse the request from the view object. 153 | $view->parse_request(); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/View/Interface_View.php: -------------------------------------------------------------------------------- 1 | ' . absint( $id ) . ''; 58 | } 59 | 60 | /** 61 | * @inheritDoc 62 | */ 63 | public function parse_request() { 64 | // The Abstract just checks for a nonce actually super handy. 65 | if ( ! parent::parse_request() ) { 66 | return; 67 | } 68 | 69 | // After this point we are safe to say that we have a good POST request 70 | $results = (array) make( Post::class )->parse_request( null, get_request_var( Plugin::$slug, [] ) ); 71 | 72 | if ( ! empty( $results ) ) { 73 | return Admin::add_message( 74 | sprintf( 75 | __( 'Faked %d new %s: [ %s ]', 'fakerpress' ), 76 | count( $results ), 77 | _n( 'post', 'posts', count( $results ), 'fakerpress' ), 78 | implode( ', ', array_map( [ $this, 'format_link' ], $results ) ) 79 | ) 80 | ); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/View/Settings_View.php: -------------------------------------------------------------------------------- 1 | get_capability_required() ) ) { 103 | return Admin::add_message( __( 'You do not have the permissions to let it go!', 'fakerpress' ), 'error' ); 104 | } 105 | 106 | $modules = [ Post::get_slug(), Term::get_slug(), Comment::get_slug(), User::get_slug() ]; 107 | 108 | 109 | foreach ( $modules as $module_slug ) { 110 | $module = make( \FakerPress\Module\Factory::class )->get( $module_slug ); 111 | 112 | if ( ! $module ) { 113 | continue; 114 | } 115 | 116 | $items = $module::fetch(); 117 | $deleted = $module::delete( $items ); 118 | } 119 | 120 | return Admin::add_message( __( 'All data is gone for good.', 'fakerpress' ), 'success' ); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/View/Term_View.php: -------------------------------------------------------------------------------- 1 | parse_request( null, get_request_var( Plugin::$slug, [] ) ); 71 | 72 | if ( is_string( $results ) ) { 73 | return Admin::add_message( $results, 'error' ); 74 | } else { 75 | return Admin::add_message( 76 | sprintf( 77 | __( 'Faked %d new %s: [ %s ]', 'fakerpress' ), 78 | count( $results ), 79 | _n( 'term', 'terms', count( $results ), 'fakerpress' ), 80 | implode( ', ', array_map( [ $this, 'format_link' ], $results ) ) 81 | ) 82 | ); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/FakerPress/Admin/View/User_View.php: -------------------------------------------------------------------------------- 1 | ' . absint( $id ) . ''; 58 | } 59 | 60 | /** 61 | * @inheritDoc 62 | */ 63 | public function parse_request() { 64 | // The Abstract just checks for a nonce actually super handy. 65 | if ( ! parent::parse_request() ) { 66 | return; 67 | } 68 | 69 | // After this point we are safe to say that we have a good POST request 70 | $results = (array) make( User::class )->parse_request( null, get_request_var( Plugin::$slug, [] ) ); 71 | 72 | if ( ! empty( $results ) ) { 73 | return Admin::add_message( 74 | sprintf( 75 | __( 'Faked %d new %s: [ %s ]', 'fakerpress' ), 76 | count( $results ), 77 | _n( 'user', 'users', count( $results ), 'fakerpress' ), 78 | implode( ', ', array_map( [ $this, 'format_link' ], $results ) ) 79 | ) 80 | ); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/FakerPress/Assets.php: -------------------------------------------------------------------------------- 1 | false, 29 | ] 30 | ); 31 | 32 | // Register QS.js. 33 | register_asset( 34 | 'fakerpress-qs', 35 | 'qs.js', 36 | [], 37 | 'admin_enqueue_scripts', 38 | [ 39 | 'conditionals' => [ $admin, 'is_active' ], 40 | ] 41 | ); 42 | 43 | // Register Vendor Select2. 44 | register_asset( 45 | 'fakerpress-select2-styles', 46 | 'select2.css', 47 | [], 48 | 'admin_enqueue_scripts', 49 | [ 50 | 'conditionals' => [ $admin, 'is_active' ], 51 | ] 52 | ); 53 | register_asset( 54 | 'fakerpress-select2-wordpress', 55 | 'select2-wordpress.css', 56 | [ 'fakerpress-select2-styles' ], 57 | 'admin_enqueue_scripts', 58 | [ 59 | 'conditionals' => [ $admin, 'is_active' ], 60 | ] 61 | ); 62 | 63 | register_asset( 64 | 'fakerpress-select2', 65 | 'select2.js', 66 | [ 'jquery' ], 67 | 'admin_enqueue_scripts', 68 | [ 69 | 'conditionals' => [ $admin, 'is_active' ], 70 | ] 71 | ); 72 | 73 | // Register DatePicker Skins. 74 | register_asset( 75 | 'fakerpress-jquery-ui', 76 | 'jquery-ui.css', 77 | [], 78 | 'admin_enqueue_scripts', 79 | [ 80 | 'conditionals' => [ $admin, 'is_active' ], 81 | ] 82 | ); 83 | register_asset( 84 | 'fakerpress-datepicker', 85 | 'datepicker.css', 86 | [ 'fakerpress-jquery-ui' ], 87 | 'admin_enqueue_scripts', 88 | [ 89 | 'conditionals' => [ $admin, 'is_active' ], 90 | ] 91 | ); 92 | 93 | // Register the plugin CSS files. 94 | register_asset( 95 | 'fakerpress-admin', 96 | 'admin.css', 97 | [], 98 | 'admin_enqueue_scripts', 99 | [ 100 | 'conditionals' => [ $admin, 'is_active' ], 101 | ] 102 | ); 103 | register_asset( 104 | 'fakerpress-messages', 105 | 'messages.css', 106 | [], 107 | 'admin_enqueue_scripts', 108 | [ 109 | 'conditionals' => [ $admin, 'is_active' ], 110 | ] 111 | ); 112 | 113 | // Register the plugin JS files. 114 | register_asset( 115 | 'fakerpress-fields', 116 | 'fields.js', 117 | [ 'jquery', 'underscore', 'fakerpress-select2', 'jquery-ui-datepicker', 'fakerpress-module' ], 118 | 'admin_enqueue_scripts', 119 | [ 120 | 'conditionals' => [ $admin, 'is_active' ], 121 | ] 122 | ); 123 | register_asset( 124 | 'fakerpress-module', 125 | 'module.js', 126 | [ 'jquery', 'underscore', 'fakerpress-qs' ], 127 | 'admin_enqueue_scripts', 128 | [ 129 | 'conditionals' => [ $admin, 'is_active' ], 130 | ] 131 | ); 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/FakerPress/Contracts/Container.php: -------------------------------------------------------------------------------- 1 | getMessage(), $e->getCode() ); 44 | } 45 | } 46 | 47 | /** 48 | * Creates the first instance of the container, it should be used for all the subsequent calls. 49 | * 50 | * @since 0.6.2 51 | * 52 | * @return Container 53 | */ 54 | public static function init(): self { 55 | if ( empty( self::$instance ) ) { 56 | self::$instance = new self; 57 | } 58 | 59 | return static::$instance; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/FakerPress/Contracts/Service_Provider.php: -------------------------------------------------------------------------------- 1 | 'today', 14 | 'text' => esc_attr__( 'Today', 'fakerpress' ), 15 | 'min' => Chronos::today()->toDateString(), 16 | 'max' => Chronos::today()->toDateString(), 17 | ], 18 | [ 19 | 'id' => 'yesterday', 20 | 'text' => esc_attr__( 'Yesterday', 'fakerpress' ), 21 | 'min' => Chronos::yesterday()->toDateString(), 22 | 'max' => Chronos::yesterday()->toDateString(), 23 | ], 24 | [ 25 | 'id' => 'tomorrow', 26 | 'text' => esc_attr__( 'Tomorrow', 'fakerpress' ), 27 | 'min' => Chronos::tomorrow()->toDateString(), 28 | 'max' => Chronos::tomorrow()->toDateString(), 29 | ], 30 | [ 31 | 'id' => 'this week', 32 | 'text' => esc_attr__( 'This week', 'fakerpress' ), 33 | 'min' => ( Chronos::today()->dayOfWeek === 1 ? Chronos::today()->toDateString() : Chronos::parse( 'last monday' )->toDateString() ), 34 | 'max' => ( Chronos::today()->dayOfWeek === 0 ? Chronos::today()->toDateString() : Chronos::parse( 'next sunday' )->toDateString() ), 35 | ], 36 | [ 37 | 'id' => 'this month', 38 | 'text' => esc_attr__( 'This month', 'fakerpress' ), 39 | 'min' => Chronos::today()->day( 1 )->toDateString(), 40 | 'max' => Chronos::parse( 'last day of this month' )->toDateString(), 41 | ], 42 | [ 43 | 'id' => 'this year', 44 | 'text' => esc_attr__( 'This year', 'fakerpress' ), 45 | 'min' => Chronos::today()->day( 1 )->month( 1 )->toDateString(), 46 | 'max' => Chronos::parse( 'last day of december' )->toDateString(), 47 | ], 48 | [ 49 | 'id' => 'last 15 days', 50 | 'text' => esc_attr__( 'Last 15 days', 'fakerpress' ), 51 | 'min' => Chronos::today()->subDays( 15 )->toDateString(), 52 | 'max' => Chronos::today()->toDateString(), 53 | ], 54 | [ 55 | 'id' => 'next 15 days', 56 | 'text' => esc_attr__( 'Next 15 Days', 'fakerpress' ), 57 | 'min' => Chronos::today()->toDateString(), 58 | 'max' => Chronos::today()->addDays( 15 )->toDateString(), 59 | ], 60 | ] 61 | ); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/FakerPress/Exceptions/Container_Exception.php: -------------------------------------------------------------------------------- 1 | 30 | */ 31 | protected $types = []; 32 | 33 | /** 34 | * Register all the Admin Views as Singletons and initializes them. 35 | * 36 | * @since 0.6.0 37 | * 38 | * @return void 39 | */ 40 | public function register() { 41 | // Register the provider as a singleton. 42 | $this->container->singleton( static::class, $this ); 43 | 44 | // When fetching all items it will initialize. 45 | $this->get_all_types(); 46 | } 47 | 48 | /** 49 | * Creates field instances from configuration. 50 | * 51 | * @since TBD 52 | * 53 | * @param array|Field_Abstract $fields Configuration array or Field instance. 54 | * 55 | * @return Field_Abstract|\WP_Error|array Array of fields, single field, or WP_Error on invalid config. 56 | */ 57 | public function make( $fields ) { 58 | if ( $fields instanceof Field_Abstract ) { 59 | return ! $fields->is_init() ? $fields->init() : $fields; 60 | } 61 | 62 | if ( ! is_array( $fields ) ) { 63 | return new \WP_Error( 'fakerpress-fields-factory-invalid-config', null, [ 'fields' => $fields ] ); 64 | } 65 | 66 | if ( $this->is_valid_field_config( $fields ) ) { 67 | $field_class = $this->get_field_class_for_type( (string) get( $fields, 'type' ) ); 68 | /** @var Field_Abstract $field */ 69 | $field = make( $field_class ); 70 | 71 | // Now using the class create a new instance and init it with the params. 72 | return $field->init( $fields ); 73 | } 74 | 75 | return array_map( [ $this, 'make' ], $fields ); 76 | } 77 | 78 | /** 79 | * Gets all registered field types. 80 | * 81 | * @since TBD 82 | * 83 | * @return array Array of field types with slug => class mapping. 84 | */ 85 | public function get_all_types(): array { 86 | $default_types = [ 87 | Raw_Field::class, 88 | Fieldset_Field::class, 89 | ]; 90 | 91 | /** 92 | * Allows the filtering of the FakerPress available modules. 93 | * 94 | * @since 0.6.0 95 | * 96 | * @param string[] $views Which modules are available. 97 | */ 98 | $types = apply_filters( 'fakerpress.fields', $default_types ); 99 | 100 | foreach ( $types as $field_type ) { 101 | // Skips all non Field Abstract items. 102 | if ( ! is_subclass_of( $field_type, Field_Abstract::class ) ) { 103 | continue; 104 | } 105 | 106 | $this->container->bind( $field_type, $field_type ); 107 | 108 | $this->types[ $field_type::get_slug() ] = $field_type; 109 | } 110 | 111 | return $this->types; 112 | } 113 | 114 | /** 115 | * Gets the field class name for a given field type. 116 | * 117 | * @since TBD 118 | * 119 | * @param string $type The field type slug. 120 | * 121 | * @return string The field class name. 122 | */ 123 | public function get_field_class_for_type( string $type ): string { 124 | return get( $this->get_all_types(), $type ); 125 | } 126 | 127 | /** 128 | * Validates if a field configuration array is valid. 129 | * 130 | * @since TBD 131 | * 132 | * @param array $field The field configuration array. 133 | * 134 | * @return bool Whether the field configuration is valid. 135 | */ 136 | public function is_valid_field_config( array $field ): bool { 137 | return (bool) $this->get_field_class_for_type( (string) get( $field, 'type' ) ); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/FakerPress/Fields/Field_Abstract.php: -------------------------------------------------------------------------------- 1 | id = $value; 86 | } 87 | 88 | /** 89 | * {@inheritDoc} 90 | */ 91 | public function get_id() { 92 | return $this->id; 93 | } 94 | 95 | /** 96 | * {@inheritDoc} 97 | */ 98 | public function get_html_id( $suffix = null ) { 99 | $ids = []; 100 | $parent = $this; 101 | 102 | // Fetch the ID of all parents 103 | while ( $parent = $parent->get_parent() ) { 104 | $ids[] = $parent->get_id(); 105 | } 106 | 107 | $ids[] = $this->get_id(); 108 | 109 | $plugin = Plugin::$slug; 110 | $type = static::get_slug(); 111 | 112 | $id = "{$plugin}-field-{$type}-" . implode( '-', (array) $ids ); 113 | 114 | if ( $suffix ) { 115 | $id .= '-' . $suffix; 116 | } 117 | 118 | return sanitize_html_class( $id ); 119 | } 120 | 121 | /** 122 | * {@inheritDoc} 123 | */ 124 | public static function get_slug(): string { 125 | return static::$slug; 126 | } 127 | 128 | /** 129 | * {@inheritDoc} 130 | */ 131 | public function get_setting( $index, $default = null ) { 132 | return get( $this->get_settings(), $index, $default ); 133 | } 134 | 135 | /** 136 | * {@inheritDoc} 137 | */ 138 | public function get_settings() { 139 | return $this->settings; 140 | } 141 | 142 | /** 143 | * {@inheritDoc} 144 | */ 145 | public function get_template() { 146 | if ( ! $this->template ) { 147 | $this->template = new Template(); 148 | $this->template 149 | ->set_template_origin( make( Plugin::class ) ) 150 | ->set_template_folder( 'src/templates/fields' ) 151 | ->set_template_context_extract( true ); 152 | } 153 | 154 | return $this->template; 155 | } 156 | 157 | /** 158 | * {@inheritDoc} 159 | */ 160 | public function set_priority( int $value ): void { 161 | $this->priority = $value; 162 | } 163 | 164 | /** 165 | * {@inheritDoc} 166 | */ 167 | public function get_priority(): int { 168 | return $this->priority; 169 | } 170 | 171 | /** 172 | * {@inheritDoc} 173 | */ 174 | public function get_html( $format = 'string', $echo = true ) { 175 | // Globally set in the template vars this instance of field. 176 | $this->get_template()->set( 'field', $this, false ); 177 | 178 | return $this->get_template()->render( static::get_slug(), [ 'field' => $this ], $echo ); 179 | } 180 | 181 | /** 182 | * Generates a random ID for when an ID was not supplied. 183 | * 184 | * @since 0.6.4 185 | * 186 | * @return string 187 | */ 188 | protected function generate_random_id(): string { 189 | return sanitize_html_class( wp_generate_uuid4() ); 190 | } 191 | 192 | /** 193 | * {@inheritDoc} 194 | */ 195 | public function init( array $args = [] ) { 196 | $this->set_id( get( $args, 'id', $this->generate_random_id() ) ); 197 | $this->set_priority( get( $args, 'priority', $this->priority ) ); 198 | $this->add_children( get( $args, 'children', [] ) ); 199 | 200 | $parent = get( $args, 'parent' ); 201 | if ( $parent ) { 202 | $this->set_parent( $parent ); 203 | } 204 | 205 | // Mark that this field was initialized. 206 | $this->set_init_flag( true ); 207 | 208 | return $this; 209 | } 210 | 211 | public function set_init_flag( bool $value ): void { 212 | $this->is_init = $value; 213 | } 214 | 215 | public function is_init(): bool { 216 | return $this->is_init; 217 | } 218 | 219 | /** 220 | * {@inheritDoc} 221 | */ 222 | public function get_children() { 223 | return $this->children; 224 | } 225 | 226 | /** 227 | * {@inheritDoc} 228 | */ 229 | public function find_children( $search, $operator = ' and ' ) { 230 | if ( $search instanceof Field_Interface ) { 231 | $args = [ 232 | 'id' => $search->id, 233 | ]; 234 | } elseif ( is_string( $search ) || is_numeric( $search ) ) { 235 | $args = [ 236 | 'id' => $search, 237 | ]; 238 | } elseif ( is_array( $search ) ) { 239 | $args = $search; 240 | } else { 241 | return []; 242 | } 243 | 244 | $found = wp_filter_object_list( $this->children, $args, $operator, false ); 245 | 246 | if ( empty( $found ) ) { 247 | return []; 248 | } 249 | 250 | return reset( $found ); 251 | } 252 | 253 | /** 254 | * {@inheritDoc} 255 | */ 256 | public function add_children( $children ) { 257 | $children = array_map( static function ( $child ) { 258 | return make( Factory::class )->make( $child ); 259 | }, $children ); 260 | 261 | // Remove non instances of Field_Interface. 262 | $children = array_filter( (array) $children, static function ( $child ) { 263 | return $child instanceof Field_Interface; 264 | } ); 265 | 266 | // Set the parent of all children to the current field. 267 | $children = array_map( function ( $children ) { 268 | return $children->set_parent( $this ); 269 | }, $children ); 270 | 271 | $this->children = array_merge( $this->children, $children ); 272 | 273 | return $this->sort_children(); 274 | } 275 | 276 | /** 277 | * {@inheritDoc} 278 | */ 279 | public function remove_children( $search = [], $operator = ' and ' ) { 280 | $found = $this->find_children( $search, $operator ); 281 | 282 | if ( empty( $found ) ) { 283 | return $this; 284 | } 285 | 286 | $key = array_search( $found, $this->children ); 287 | 288 | if ( isset( $this->children[ $key ] ) ) { 289 | unset( $this->children[ $key ] ); 290 | } 291 | 292 | return $this->sort_children(); 293 | } 294 | 295 | /** 296 | * {@inheritDoc} 297 | */ 298 | public function sort_children() { 299 | usort( $this->children, 'FakerPress\sort_by_priority' ); 300 | 301 | return $this; 302 | } 303 | 304 | /** 305 | * {@inheritDoc} 306 | */ 307 | public function get_parent() { 308 | return $this->parent; 309 | } 310 | 311 | /** 312 | * {@inheritDoc} 313 | */ 314 | public function set_parent( Field_Interface $parent ) { 315 | $this->parent = $parent; 316 | 317 | return $this; 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /src/FakerPress/Fields/Field_Interface.php: -------------------------------------------------------------------------------- 1 | set_raw_html( get( $args, 'html' ) ); 22 | 23 | return $this; 24 | } 25 | 26 | public function set_raw_html( $value ) { 27 | $this->raw_html = $value; 28 | } 29 | 30 | public function get_raw_html() { 31 | return $this->raw_html; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/FakerPress/Hooks.php: -------------------------------------------------------------------------------- 1 | add_actions(); 38 | $this->add_filters(); 39 | } 40 | 41 | /** 42 | * Adds the actions required by each Plugin component. 43 | * 44 | * @since 0.6.0 45 | */ 46 | protected function add_actions() { 47 | add_action( 'fakerpress.plugin_loaded', [ $this, 'load_text_domain' ] ); 48 | add_action( 'fakerpress.plugin_loaded', [ $this, 'load_admin' ] ); 49 | 50 | $admin = make( Admin::class ); 51 | $menu = make( Admin\Menu::class ); 52 | 53 | // From this point on we are doing hooks! 54 | add_action( 'admin_body_class', [ $admin, '_filter_body_class' ] ); 55 | add_action( 'admin_notices', [ $admin, '_action_admin_notices' ] ); 56 | add_action( 'fakerpress.view.request.settings', [ $admin, '_action_setup_settings_page' ] ); 57 | 58 | add_action( 'admin_init', [ $this, 'parse_view_request' ], 15 ); 59 | 60 | // When trying to add a menu, make bigger than the default to avoid conflicting index further on 61 | add_action( 'admin_menu', [ $menu, 'register_menus_to_wp' ], 11 ); 62 | 63 | add_action( 'current_screen', [ $this, 'modify_current_screen' ], 0 ); 64 | } 65 | 66 | /** 67 | * Adds the filters required by each Plugin component. 68 | * 69 | * @since 0.6.0 70 | */ 71 | protected function add_filters() { 72 | $admin = make( Admin::class ); 73 | 74 | // Setup the Submenu using an PHP action based on View 75 | add_filter( 'submenu_file', [ $this, 'filter_admin_submenu_file' ] ); 76 | 77 | // Creating information for the plugin pages footer 78 | add_filter( 'admin_footer_text', [ $admin, '_filter_admin_footer_text' ] ); 79 | add_filter( 'update_footer', [ $admin, '_filter_update_footer' ], 15 ); 80 | 81 | add_filter( 'admin_title', [ $admin, '_filter_set_admin_page_title' ], 15, 2 ); 82 | 83 | add_filter( 'plugin_row_meta', [ $admin, 'filter_plugin_row_meta' ], 10, 2 ); 84 | 85 | // Allow WordPress 86 | add_filter( 'fakerpress.messages.allowed_html', [ $admin, '_filter_messages_allowed_html' ], 1, 1 ); 87 | } 88 | 89 | /** 90 | * Loads the Administration classes. 91 | * 92 | * @since 0.6.0 93 | */ 94 | public function load_admin() { 95 | make( Admin::class ); 96 | make( Ajax::class ); 97 | } 98 | 99 | /** 100 | * Filter the `$submenu_file` global right before WordPress builds the Administration Menu 101 | * 102 | * @since 0.6.0 103 | * 104 | * @param string $submenu_file Which is the current submenu file. 105 | * 106 | * @return string 107 | */ 108 | public function filter_admin_submenu_file( $submenu_file ) { 109 | return make( Admin\Menu::class )->filter_submenu_file( $submenu_file ); 110 | } 111 | 112 | /** 113 | * To allow internationalization for the errors strings the text domain is 114 | * loaded in a 5.2 way, no Fatal Errors, only a message to the user. 115 | * 116 | * @since 0.6.0 117 | * 118 | * @return bool 119 | */ 120 | public function load_text_domain() { 121 | return load_plugin_textdomain( Plugin::$slug, false, Plugin::path( 'languages/' ) ); 122 | } 123 | 124 | /** 125 | * Parses the current view request for the admin views. 126 | * 127 | * @since 0.6.0 128 | * 129 | * @return mixed 130 | */ 131 | public function parse_view_request() { 132 | return make( View_Factory::class )->parse_current_view_request(); 133 | } 134 | 135 | /** 136 | * Sets the current screen on the administration properly for subviews. 137 | * 138 | * @since 0.6.4 139 | * 140 | * @param \WP_Screen $screen 141 | * 142 | */ 143 | public function modify_current_screen( $screen ) { 144 | // Removes itself since it's required to avoid infinitte loop. 145 | remove_action( 'current_screen', [ $this, 'modify_current_screen' ], 0 ); 146 | 147 | make( Menu::class )->correctly_set_current_screen( $screen ); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/FakerPress/Module/Attachment.php: -------------------------------------------------------------------------------- 1 | get_faker()->uuid(), reset( $extension ) ] ); 113 | 114 | $file = [ 115 | 'name' => $filename, 116 | 'tmp_name' => $temporary_file, 117 | ]; 118 | 119 | // uploads as an attachment to WP 120 | $attachment_id = media_handle_sideload( $file, $post_parent_id ); 121 | 122 | // download_url requires deleting the file 123 | if ( file_exists( $temporary_file ) ) { 124 | unlink( $temporary_file ); 125 | } 126 | 127 | /** 128 | * We don't want to pass something to $id 129 | * if there were upload errors. 130 | * So this checks for errors 131 | */ 132 | if ( is_wp_error( $attachment_id ) ) { 133 | if ( file_exists( $temporary_file ) ) { 134 | unlink( $temporary_file ); 135 | } 136 | return $attachment_id; 137 | } 138 | 139 | // Return Attachment ID 140 | return $attachment_id; 141 | } 142 | 143 | /** 144 | * @inheritDoc 145 | */ 146 | public function filter_save_response( $response, array $data, Abstract_Module $module ) { 147 | if ( empty( $data['attachment_url'] ) ) { 148 | return false; 149 | } 150 | 151 | $attachment_id = $this->handle_download( $data['attachment_url'] ); 152 | 153 | // Flag the Object as FakerPress 154 | update_post_meta( $attachment_id, static::get_flag(), 1 ); 155 | 156 | // Add the Original URL to the meta of the attachment 157 | update_post_meta( $attachment_id, static::$meta_key_original_url, $data['attachment_url'] ); 158 | 159 | return $attachment_id; 160 | } 161 | 162 | /** 163 | * Gets an Array with all the providers based on a given Type 164 | * 165 | * @param string $type Which type of provider you are looking for 166 | * 167 | * @return array With ID, Text and Type 168 | */ 169 | public static function get_providers( string $type = 'image' ): array { 170 | $providers = [ 171 | [ 172 | 'id' => Placeholder::ID, 173 | 'text' => esc_attr__( 'Placehold.co', 'fakerpress' ), 174 | 'type' => 'image', 175 | ], 176 | [ 177 | 'id' => LoremPicsum::ID, 178 | 'text' => esc_attr__( 'Lorem Picsum', 'fakerpress' ), 179 | 'type' => 'image', 180 | ], 181 | ]; 182 | 183 | return $providers; 184 | 185 | } 186 | 187 | /** 188 | * @since 0.6.4 189 | * 190 | * @throws \Exception 191 | * 192 | * @param $request 193 | * @param $qty 194 | * 195 | * @return array|string 196 | */ 197 | public function parse_request( $qty, $request = [] ) { 198 | 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /src/FakerPress/Module/Comment.php: -------------------------------------------------------------------------------- 1 | [ 48 | [ 49 | 'key' => static::get_flag(), 50 | 'value' => true, 51 | 'type' => 'BINARY', 52 | ], 53 | ], 54 | ]; 55 | $comments = []; 56 | 57 | $query_comments = new \WP_Comment_Query; 58 | $args = wp_parse_args( $args, $defaults ); 59 | 60 | $query_comments = $query_comments->query( $args ); 61 | 62 | foreach ( $query_comments as $comment ) { 63 | $comments[] = absint( $comment->comment_ID ); 64 | } 65 | 66 | return $comments; 67 | } 68 | 69 | /** 70 | * @inheritDoc 71 | */ 72 | public static function delete( $comment ) { 73 | if ( is_array( $comment ) ) { 74 | $deleted = []; 75 | 76 | foreach ( $comment as $id ) { 77 | $id = $id instanceof \WP_Comment ? $id->comment_ID : $id; 78 | 79 | if ( ! is_numeric( $id ) ) { 80 | continue; 81 | } 82 | 83 | $deleted[ $id ] = static::delete( $id ); 84 | } 85 | 86 | return $deleted; 87 | } 88 | 89 | if ( is_numeric( $comment ) ) { 90 | $comment = \WP_Comment::get_instance( $comment ); 91 | } 92 | 93 | if ( ! $comment instanceof \WP_Comment ) { 94 | return false; 95 | } 96 | 97 | $flag = (bool) get_comment_meta( $comment->comment_ID, static::get_flag(), true ); 98 | 99 | if ( true !== $flag ) { 100 | return false; 101 | } 102 | 103 | return wp_delete_comment( $comment->comment_ID, true ); 104 | } 105 | 106 | /** 107 | * @inheritDoc 108 | */ 109 | public function filter_save_response( $response, array $data, Abstract_Module $module ) { 110 | $comment_id = wp_insert_comment( $data ); 111 | 112 | if ( ! is_numeric( $comment_id ) ) { 113 | return false; 114 | } 115 | 116 | // Flag the Object as FakerPress 117 | update_post_meta( $comment_id, static::get_flag(), 1 ); 118 | 119 | return $comment_id; 120 | } 121 | 122 | public function parse_request( $qty, $request = [] ) { 123 | if ( is_null( $qty ) ) { 124 | $qty = make( Utils::class )->get_qty_from_range( get_request_var( [ Plugin::$slug, 'qty' ] ) ); 125 | } 126 | 127 | if ( 0 === $qty ) { 128 | return esc_attr__( 'Zero is not a good number of comments to fake...', 'fakerpress' ); 129 | } 130 | 131 | $comment_content_size = get( $request, 'content_size', [ 1, 5 ] ); 132 | $comment_content_use_html = is_truthy( get( $request, 'use_html', 'off' ) ); 133 | $comment_content_html_tags = array_map( 'trim', explode( ',', get( $request, 'html_tags' ) ) ); 134 | $comment_type = array_map( 'trim', explode( ',', get( $request, 'type' ) ) ); 135 | $post_types = array_map( 'trim', explode( ',', get( $request, 'post_types' ) ) ); 136 | 137 | $min_date = get( $request, [ 'interval_date', 'min' ] ); 138 | $max_date = get( $request, [ 'interval_date', 'max' ] ); 139 | $metas = get( $request, 'meta', [] ); 140 | 141 | $results = []; 142 | 143 | for ( $i = 0; $i < $qty; $i ++ ) { 144 | $this->set( 'comment_date', $min_date, $max_date ); 145 | $this->set( 146 | 'comment_content', 147 | $comment_content_use_html, 148 | [ 149 | 'qty' => $comment_content_size, 150 | 'elements' => $comment_content_html_tags, 151 | ] 152 | ); 153 | $this->set( 'user_id', 0 ); 154 | $this->set( 'comment_type', $comment_type ); 155 | 156 | $this->set( 'comment_author' ); 157 | $this->set( 'comment_parent' ); 158 | $this->set( 'comment_author_IP' ); 159 | $this->set( 'comment_agent' ); 160 | $this->set( 'comment_approved' ); 161 | $this->set( 'comment_post_ID', null, [ 'post_type' => $post_types ] ); 162 | $this->set( 'comment_author_email' ); 163 | $this->set( 'comment_author_url' ); 164 | 165 | $comment_id = $this->generate()->save(); 166 | 167 | if ( $comment_id && is_numeric( $comment_id ) ) { 168 | foreach ( $metas as $meta_index => $meta ) { 169 | if ( ! isset( $meta['type'], $meta['name'] ) ) { 170 | continue; 171 | } 172 | 173 | $type = get( $meta, 'type' ); 174 | $name = get( $meta, 'name' ); 175 | unset( $meta['type'], $meta['name'] ); 176 | 177 | if ( isset( $meta['weight'] ) ) { 178 | $meta['weight'] = absint( $meta['weight'] ); 179 | $meta['weight'] = $meta['weight'] > 0 ? $meta['weight'] : 100; 180 | } else { 181 | $meta['weight'] = 100; 182 | } 183 | 184 | make( Meta::class )->object( $comment_id, 'comment' )->with( $type, $name, $meta )->generate()->save(); 185 | } 186 | } 187 | $results[] = $comment_id; 188 | } 189 | $results = array_filter( $results, 'absint' ); 190 | 191 | return $results; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/FakerPress/Module/Factory.php: -------------------------------------------------------------------------------- 1 | views ) ) { 33 | $modules_classes = [ 34 | Attachment::class, 35 | Comment::class, 36 | Meta::class, 37 | Post::class, 38 | Term::class, 39 | User::class, 40 | ]; 41 | 42 | foreach ( $modules_classes as $module_class ) { 43 | $this->container->singleton( $module_class, $module_class, [ 'hook' ] ); 44 | $this->modules[] = $this->container->make( $module_class ); 45 | } 46 | } 47 | 48 | /** 49 | * Allows the filtering of the FakerPress available modules. 50 | * 51 | * @since 0.6.0 52 | * 53 | * @param Abstract_Module[] $modules Which modules are available. 54 | */ 55 | return apply_filters( 'fakerpress.modules', $this->modules ); 56 | } 57 | 58 | /** 59 | * Gets a specific module based on its slug. 60 | * 61 | * @since 0.6.0 62 | * 63 | * @param string $slug Which module we are looking for. 64 | * 65 | * @return Abstract_Module|null 66 | */ 67 | public function get( string $slug ) { 68 | $views = array_filter( $this->get_all(), static function( $module ) use ( $slug ) { 69 | return $module::get_slug() === $slug; 70 | } ); 71 | 72 | if ( empty( $views ) ) { 73 | return null; 74 | } 75 | 76 | return reset( $views ); 77 | } 78 | 79 | /** 80 | * Register all the Modules as Singletons and initializes them. 81 | * 82 | * @since 0.6.0 83 | */ 84 | public function register() { 85 | // Register the provider as a singleton. 86 | $this->container->singleton( static::class, $this ); 87 | 88 | // Initializes all modules. 89 | $this->get_all(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/FakerPress/Module/Interface_Module.php: -------------------------------------------------------------------------------- 1 | insert_id or bool for the state 101 | */ 102 | public function save( bool $reset = true ); 103 | 104 | /** 105 | * Use this method to delete a given item from this Module. 106 | * 107 | * @since 0.6.0 108 | * 109 | * @param int|\WP_Post|string $item What are we deleting 110 | * 111 | * @return bool|\WP_Error 112 | */ 113 | public static function delete( $item ); 114 | 115 | /** 116 | * Use this method to fetch all items created from a given module. 117 | * 118 | * @since 0.6.0 119 | * 120 | * @param array $args Overwrite the default arguments used to fetch the items. 121 | * 122 | * @return bool|\WP_Error 123 | */ 124 | public static function fetch( array $args = [] ): array; 125 | 126 | /** 127 | * Resets all the data on this module. 128 | * 129 | * @since 0.6.0 130 | * 131 | * @return self 132 | */ 133 | public function reset(): Interface_Module; 134 | 135 | /** 136 | * Use this method to generate all the needed data. 137 | * 138 | * @since 0.6.0 139 | * @since 0.6.2 Added the $force parameter. 140 | * 141 | * @param bool $force Whether to force the regeneration of the data. 142 | * 143 | * @return self 144 | */ 145 | public function generate( bool $force = false ): Interface_Module; 146 | 147 | /** 148 | * A method to make it easier to debug which variables will be actually saved. 149 | * 150 | * @param 0.6.0 151 | * 152 | * @return array 153 | */ 154 | public function get_values(): array; 155 | 156 | /** 157 | * A method to get the data for a given key. 158 | * 159 | * @param string $key 160 | * 161 | * @return array|null 162 | */ 163 | public function get( string $key ): ?object; 164 | 165 | /** 166 | * A method to get the value for a given key. 167 | * 168 | * @param string $key 169 | * 170 | * @return mixed 171 | */ 172 | public function get_value( string $key ); 173 | 174 | /** 175 | * Determines if a value is set for a given key. 176 | * 177 | * @param string $key 178 | * 179 | * @return bool 180 | */ 181 | public function has_value( string $key ): bool; 182 | } 183 | -------------------------------------------------------------------------------- /src/FakerPress/Module/Meta.php: -------------------------------------------------------------------------------- 1 | object_id = 0; 83 | 84 | return $this; 85 | } 86 | 87 | /** 88 | * Configure which Object we will save Meta to 89 | * 90 | * @since 0.3.0 91 | * 92 | * @return self 93 | */ 94 | public function object( $id = 0, $name = 'post' ): Interface_Module { 95 | $this->object_id = $id; 96 | $this->object_name = $name; 97 | 98 | return $this; 99 | } 100 | 101 | public function with( string $type, string $name, $args ): Interface_Module { 102 | $this->data['meta_key'] = null; 103 | $this->data['meta_value'] = null; 104 | 105 | if ( empty( $type ) ) { 106 | return $this; 107 | } 108 | 109 | if ( empty( $name ) ) { 110 | return $this; 111 | } 112 | 113 | $this->data['meta_type'] = $type; 114 | $this->data['meta_key'] = $name; 115 | $this->data['meta_args'] = array_values( $args ); 116 | 117 | $faker = $this->get_faker(); 118 | 119 | // Pass which object we are dealing with. 120 | $faker->set_meta_object( $this->object_name, $this->object_id ); 121 | 122 | return $this; 123 | } 124 | 125 | /** 126 | * @inheritDoc 127 | */ 128 | public function generate( bool $force = false ): Interface_Module { 129 | // Only regenerate if there is no data, or we are forcing it. 130 | if ( isset( $this->data['meta_value'] ) && ! $force ) { 131 | return $this; 132 | } 133 | 134 | // Failed generation because we have no type. 135 | if ( ! isset( $this->data['meta_type'] ) ) { 136 | return $this; 137 | } 138 | 139 | $type = $this->data['meta_type']; 140 | $args = $this->data['meta_args'] ?? []; 141 | 142 | $faker = $this->get_faker(); 143 | 144 | if ( is_callable( [ $faker, 'meta_type_' . $type ] ) ) { 145 | $this->data['meta_value'] = call_user_func_array( [ $faker, 'meta_type_' . $type ], $args ); 146 | } elseif ( count( $args ) === 1 ) { 147 | $this->data['meta_value'] = reset( $args ); 148 | } 149 | 150 | /** 151 | * Allow filtering for the value for a Meta 152 | * 153 | * @since 0.4.8 154 | * 155 | * @param mixed $meta_value The Meta value that will be filtered 156 | * @param string $meta_key Which meta key we are currently filtering for 157 | * @param string $meta_type Which type of Meta we are dealing with 158 | * @param self $module An instance of the Meta Module 159 | */ 160 | $this->data['meta_value'] = apply_filters( "fakerpress.module.meta.value", $this->data['meta_value'], $this->data['meta_key'], $type, $this ); 161 | 162 | /** 163 | * Allow filtering for the Value of a specific meta value based on it's key 164 | * 165 | * @since 0.4.8 166 | * 167 | * @param mixed $meta_value The Meta value that will be filtered 168 | * @param string $meta_type Which type of Meta we are dealing with 169 | * @param self $module An instance of the Meta Module 170 | */ 171 | $this->data['meta_value'] = apply_filters( "fakerpress.module.meta.{$this->data['meta_key']}.value", $this->data['meta_value'], $type, $this ); 172 | 173 | return $this; 174 | } 175 | 176 | /** 177 | * @inheritDoc 178 | */ 179 | public function filter_save_response( $response, array $data, Abstract_Module $module ) { 180 | if ( ! isset( $data['meta_value'] ) ) { 181 | return false; 182 | } 183 | 184 | if ( empty( $data['meta_key'] ) ) { 185 | return false; 186 | } 187 | 188 | return update_metadata( $this->object_name, $this->object_id, $data['meta_key'], $data['meta_value'] ); 189 | } 190 | 191 | /** 192 | * @inheritDoc 193 | */ 194 | public static function fetch( array $args = [] ): array { 195 | // TODO: Implement fetch() method. 196 | } 197 | 198 | /** 199 | * @inheritDoc 200 | */ 201 | public static function delete( $item ) { 202 | // TODO: Implement delete() method. 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/FakerPress/Module/Post.php: -------------------------------------------------------------------------------- 1 | 'any', 49 | 'post_status' => 'any', 50 | 'nopaging' => true, 51 | 'posts_per_page' => - 1, 52 | 'fields' => 'ids', 53 | 'meta_query' => [ 54 | [ 55 | 'key' => static::get_flag(), 56 | 'value' => true, 57 | 'type' => 'BINARY', 58 | ], 59 | ], 60 | ]; 61 | 62 | $args = wp_parse_args( $args, $defaults ); 63 | $query_posts = new \WP_Query( $args ); 64 | 65 | return array_map( 'absint', $query_posts->posts ); 66 | } 67 | 68 | /** 69 | * @inheritDoc 70 | */ 71 | public static function delete( $item ) { 72 | if ( is_array( $item ) ) { 73 | $deleted = []; 74 | 75 | foreach ( $item as $id ) { 76 | $id = $id instanceof \WP_Post ? $id->ID : $id; 77 | 78 | if ( ! is_numeric( $id ) ) { 79 | continue; 80 | } 81 | 82 | $deleted[ $id ] = static::delete( $id ); 83 | } 84 | 85 | return $deleted; 86 | } 87 | 88 | if ( is_numeric( $item ) ) { 89 | $item = \WP_Post::get_instance( $item ); 90 | } 91 | 92 | if ( ! $item instanceof \WP_Post ) { 93 | return false; 94 | } 95 | 96 | $flag = (bool) get_post_meta( $item->ID, static::get_flag(), true ); 97 | 98 | if ( true !== $flag ) { 99 | return false; 100 | } 101 | 102 | return wp_delete_post( $item->ID, true ); 103 | } 104 | 105 | /** 106 | * @inheritDoc 107 | */ 108 | public function filter_save_response( $response, array $data, Abstract_Module $module ) { 109 | $post_id = wp_insert_post( $data ); 110 | 111 | if ( ! is_numeric( $post_id ) ) { 112 | return false; 113 | } 114 | 115 | // Flag the Object as FakerPress 116 | update_post_meta( $post_id, static::get_flag(), 1 ); 117 | 118 | return $post_id; 119 | } 120 | 121 | /** 122 | * @since 0.6.4 123 | * 124 | * @throws \Exception 125 | * 126 | * @param $request 127 | * @param $qty 128 | * 129 | * @return array|string 130 | */ 131 | public function parse_request( $qty, $request = [] ) { 132 | if ( is_null( $qty ) ) { 133 | $qty = get_request_var( [ Plugin::$slug, 'qty' ] ); 134 | $min = absint( $qty['min'] ); 135 | $max = max( absint( isset( $qty['max'] ) ? $qty['max'] : 0 ), $min ); 136 | $qty = $this->get_faker()->numberBetween( $min, $max ); 137 | } 138 | 139 | if ( 0 === $qty ) { 140 | return esc_attr__( 'Zero is not a good number of posts to fake...', 'fakerpress' ); 141 | } 142 | 143 | // Fetch Comment Status 144 | $comment_status = get( $request, 'comment_status' ); 145 | $comment_status = array_map( 'trim', explode( ',', $comment_status ) ); 146 | 147 | // Fetch Post Author 148 | $post_author = get( $request, 'author' ); 149 | $post_author = array_map( 'trim', explode( ',', $post_author ) ); 150 | $post_author = array_intersect( get_users( [ 'fields' => 'ID' ] ), $post_author ); 151 | 152 | // Fetch the dates 153 | $date = [ 154 | get( $request, [ 'interval_date', 'min' ] ), 155 | get( $request, [ 'interval_date', 'max' ] ), 156 | ]; 157 | 158 | // Fetch Post Types 159 | $post_types = get( $request, 'post_types' ); 160 | $post_types = array_map( 'trim', explode( ',', $post_types ) ); 161 | $post_types = array_intersect( get_post_types( [ 'public' => true ] ), $post_types ); 162 | 163 | // Fetch Post Content 164 | $post_content_size = get( $request, 'content_size', [ 5, 15 ] ); 165 | $post_content_use_html = ( (int) get( $request, 'use_html', 0 ) ) === 1; 166 | $post_content_html_tags = array_map( 'trim', explode( ',', get( $request, 'html_tags' ) ) ); 167 | 168 | // Fetch Post Excerpt. 169 | $post_excerpt_size = get( $request, 'excerpt_size', [ 1, 3 ] ); 170 | 171 | // Fetch and clean Post Parents 172 | $post_parents = get( $request, 'post_parent' ); 173 | $post_parents = array_map( 'trim', explode( ',', $post_parents ) ); 174 | 175 | $images_origin = array_map( 'trim', explode( ',', get( $request, 'images_origin' ) ) ); 176 | 177 | // Fetch Taxonomies 178 | $taxonomies_configuration = get( $request, 'taxonomy' ); 179 | 180 | // Fetch Metas It will be parsed later! 181 | $metas = get( $request, 'meta', [] ); 182 | 183 | $results = []; 184 | 185 | for ( $i = 0; $i < $qty; $i ++ ) { 186 | $this->set( 'post_title' ); 187 | $this->set( 'post_status', 'publish' ); 188 | $this->set( 'post_date', $date ); 189 | $this->set( 'post_parent', $post_parents ); 190 | $this->set( 191 | 'post_content', 192 | $post_content_use_html, 193 | [ 194 | 'qty' => $post_content_size, 195 | 'elements' => $post_content_html_tags, 196 | 'sources' => $images_origin, 197 | ] 198 | ); 199 | $this->set( 'post_excerpt', $post_excerpt_size ); 200 | $this->set( 'post_author', $post_author ); 201 | $this->set( 'post_type', $post_types ); 202 | $this->set( 'comment_status', $comment_status ); 203 | $this->set( 'ping_status' ); 204 | $this->set( 'tax_input', $taxonomies_configuration ); 205 | 206 | $generated = $this->generate(); 207 | $post_id = $generated->save(); 208 | 209 | if ( $post_id && is_numeric( $post_id ) ) { 210 | foreach ( $metas as $meta_index => $meta ) { 211 | if ( ! isset( $meta['type'], $meta['name'] ) ) { 212 | continue; 213 | } 214 | 215 | $type = get( $meta, 'type' ); 216 | $name = get( $meta, 'name' ); 217 | unset( $meta['type'], $meta['name'] ); 218 | 219 | if ( isset( $meta['weight'] ) ) { 220 | $meta['weight'] = absint( $meta['weight'] ); 221 | $meta['weight'] = $meta['weight'] > 0 ? $meta['weight'] : 100; 222 | } else { 223 | $meta['weight'] = 100; 224 | } 225 | 226 | make( Meta::class )->object( $post_id )->with( $type, $name, $meta )->generate()->save(); 227 | } 228 | } 229 | 230 | $results[] = $post_id; 231 | } 232 | 233 | $results = array_filter( (array) $results, 'absint' ); 234 | 235 | return $results; 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /src/FakerPress/Module/Term.php: -------------------------------------------------------------------------------- 1 | $terms ){ 55 | $deleted[ $taxonomy ] = []; 56 | 57 | foreach ( $terms as $term ){ 58 | $deleted[ $taxonomy ][ $term ] = wp_delete_term( $term, $taxonomy ); 59 | } 60 | } 61 | 62 | delete_option( 'fakerpress.module_flag.term' ); 63 | 64 | return $deleted; 65 | } 66 | 67 | /** 68 | * @inheritDoc 69 | */ 70 | public function filter_save_response( $response, array $data, Abstract_Module $module ) { 71 | $args = [ 72 | 'description' => $data['description'], 73 | 'parent' => $data['parent_term'], 74 | ]; 75 | 76 | $term_object = wp_insert_term( $data['name'], $data['taxonomy'], $args ); 77 | if ( is_wp_error( $term_object ) ) { 78 | return false; 79 | } 80 | 81 | $flagged = get_option( 'fakerpress.module_flag.' . $this::get_slug(), [] ); 82 | 83 | // Ensure that this option is an Array by resetting the variable. 84 | if ( ! is_array( $flagged ) ){ 85 | $flagged = []; 86 | } 87 | 88 | if ( ! isset( $flagged[ $data['taxonomy'] ] ) || ! is_array( $flagged[ $data['taxonomy'] ] ) ){ 89 | $flagged[ $data['taxonomy'] ] = []; 90 | } 91 | $flagged[ $data['taxonomy'] ] = array_merge( $flagged[ $data['taxonomy'] ], (array) $term_object['term_id'] ); 92 | 93 | // When in posts relating is harder so we store in the Options Table 94 | update_option( 'fakerpress.module_flag.' . $this::get_slug(), $flagged ); 95 | 96 | return $term_object['term_id']; 97 | } 98 | 99 | public function parse_request( $qty, $request = [] ) { 100 | if ( is_null( $qty ) ) { 101 | $qty = make( Utils::class )->get_qty_from_range( get_request_var( [ Plugin::$slug, 'qty' ] ) ); 102 | } 103 | 104 | if ( 0 === $qty ){ 105 | return esc_attr__( 'Zero is not a good number of terms to fake...', 'fakerpress' ); 106 | } 107 | 108 | $name_size = get_request_var( [ Plugin::$slug, 'size' ] ); 109 | 110 | // Fetch taxonomies 111 | $taxonomies = get( $request, 'taxonomies' ); 112 | $taxonomies = array_map( 'trim', explode( ',', $taxonomies ) ); 113 | $taxonomies = array_intersect( get_taxonomies( [ 'public' => true ] ), $taxonomies ); 114 | 115 | // Only has meta after 4.4-beta 116 | $has_metas = version_compare( $GLOBALS['wp_version'], '4.4-beta', '>=' ); 117 | 118 | if ( $has_metas ) { 119 | $metas = get( $request, 'meta' ); 120 | } 121 | 122 | for ( $i = 0; $i < $qty; $i++ ) { 123 | $this->set( 'taxonomy', $taxonomies ); 124 | $this->set( 'name', $name_size ); 125 | $this->set( 'description' ); 126 | $this->set( 'parent_term' ); 127 | 128 | $term_id = $this->generate()->save(); 129 | 130 | if ( $has_metas && $term_id && is_numeric( $term_id ) ){ 131 | foreach ( $metas as $meta_index => $meta ) { 132 | if ( ! isset( $meta['type'], $meta['name'] ) ) { 133 | continue; 134 | } 135 | 136 | $type = get( $meta, 'type' ); 137 | $name = get( $meta, 'name' ); 138 | unset( $meta['type'], $meta['name'] ); 139 | 140 | if ( isset( $meta['weight'] ) ) { 141 | $meta['weight'] = absint( $meta['weight'] ); 142 | $meta['weight'] = $meta['weight'] > 0 ? $meta['weight'] : 100; 143 | } else { 144 | $meta['weight'] = 100; 145 | } 146 | 147 | make( Meta::class )->object( $term_id, 'term' )->with( $type, $name, $meta )->generate()->save(); 148 | } 149 | } 150 | 151 | $results[] = $term_id; 152 | } 153 | 154 | $results = array_filter( (array) $results, 'absint' ); 155 | 156 | return $results; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/FakerPress/Module/User.php: -------------------------------------------------------------------------------- 1 | 'ID', 48 | 'meta_query' => [ 49 | [ 50 | 'key' => static::get_flag(), 51 | 'value' => true, 52 | 'type' => 'BINARY', 53 | ], 54 | ], 55 | ]; 56 | $args = wp_parse_args( $args, $defaults ); 57 | 58 | $query_users = new \WP_User_Query( $args ); 59 | 60 | return array_map( 'absint', $query_users->results ); 61 | } 62 | 63 | /** 64 | * @inheritDoc 65 | */ 66 | public static function delete( $user ) { 67 | if ( is_array( $user ) ) { 68 | $deleted = []; 69 | 70 | foreach ( $user as $id ) { 71 | $id = $id instanceof \WP_User ? $id->ID : $id; 72 | 73 | if ( ! is_numeric( $id ) ) { 74 | continue; 75 | } 76 | 77 | $deleted[ $id ] = self::delete( $id ); 78 | } 79 | 80 | return $deleted; 81 | } 82 | 83 | if ( is_numeric( $user ) ) { 84 | $user = new \WP_User( $user ); 85 | } 86 | 87 | if ( ! $user instanceof \WP_User || ! $user->exists() ) { 88 | return false; 89 | } 90 | 91 | $flag = (bool) get_user_meta( $user->ID, static::get_flag(), true ); 92 | 93 | if ( true !== $flag ) { 94 | return false; 95 | } 96 | 97 | return wp_delete_user( $user->ID, get_current_user_id() ); 98 | } 99 | 100 | /** 101 | * @inheritDoc 102 | */ 103 | public function filter_save_response( $response, array $data, Abstract_Module $module ) { 104 | $user_id = wp_insert_user( $data ); 105 | 106 | if ( ! is_numeric( $user_id ) ) { 107 | return false; 108 | } 109 | 110 | // Only set role if needed 111 | if ( ! is_null( $data['role'] ) ) { 112 | $user = new \WP_User( $user_id ); 113 | 114 | // Here we could add in the future the possibility to set multiple roles at once 115 | $user->set_role( $data['role'] ); 116 | } 117 | 118 | // Flag the Object as FakerPress 119 | update_user_meta( $user_id, static::get_flag(), 1 ); 120 | 121 | return $user_id; 122 | } 123 | 124 | /** 125 | * @inheritDoc 126 | */ 127 | public function parse_request( $qty, $request = [] ) { 128 | if ( is_null( $qty ) ) { 129 | $qty = get_request_var( [ Plugin::$slug, 'qty' ] ); 130 | $min = absint( $qty['min'] ); 131 | $max = max( absint( isset( $qty['max'] ) ? $qty['max'] : 0 ), $min ); 132 | $qty = $this->get_faker()->numberBetween( $min, $max ); 133 | } 134 | 135 | if ( 0 === $qty ) { 136 | return esc_attr__( 'Zero is not a good number of users to fake...', 'fakerpress' ); 137 | } 138 | 139 | $description_size = get( $request, 'description_size', [ 1, 5 ] ); 140 | $description_use_html = get( $request, 'use_html', 'off' ) === 'on'; 141 | $description_html_tags = array_map( 'trim', explode( ',', get( $request, 'html_tags' ) ) ); 142 | 143 | $roles = array_intersect( array_keys( get_editable_roles() ), array_map( 'trim', explode( ',', get( $request, 'roles' ) ) ) ); 144 | $metas = get( $request, 'meta', [] ); 145 | 146 | $results = []; 147 | 148 | for ( $i = 0; $i < $qty; $i ++ ) { 149 | $this->set( 'role', $roles ); 150 | $this->set( 151 | 'description', 152 | $description_use_html, 153 | [ 154 | 'qty' => $description_size, 155 | 'elements' => $description_html_tags, 156 | ] 157 | ); 158 | $this->set( 'user_registered', 'yesterday', 'now' ); 159 | 160 | $this->set( [ 161 | 'first_name', 162 | 'last_name', 163 | 'user_pass', 164 | 'user_url', 165 | ] ); 166 | 167 | $this->generate(); 168 | 169 | $username_from_generated_first_last = strtolower( implode( '.', [ $this->get_value( 'first_name' ), $this->get_value( 'last_name' ) ] ) ); 170 | 171 | $this->set( 'user_login', $username_from_generated_first_last ); 172 | $this->set( 'user_nicename', $username_from_generated_first_last ); 173 | $this->set( 'user_email', $username_from_generated_first_last . '@' . FakerPress\ThirdParty\Faker\Provider\Internet::safeEmailDomain() ); 174 | $this->set( 'display_name', $this->get_value( 'first_name' ) ); 175 | $this->set( 'nickname', $username_from_generated_first_last ); 176 | 177 | $user_id = $this->generate()->save(); 178 | 179 | if ( $user_id && is_numeric( $user_id ) ) { 180 | foreach ( $metas as $meta_index => $meta ) { 181 | if ( ! isset( $meta['type'], $meta['name'] ) ) { 182 | continue; 183 | } 184 | 185 | $type = get( $meta, 'type' ); 186 | $name = get( $meta, 'name' ); 187 | unset( $meta['type'], $meta['name'] ); 188 | 189 | if ( isset( $meta['weight'] ) ) { 190 | $meta['weight'] = absint( $meta['weight'] ); 191 | $meta['weight'] = $meta['weight'] > 0 ? $meta['weight'] : 100; 192 | } else { 193 | $meta['weight'] = 100; 194 | } 195 | 196 | make( Meta::class )->object( $user_id, 'user' )->with( $type, $name, $meta )->generate()->save(); 197 | } 198 | } 199 | $results[] = $user_id; 200 | } 201 | $results = array_filter( $results, 'absint' ); 202 | 203 | return $results; 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/FakerPress/Plugin.php: -------------------------------------------------------------------------------- 1 | register(); 113 | 114 | return $plugin; 115 | } 116 | 117 | /** 118 | * Plugin constructor. 119 | * 120 | * This is intentionally empty and protected to prevent direct instantiation, please use the `boot` method. 121 | * 122 | * @since 0.6.2 123 | */ 124 | protected function __construct() { 125 | // Intentionally empty. 126 | } 127 | 128 | /** 129 | * Registers the plugin. 130 | * 131 | * Do not attempt to interact with FakerPress before this method is called. 132 | * 133 | * @since 0.6.2 134 | */ 135 | protected function register(): void { 136 | $this->plugin_path = trailingslashit( dirname( static::$_file ) ); 137 | $this->plugin_dir = trailingslashit( basename( $this->plugin_path ) ); 138 | $this->plugin_url = plugins_url( $this->plugin_dir, $this->plugin_path ); 139 | 140 | $this->autoload(); 141 | 142 | // Register this as a singleton on the container. 143 | singleton( static::class, $this ); 144 | 145 | $this->bind_implementations(); 146 | 147 | /** 148 | * Triggers an action for loading of functionality. 149 | * 150 | * @since 0.6.0 151 | */ 152 | do_action( 'fakerpress.plugin_loaded' ); 153 | } 154 | 155 | /** 156 | * Autoload the classes for the plugin via Composer. 157 | * 158 | * @since 0.6.2 159 | * 160 | * @return void 161 | */ 162 | protected function autoload(): void { 163 | // Load Composer Vendor Modules 164 | require_once $this->plugin_path . 'vendor-prefixed' . DIRECTORY_SEPARATOR . 'autoload.php'; 165 | } 166 | 167 | /** 168 | * Register the implementations of the plugin with the container. 169 | * 170 | * @since 0.6.2 171 | */ 172 | protected function bind_implementations(): void { 173 | singleton( Admin::class, Admin::class ); 174 | singleton( Admin\Menu::class, Admin\Menu::class ); 175 | singleton( Ajax::class, Ajax::class ); 176 | singleton( Utils\Assets::class, Utils\Assets::class ); 177 | singleton( Utils::class, Utils::class ); 178 | 179 | // Register all the Service Providers. 180 | register( Assets::class ); 181 | register( Hooks::class ); 182 | 183 | register( Module\Factory::class ); 184 | register( Admin\View\Factory::class ); 185 | register( Fields\Factory::class ); 186 | } 187 | 188 | /** 189 | * Return a Path relative to the plugin root 190 | * 191 | * @since 0.1.0 192 | * 193 | * @uses plugin_dir_path 194 | * 195 | * @param string $append A string to be appended to the root path 196 | * 197 | * @return string The path after being appended by the variable 198 | */ 199 | public static function path( string $append = '' ): string { 200 | return (string) make( static::class )->plugin_path . str_replace( '/', DIRECTORY_SEPARATOR, $append ); 201 | } 202 | 203 | /** 204 | * Return a URL relative to the plugin root 205 | * 206 | * @since 0.1.0 207 | * @uses plugins_url 208 | * 209 | * @param string $file A string to be appended to the root url 210 | * 211 | * @return string The url to the file 212 | */ 213 | public static function url( string $file = '' ): string { 214 | return (string) make( static::class )->plugin_url . $file; 215 | } 216 | 217 | /** 218 | * Return a URL relative to the plugin's administration page. 219 | * 220 | * @since 0.1.0 221 | * 222 | * @uses admin_url 223 | * @uses wp_parse_args 224 | * @uses add_query_arg 225 | * 226 | * @param string|array $args Arguments for the admin URL 227 | * @param string $hash Hash for the admin URL 228 | * 229 | * @return string The url to the file 230 | */ 231 | public static function admin_url( $args = '', $hash = false ): string { 232 | /** 233 | * Define the array of defaults 234 | */ 235 | $defaults = [ 236 | 'page' => static::$slug, 237 | ]; 238 | 239 | /** 240 | * Parse incoming $args into an array and merge it with $defaults 241 | */ 242 | $args = wp_parse_args( $args, $defaults ); 243 | 244 | return add_query_arg( $args, admin_url( 'admin.php' ) ) . ( $hash !== false ? "#{$hash}" : '' ); 245 | } 246 | 247 | /** 248 | * Returns a URL for the external project website 249 | * 250 | * @since 0.3.2 251 | * @uses esc_url_raw 252 | * 253 | * @param string $path Hash for the admin URL 254 | * 255 | * @return string The url the external website with the appended $path 256 | */ 257 | public static function ext_site_url( string $path = '/' ): string { 258 | return esc_url_raw( static::$_ext_domain . ( ! empty( $path ) ? $path : '/' ), [ 'http', 'https' ] ); 259 | } 260 | 261 | public static function get( $name, $default = false ) { 262 | $options = static::all(); 263 | $value = get( $options, $name, $default ); 264 | 265 | return $value; 266 | } 267 | 268 | public static function update( $name = null, $value = false ) { 269 | $options = static::all(); 270 | $opts = []; 271 | 272 | foreach ( (array) $name as $k => $index ) { 273 | if ( 0 === $k ) { 274 | $opts[ - 1 ] = &$options; 275 | } 276 | 277 | if ( count( $name ) - 1 !== $k && ! isset( $opts[ $k - 1 ][ $index ] ) ) { 278 | $opts[ $k - 1 ][ $index ] = []; 279 | } 280 | 281 | if ( isset( $opts[ $k - 1 ][ $index ] ) ) { 282 | $opts[ $k ] = &$opts[ $k - 1 ][ $index ]; 283 | } else { 284 | $opts[ $k - 1 ][ $index ] = $value; 285 | } 286 | } 287 | $opts[ $k ] = $value; 288 | 289 | return update_option( static::$slug . '-plugin-options', $options ); 290 | } 291 | 292 | public static function remove( $name = null ) { 293 | // @TODO 294 | } 295 | 296 | public static function all() { 297 | $defaults = []; 298 | 299 | return get_option( static::$slug . '-plugin-options', $defaults ); 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /src/FakerPress/Provider/Image/LoremPicsum.php: -------------------------------------------------------------------------------- 1 | generator, 'numberBetween' ], $width ); 30 | } 31 | 32 | // Makes sure we have an Int 33 | $width = absint( $width ); 34 | 35 | // Check For float (ratio) 36 | if ( is_float( $height ) ) { 37 | $height = floor( $width / floatval( $height ) ); 38 | } elseif ( is_array( $height ) ) { 39 | $height = call_user_func_array( [ $this->generator, 'numberBetween' ], $height ); 40 | } 41 | 42 | // https://picsum.photos/200/640/?random 43 | $url = "https://picsum.photos/{$width}/{$height}/?random"; 44 | 45 | return $url; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/FakerPress/Provider/Image/Placeholder.php: -------------------------------------------------------------------------------- 1 | generator, 'numberBetween' ], $width ); 29 | } 30 | 31 | // Makes sure we have an Int 32 | $width = absint( $width ); 33 | 34 | // Check For float (ratio) 35 | if ( is_float( $height ) ) { 36 | $height = floor( $width / floatval( $height ) ); 37 | } elseif ( is_array( $height ) ) { 38 | $height = call_user_func_array( [ $this->generator, 'numberBetween' ], $height ); 39 | } 40 | 41 | $url = "https://placehold.co/{$width}x{$height}/"; 42 | 43 | return $url; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/FakerPress/Provider/Text/Base.php: -------------------------------------------------------------------------------- 1 | [ 'closed', 'open' ], 17 | 'comment_status' => [ 'closed', 'open' ], 18 | ]; 19 | 20 | /** 21 | * Hold the default width and height for the diff providers. 22 | * 23 | * @since 0.1.0 24 | * @since 0.5.0 now it's a public static var. 25 | * 26 | * @var array 27 | */ 28 | public static $type_defaults = [ 29 | Placeholder::ID => [ 30 | 'width' => [ 200, 640 ], 31 | 'height' => 1.25, 32 | ], 33 | LoremPicsum::ID => [ 34 | 'width' => [ 1024, 1440 ], 35 | 'height' => 1.5, 36 | ], 37 | ]; 38 | 39 | public function attachment_url( $type = LoremPicsum::ID, $args = [] ) { 40 | $url = ''; 41 | 42 | // Check if defaults exists 43 | if ( ! isset( self::$type_defaults[ $type ] ) ) { 44 | return $url; 45 | } 46 | 47 | $args = wp_parse_args( $args, static::$type_defaults[ $type ] ); 48 | 49 | if ( Placeholder::ID === $type ) { 50 | $url = call_user_func_array( [ $this->generator, Placeholder::ID ], (array) $args ); 51 | } elseif ( LoremPicsum::ID === $type ) { 52 | $url = call_user_func_array( [ $this->generator, LoremPicsum::ID ], (array) $args ); 53 | } 54 | 55 | return $url; 56 | } 57 | 58 | public function post_title( $qty_words = 5 ) { 59 | $title = $this->generator->sentence( $qty_words ); 60 | $title = substr( $title, 0, strlen( $title ) - 1 ); 61 | 62 | return $title; 63 | } 64 | 65 | public function post_content( $html = true, $args = [] ) { 66 | if ( true === $html ) { 67 | $content = implode( "\n", $this->generator->html_elements( $args ) ); 68 | } else { 69 | $content = implode( "\r\n\r\n", $this->generator->paragraphs( $this->generator->randomDigitNotNull() ) ); 70 | } 71 | 72 | return $content; 73 | } 74 | 75 | public function post_author( $haystack = [] ) { 76 | if ( empty( $haystack ) ) { 77 | $haystack = get_users( 78 | [ 79 | 'blog_id' => get_current_blog_id(), 80 | 'count_total' => false, 81 | 'fields' => 'ID', // When you pass only one field it returns an array of the values 82 | ] 83 | ); 84 | } 85 | 86 | return $this->generator->randomElement( (array) $haystack ); 87 | } 88 | 89 | public function post_status() { 90 | return 'inherit'; 91 | } 92 | 93 | public function post_parent( $haystack = [], $rate = 70 ) { 94 | return $this->generator->numberBetween( 0, 100 ) < absint( $rate ) ? 0 : $this->generator->randomElement( (array) $haystack ); 95 | } 96 | 97 | public function ping_status( $haystack = [] ) { 98 | if ( empty( $haystack ) ) { 99 | $haystack = static::$default['ping_status']; 100 | } 101 | 102 | return $this->generator->randomElement( (array) $haystack ); 103 | } 104 | 105 | public function comment_status( $haystack = [] ) { 106 | if ( empty( $haystack ) ) { 107 | $haystack = static::$default['comment_status']; 108 | } 109 | 110 | return $this->generator->randomElement( (array) $haystack ); 111 | } 112 | 113 | public function menu_order( $haystack = [] ) { 114 | if ( empty( $haystack ) ) { 115 | return 0; 116 | } 117 | 118 | return $this->generator->randomElement( (array) $haystack ); 119 | } 120 | 121 | public function post_password( $generator = null, $args = [] ) { 122 | if ( is_null( $generator ) ) { 123 | return ''; 124 | } 125 | 126 | return call_user_func_array( $generator, $args ); 127 | } 128 | 129 | public function post_date( $min = 'now', $max = null ) { 130 | $min = carbon( $min ); 131 | if ( is_wp_error( $min ) ) { 132 | return null; 133 | } 134 | 135 | if ( ! is_null( $max ) ) { 136 | $max = carbon( $max ); 137 | } 138 | 139 | if ( ! is_null( $max ) ) { 140 | $selected = $this->generator->dateTimeBetween( (string) $min, (string) $max )->format( 'Y-m-d H:i:s' ); 141 | } else { 142 | $selected = (string) $min; 143 | } 144 | 145 | return $selected; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/FakerPress/Provider/WP_Comment.php: -------------------------------------------------------------------------------- 1 | [ 5, 15 ], 14 | ]; 15 | $args = wp_parse_args( $args, $defaults ); 16 | 17 | if ( true === $html ) { 18 | $content = implode( "\n", $this->generator->html_elements( $args ) ); 19 | } else { 20 | $content = implode( "\r\n\r\n", $this->generator->paragraphs( make( Utils::class )->get_qty_from_range( $args['qty'] ) ) ); 21 | } 22 | 23 | return $content; 24 | } 25 | 26 | public function user_id( $users = [] ) { 27 | // We only need to query if there is no users passed 28 | if ( is_array( $users ) && empty( $users ) ) { 29 | $users = get_users( 30 | [ 31 | 'blog_id' => $GLOBALS['blog_id'], 32 | 'count_total' => false, 33 | 'fields' => 'ID', // When you pass only one field it returns an array of the values 34 | ] 35 | ); 36 | } 37 | 38 | // Cast $users as an array and always return an absolute integer 39 | $user_id = absint( $this->generator->randomElement( (array) $users ) ); 40 | 41 | return $user_id; 42 | } 43 | 44 | public function comment_author( $comment_author = null ) { 45 | // Lacks the method to random a bunch of elements 46 | return $this->generator->name(); 47 | } 48 | 49 | public function comment_parent( $comment_parent = null ) { 50 | // Lacks the method to random a bunch of elements 51 | return absint( $comment_parent ); 52 | } 53 | 54 | /** 55 | * Generate a random comment type with the values given 56 | * Converts 'default' into an empty string for default post comments 57 | * 58 | * @since 0.4.8 59 | * 60 | * @param array|string $comment_type Possible comment types to pick from 61 | * 62 | * @return string 63 | */ 64 | public function comment_type( $comment_type = null ) { 65 | // Fetch a Random element from the possible comment types 66 | $comment_type = $this->generator->randomElement( (array) $comment_type ); 67 | 68 | if ( 'default' === $comment_type || is_null( $comment_type ) ) { 69 | $comment_type = ''; 70 | } 71 | 72 | return $comment_type; 73 | } 74 | 75 | public function comment_author_IP( $ip = null ) { 76 | if ( is_null( $ip ) ) { 77 | $ip = $this->generator->ipv4; 78 | } 79 | 80 | return $ip; 81 | } 82 | 83 | public function comment_agent( $user_agent = null ) { 84 | if ( is_null( $user_agent ) ) { 85 | $user_agent = $this->generator->userAgent; 86 | } 87 | 88 | return $user_agent; 89 | } 90 | 91 | public function comment_approved( $comment_approved = 1 ) { 92 | 93 | return $comment_approved; 94 | } 95 | 96 | /** 97 | * Generates a Post ID for the Comment 98 | * 99 | * @since 0.1.0 100 | * @since 0.4.8 Argument `$args` to allow custom Post Types 101 | * 102 | * @param array|int $comment_post_ID Which ids you want to use 103 | * @param array $args WP_Query args for Searching these Posts 104 | * 105 | * @return int 106 | */ 107 | public function comment_post_ID( $comment_post_ID = null, $args = [] ) { 108 | 109 | if ( is_null( $comment_post_ID ) ) { 110 | // We should be able to pass these arguments 111 | $defaults = [ 112 | 'posts_per_page' => -1, 113 | 'post_type' => 'post', 114 | 'post_status' => 'publish', 115 | 'suppress_filters' => true, 116 | ]; 117 | 118 | // Apply the defaults 119 | $args = wp_parse_args( $args, $defaults ); 120 | 121 | // We need only the IDs here 122 | $args['fields'] = 'ids'; 123 | 124 | $query = new \WP_Query( $args ); 125 | 126 | if ( $query->found_posts ) { 127 | $comment_post_ID = absint( $this->generator->randomElement( $query->posts, 1 ) ); 128 | } 129 | 130 | // We need to check if there is no posts, should we include the comment anyways? 131 | } 132 | 133 | return $comment_post_ID; 134 | } 135 | 136 | public function comment_author_email( $author_email = null ) { 137 | if ( is_null( $author_email ) ) { 138 | $author_email = $this->generator->safeEmail; 139 | $author_email = substr( $author_email, 0, strlen( $author_email ) - 1 ); 140 | } 141 | 142 | return $author_email; 143 | } 144 | 145 | public function comment_author_url( $author_url = null ) { 146 | if ( is_null( $author_url ) ) { 147 | $author_url = $this->generator->url; 148 | $author_url = substr( $author_url, 0, strlen( $author_url ) - 1 ); 149 | } 150 | 151 | return $author_url; 152 | } 153 | 154 | public function comment_date( $min = 'now', $max = null ) { 155 | // Unfortunately there is not such solution to this problem, we need to try and catch with DateTime 156 | try { 157 | $min = new Chronos( $min ); 158 | } catch ( \Exception $e ) { 159 | return null; 160 | } 161 | 162 | if ( ! is_null( $max ) ) { 163 | // Unfortunately there is not such solution to this problem, we need to try and catch with DateTime 164 | try { 165 | $max = new Chronos( $max ); 166 | } catch ( \Exception $e ) { 167 | return null; 168 | } 169 | } 170 | 171 | if ( ! is_null( $max ) ) { 172 | $selected = $this->generator->dateTimeBetween( (string) $min, (string) $max )->format( 'Y-m-d H:i:s' ); 173 | } else { 174 | $selected = (string) $min; 175 | } 176 | 177 | return $selected; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/FakerPress/Provider/WP_Post.php: -------------------------------------------------------------------------------- 1 | [ 'closed', 'open' ], 27 | 'comment_status' => [ 'closed', 'open' ], 28 | ]; 29 | 30 | public function post_title( $qty_words = 5 ) { 31 | $title = $this->generator->sentence( $qty_words ); 32 | $title = substr( $title, 0, strlen( $title ) - 1 ); 33 | 34 | return $title; 35 | } 36 | 37 | public function post_type( $haystack = [] ) { 38 | if ( empty( $haystack ) ) { 39 | // Later on we will remove the Attachment rule 40 | $haystack = array_diff( get_post_types( [ 'public' => true, 'show_ui' => true ], 'names' ), [ 'attachment' ] ); 41 | } 42 | 43 | return $this->generator->randomElement( (array) $haystack ); 44 | } 45 | 46 | public function post_status( $haystack = [ 'draft', 'publish', 'private' ] ) { 47 | if ( empty( $haystack ) ) { 48 | $haystack = array_values( get_post_stati() ); 49 | } 50 | 51 | return $this->generator->randomElement( (array) $haystack ); 52 | } 53 | 54 | public function post_date( $interval = 'now' ) { 55 | $format = 'Y-m-d H:i:s'; 56 | $interval = (array) $interval; 57 | 58 | // Unfortunately there is not such solution to this problem, we need to try and catch with DateTime 59 | try { 60 | $min = new Chronos( array_shift( $interval ) ); 61 | } catch ( \Exception $e ) { 62 | $min = new Chronos( 'today' ); 63 | $min = $min->startOfDay(); 64 | } 65 | 66 | if ( ! empty( $interval ) ) { 67 | // Unfortunately there is not such solution to this problem, we need to try and catch with DateTime 68 | try { 69 | $max = new Chronos( array_shift( $interval ) ); 70 | } catch ( \Exception $e ) { 71 | 72 | } 73 | } 74 | 75 | if ( ! isset( $max ) ) { 76 | $max = new Chronos( 'now' ); 77 | } 78 | 79 | // If max has no Time set it to the end of the day 80 | $max_has_time = array_filter( [ $max->hour, $max->minute, $max->second ] ); 81 | $max_has_time = ! empty( $max_has_time ); 82 | if ( ! $max_has_time ) { 83 | $max = $max->endOfDay(); 84 | } 85 | 86 | $selected = $this->generator->dateTimeBetween( (string) $min, (string) $max )->format( $format ); 87 | 88 | return $selected; 89 | } 90 | 91 | public function post_content( $html = true, $args = [] ) { 92 | $defaults = [ 93 | 'qty' => [ 5, 15 ], 94 | ]; 95 | $args = wp_parse_args( $args, $defaults ); 96 | 97 | if ( true === $html ) { 98 | $content = implode( "\n", $this->generator->html_elements( $args ) ); 99 | } else { 100 | $content = implode( "\r\n\r\n", $this->generator->paragraphs( make( Utils::class )->get_qty_from_range( $args['qty'] ) ) ); 101 | } 102 | 103 | return $content; 104 | } 105 | 106 | /** 107 | * Configures a Excerpt for the Post 108 | * 109 | * @since 0.4.9 110 | * 111 | * @param array|int $qty How many words we should generate (range with Array) 112 | * @param boolean $html Should use HTML or not (currently not used) 113 | * @param integer $weight Percentage of times where we will setup a Excerpt 114 | * 115 | * @return string 116 | */ 117 | public function post_excerpt( $qty = [ 25, 75 ], $html = false, $weight = 60 ) { 118 | $words = make( Utils::class )->get_qty_from_range( $qty ); 119 | $paragraphs = $this->generator->randomElement( [ 1, 1, 1, 1, 1, 2, 2, 2, 3, 4 ] ); 120 | 121 | for ( $i = 0; $i < $paragraphs; $i++ ) { 122 | $excerpt[ $i ] = $this->generator->sentence( $words ); 123 | } 124 | 125 | $excerpt = implode( "\n\n", $excerpt ); 126 | 127 | return $this->generator->optional( $weight / 100, '' )->randomElement( (array) $excerpt ); 128 | } 129 | 130 | public function post_author( $haystack = [] ) { 131 | if ( empty( $haystack ) ) { 132 | $haystack = get_users( 133 | [ 134 | 'blog_id' => get_current_blog_id(), 135 | 'count_total' => false, 136 | 'fields' => 'ID', // When you pass only one field it returns an array of the values 137 | ] 138 | ); 139 | } 140 | 141 | return $this->generator->randomElement( (array) $haystack ); 142 | } 143 | 144 | public function post_parent( $haystack = [], $weight = 70 ) { 145 | return $this->generator->optional( $weight / 100, 0 )->randomElement( (array) $haystack ); 146 | } 147 | 148 | public function ping_status( $haystack = [] ) { 149 | if ( empty( $haystack ) ) { 150 | $haystack = static::$default['ping_status']; 151 | } 152 | 153 | return $this->generator->randomElement( (array) $haystack ); 154 | } 155 | 156 | public function comment_status( $haystack = [] ) { 157 | if ( empty( $haystack ) ) { 158 | $haystack = static::$default['comment_status']; 159 | } 160 | 161 | return $this->generator->randomElement( (array) $haystack ); 162 | } 163 | 164 | public function menu_order( $haystack = [] ) { 165 | if ( empty( $haystack ) ) { 166 | return 0; 167 | } 168 | 169 | return $this->generator->randomElement( (array) $haystack ); 170 | } 171 | 172 | public function post_password( $generator = null, $args = [] ) { 173 | if ( is_null( $generator ) ) { 174 | return ''; 175 | } 176 | 177 | return call_user_func_array( $generator, $args ); 178 | } 179 | 180 | public function tax_input( $config = null ) { 181 | $output = []; 182 | if ( is_null( $config ) ) { 183 | return $output; 184 | } 185 | 186 | // The percentage of change in which the terms will be applied 187 | $rates = apply_filters( 'fakerpress/provider/WP_Post/tax_input.rates', [ 188 | 'category' => 50, 189 | 'post_tag' => 45, 190 | '__default' => 35, 191 | ] ); 192 | 193 | // The amount of terms that might have, provide a number for exact and [ int, int ] to range 194 | $ranges = apply_filters( 'fakerpress/provider/WP_Post/tax_input.ranges', [ 195 | 'category' => [ 1, 3 ], 196 | 'post_tag' => [ 0, 15 ], 197 | '__default' => [ 0, 3 ], 198 | ] ); 199 | 200 | foreach ( $config as $settings ) { 201 | $settings = (object) $settings; 202 | 203 | if ( ! empty( $settings->taxonomies ) && is_string( $settings->taxonomies ) ) { 204 | $settings->taxonomies = explode( ',', $settings->taxonomies ); 205 | } 206 | $settings->taxonomies = array_filter( (array) $settings->taxonomies ); 207 | 208 | if ( ! empty( $settings->terms ) && is_string( $settings->terms ) ) { 209 | $settings->terms = explode( ',', $settings->terms ); 210 | } 211 | $settings->terms = array_filter( (array) $settings->terms ); 212 | 213 | foreach ( $settings->taxonomies as $taxonomy ) { 214 | if ( empty( $settings->terms ) ) { 215 | $terms = get_terms( $taxonomy, [ 'fields' => 'ids', 'hide_empty' => false ] ); 216 | } else { 217 | $terms = $settings->terms; 218 | } 219 | 220 | // Get all the term ids 221 | $terms = array_filter( array_map( 'absint', $terms ) ); 222 | 223 | if ( ! isset( $settings->qty ) ) { 224 | $qty = make( Utils::class )->get_qty_from_range( ( isset( $ranges[ $taxonomy ] ) ? $ranges[ $taxonomy ] : $ranges['__default'] ), $terms ); 225 | } else { 226 | $qty = (int) make( Utils::class )->get_qty_from_range( $settings->qty, $terms ); 227 | } 228 | 229 | if ( ! isset( $settings->rate ) ) { 230 | $rate = isset( $rates[ $taxonomy ] ) ? $rates[ $taxonomy ] : $rates['__default']; 231 | } else { 232 | $rate = (int) $settings->rate; 233 | } 234 | 235 | // Select the elements based on qty 236 | $output[ $taxonomy ] = $this->generator->optional( ( (int) $rate ) / 100, null )->randomElements( $terms, (int) $qty ); 237 | } 238 | } 239 | 240 | return $output; 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /src/FakerPress/Provider/WP_Term.php: -------------------------------------------------------------------------------- 1 | get_qty_from_range( $qty ); 12 | $name = $this->generator->sentence( $qty ); 13 | 14 | // This removes the last dot on the end of the sentence 15 | $name = rtrim( $name, '.' ); 16 | 17 | return $name; 18 | } 19 | 20 | public function taxonomy( $taxonomies = [ 'category', 'post_tag' ], $args = [] ) { 21 | if ( empty( $taxonomies ) ){ 22 | // Merge the returned terms to those provided 23 | $taxonomies = get_taxonomies( $args, 'names' ); 24 | } 25 | 26 | return $this->generator->randomElement( (array) $taxonomies ); 27 | } 28 | 29 | public function description( $min = 5, $max = 50 ) { 30 | if ( is_array( $min ) ){ 31 | $description = $this->generator->randomElement( $min ); 32 | } else { 33 | // Not sure if this is the best approach, but it will work no metter what... 34 | if ( ! is_numeric( $min ) ){ 35 | $min = 5; 36 | } 37 | if ( ! is_numeric( $max ) ){ 38 | $max = 50; 39 | } 40 | $description = $this->generator->sentence( $this->generator->numberBetween( $min, $max ) ); 41 | 42 | // This removes the last dot on the end of the sentence 43 | $description = substr( $description, 0, strlen( $description ) - 1 ); 44 | } 45 | 46 | return $description; 47 | } 48 | 49 | public function parent_term( $terms = [], $taxonomies = [], $args = [] ) { 50 | if ( ! empty( $taxonomies ) ){ 51 | // We only need the ids to be returned 52 | $args['fields'] = 'ids'; 53 | 54 | // Merge the returned terms to the one provided 55 | $terms = array_merge( (array) $terms, get_terms( $taxonomies, $args ) ); 56 | } 57 | 58 | return $this->generator->randomElement( (array) $terms ); 59 | } 60 | 61 | 62 | // For now I think we should omit the slug, since it's auto-gen, but we need to figure a way to do it later 63 | /* 64 | public function slug(){ 65 | 66 | return $slug; 67 | } 68 | */ 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/FakerPress/Provider/WP_User.php: -------------------------------------------------------------------------------- 1 | generator->firstName( $this->generator->randomElements( $gender, 1 ) ); 24 | } 25 | 26 | /** 27 | * Returns a last name, if nothing was passed, it will generate a random one. 28 | * 29 | * @since 0.1.0 30 | * @since 0.6.2 Introduced type safety. 31 | * 32 | * @param string|null $last_name 33 | * 34 | * @return string|null 35 | */ 36 | public function last_name( ?string $last_name = null ): ?string { 37 | return $last_name ?? $this->generator->lastName(); 38 | } 39 | 40 | /** 41 | * Returns a random username, if nothing was passed, it will generate a random one. 42 | * 43 | * @since 0.1.0 44 | * @since 0.6.2 Introduced type safety. 45 | * 46 | * @param string|null $login 47 | * 48 | * @return string|null 49 | */ 50 | public function user_login( ?string $login = null ): ?string { 51 | return $login ?? $this->generator->userName(); 52 | } 53 | 54 | /** 55 | * Returns a random nicename, if nothing was passed, it will generate a random one. 56 | * 57 | * @since 0.1.0 58 | * @since 0.6.2 Introduced type safety. 59 | * 60 | * @param string|null $nicename 61 | * 62 | * @return string|null 63 | */ 64 | public function user_nicename( ?string $nicename = null ): ?string { 65 | return $nicename ?? $this->generator->userName(); 66 | } 67 | 68 | /** 69 | * Returns a random URL, if nothing was passed, it will generate a random one. 70 | * 71 | * @since 0.1.0 72 | * @since 0.6.2 Introduced type safety. 73 | * 74 | * @param string|null $url 75 | * 76 | * @return string|null 77 | */ 78 | public function user_url( ?string $url = null ): ?string { 79 | return $url ?? $this->generator->url(); 80 | } 81 | 82 | /** 83 | * Returns a random email, if nothing was passed, it will generate a random one. 84 | * 85 | * @since 0.1.0 86 | * @since 0.6.2 Introduced type safety. 87 | * 88 | * @param string|null $email 89 | * 90 | * @return string|null 91 | */ 92 | public function user_email( ?string $email = null ): ?string { 93 | return $email ?? $this->generator->safeEmail(); 94 | } 95 | 96 | /** 97 | * Returns a random display name, if nothing was passed, it will generate a random one. 98 | * 99 | * @since 0.1.0 100 | * @since 0.6.2 Introduced type safety. 101 | * 102 | * @param string|null $display_name 103 | * @param string[] $gender 104 | * 105 | * @return string|null 106 | */ 107 | public function display_name( ?string $display_name = null, array $gender = [ 'male', 'female' ] ): ?string { 108 | return $display_name ?? $this->generator->firstName( $this->generator->randomElements( $gender, 1 ) ); 109 | } 110 | 111 | /** 112 | * Returns a random nickname, if nothing was passed, it will generate a random one. 113 | * 114 | * @since 0.1.0 115 | * @since 0.6.2 Introduced type safety. 116 | * 117 | * @param string|null $nickname 118 | * 119 | * @return string|null 120 | */ 121 | public function nickname( ?string $nickname = null ): ?string { 122 | return $nickname ?? $this->generator->userName(); 123 | } 124 | 125 | /** 126 | * Returns a random password, if nothing was passed, it will generate a random one. 127 | * 128 | * @since 0.1.0 129 | * @since 0.6.2 Introduced type safety. 130 | * 131 | * @param string|null $pass 132 | * @param int $qty 133 | * 134 | * @return string|null 135 | */ 136 | public function user_pass( ?string $pass = null, int $qty = 16 ): ?string { 137 | if ( is_null( $pass ) ) { 138 | if ( function_exists( 'wp_generate_password' ) ) { 139 | $pass = wp_generate_password( $qty, true ); 140 | } else { 141 | $pass = $this->generator->password( $qty ); 142 | } 143 | } 144 | return $pass; 145 | } 146 | 147 | /** 148 | * Returns a random description. 149 | * 150 | * @since 0.1.0 151 | * @since 0.6.2 Introduced type safety. 152 | * 153 | * @param bool $html Whether to return HTML or plain text. 154 | * @param array $args 155 | * 156 | * @return string|null 157 | */ 158 | public function description( $html = true, $args = [] ): ?string { 159 | $defaults = [ 160 | 'qty' => [ 5, 15 ], 161 | ]; 162 | $args = wp_parse_args( $args, $defaults ); 163 | 164 | if ( true === $html ) { 165 | $content = implode( "\n", $this->generator->html_elements( $args ) ); 166 | } else { 167 | $content = implode( "\r\n\r\n", $this->generator->paragraphs( make( Utils::class )->get_qty_from_range( $args['qty'] ) ) ); 168 | } 169 | 170 | return $content; 171 | } 172 | 173 | /** 174 | * Returns a random role, if nothing was passed, it will pick a random one from the available roles. 175 | * 176 | * @since 0.1.0 177 | * @since 0.6.2 Introduced type safety. 178 | * 179 | * @param string[] $role 180 | * 181 | * @return string 182 | */ 183 | public function role( ?array $role = [] ): ?string { 184 | return $this->generator->randomElement( $role ?? array_keys( get_editable_roles() ) ); 185 | } 186 | 187 | public function user_registered( $min = 'now', $max = null ) { 188 | try { 189 | $min = new Chronos( $min ); 190 | } catch ( \Exception $e ) { 191 | return null; 192 | } 193 | 194 | if ( ! is_null( $max ) ) { 195 | // Unfortunately there is not such solution to this problem, we need to try and catch with DateTime 196 | try { 197 | $max = new Chronos( $max ); 198 | } catch ( \Exception $e ) { 199 | return null; 200 | } 201 | } 202 | 203 | if ( ! is_null( $max ) ) { 204 | $selected = $this->generator->dateTimeBetween( (string) $min, (string) $max )->format( 'Y-m-d H:i:s' ); 205 | } else { 206 | $selected = (string) $min; 207 | } 208 | 209 | return $selected; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /src/functions/assets.php: -------------------------------------------------------------------------------- 1 | register( $origin, $slug, $file, $deps, $action, $arguments ); 23 | } 24 | 25 | /** 26 | * Shortcut for FakerPress\Assets::enqueue() to include assets. 27 | * 28 | * @since 0.5.1 29 | * 30 | * @param string|array $slug Slug to enqueue 31 | */ 32 | function enqueue_asset( $slug ) { 33 | $assets = make( Utils\Assets::class ); 34 | 35 | $assets->enqueue( $slug ); 36 | } 37 | 38 | /** 39 | * Shortcut for FakerPress\Assets::enqueue_group() include assets by groups. 40 | * 41 | * @since 0.5.1 42 | * 43 | * @param string|array $group Which group(s) should be enqueued. 44 | */ 45 | function enqueue_asset_group( $group ) { 46 | $assets = make( Utils\Assets::class ); 47 | $assets->enqueue_group( $group ); 48 | } 49 | -------------------------------------------------------------------------------- /src/functions/conditionals.php: -------------------------------------------------------------------------------- 1 | $e ] ); 31 | } 32 | 33 | return $date; 34 | } 35 | -------------------------------------------------------------------------------- /src/functions/load.php: -------------------------------------------------------------------------------- 1 | priority; 20 | } 21 | 22 | if ( is_array( $b ) ) { 23 | $b_priority = $b['priority']; 24 | } else { 25 | $b_priority = $b->priority; 26 | } 27 | 28 | if ( (int) $a_priority === (int) $b_priority ) { 29 | return 0; 30 | } 31 | 32 | return (int) $a_priority < (int) $b_priority ? -1 : 1; 33 | } 34 | -------------------------------------------------------------------------------- /src/functions/variables.php: -------------------------------------------------------------------------------- 1 | ">

<%= html %>

' )( templateVars ), 23 | $notice = $( noticeHtml ); 24 | 25 | $notice.on( 'click.wp-dismiss-notice', '.notice-dismiss', function( event ) { 26 | event.preventDefault(); 27 | $notice.fadeTo( 100 , 0, function() { 28 | $(this).slideUp( 100, function() { 29 | $(this).remove(); 30 | }); 31 | }); 32 | }); 33 | 34 | return $element.append( $notice ); 35 | }; 36 | 37 | fp.moduleGenerate = ( $form, _POST ) => { 38 | if ( 'undefined' === typeof _POST ){ 39 | _POST = window.fakerpress.qs.parse( $form.serialize() ); 40 | } 41 | 42 | // Always Hard set the Action 43 | _POST.action = 'fakerpress.module_generate'; 44 | 45 | var $submit_container = $form.find( '.fp-submit' ), 46 | $spinner = $submit_container.find( '.spinner' ), 47 | $button = $submit_container.find( '.button-primary' ), 48 | $response = $submit_container.find( '.fp-response' ); 49 | 50 | if ( $spinner.hasClass( 'is-active' ) ){ 51 | return; 52 | } 53 | $spinner.addClass( 'is-active' ); 54 | $button.prop( 'disabled', true ); 55 | 56 | $.ajax({ 57 | dataType: 'json', 58 | type: 'POST', 59 | url: window.ajaxurl, 60 | data: _POST, 61 | complete: function( jqXHR, status ){ 62 | if ( 'success' !== status ){ 63 | $spinner.removeClass( 'is-active' ); 64 | $button.prop( 'disabled', false ); 65 | 66 | fp.log( $response, '<%= message %>', { message: jqXHR.responseText }, 'notice-error' ); 67 | } 68 | }, 69 | success: function( data, textStatus, jqXHR ) { 70 | $spinner.removeClass( 'is-active' ); 71 | if ( null === data ) { 72 | $button.prop( 'disabled', false ); 73 | fp.log( $response, '<%= message %>', { message: jqXHR.responseText }, 'notice-error' ); 74 | } else if ( data.status ){ 75 | if ( data.is_capped && data.offset < data.total ){ 76 | _POST.offset = data.offset; 77 | _POST.total = data.total; 78 | 79 | fp.moduleGenerate( $form, _POST ); 80 | } else { 81 | $button.prop( 'disabled', false ); 82 | } 83 | 84 | fp.log( $response, 'Faked <%= total %>: <%= message %>', { message: data.message, total: data.results.length }, 'notice-success' ); 85 | } else { 86 | $button.prop( 'disabled', false ); 87 | fp.log( $response, '<%= message %>', data, 'notice-error' ); 88 | } 89 | } 90 | }); 91 | }; 92 | 93 | // Document Ready Actions 94 | $( () => { 95 | const $forms = $( fp.selectors.moduleGenerator ).each( function() { 96 | const $form = $( this ); 97 | 98 | $form.on( 'submit', function ( event ) { 99 | fp.moduleGenerate( $form ); 100 | 101 | console.log( 'Form', $form ); 102 | event.preventDefault(); 103 | return; 104 | } ); 105 | } ); 106 | } ); 107 | }( jQuery, _ ) ); 108 | -------------------------------------------------------------------------------- /src/resources/pcss/font.pcss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'FakerPress'; 3 | src:url('../font/fakerpress.eot'); 4 | src:url('../font/fakerpress.eot?#iefix') format('embedded-opentype'), 5 | url('../font/fakerpress.ttf') format('truetype'), 6 | url('../font/fakerpress.woff') format('woff'), 7 | url('../font/fakerpress.svg#fakerpress') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | .icon-fakerpress::before, 13 | .toplevel_page_fakerpress.menu-top .wp-menu-image::before { 14 | font-family: 'FakerPress'; 15 | content: "\e600"; 16 | display: block; 17 | } 18 | 19 | 20 | .toplevel_page_fakerpress.menu-top .wp-menu-image::before { 21 | margin: 1px 0 0 8px; 22 | } 23 | -------------------------------------------------------------------------------- /src/resources/pcss/messages.pcss: -------------------------------------------------------------------------------- 1 | .fakerpress-message { 2 | border-left: 4px solid #444; 3 | padding: 1px 12px; 4 | background-color: #fff; 5 | -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1); 6 | box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1); 7 | margin-bottom: 5px; 8 | } 9 | .fakerpress-message.first { 10 | margin-top: 20px; 11 | } 12 | 13 | .fakerpress-message.fakerpress-message-success { 14 | border-left-color: #7ad03a; 15 | } 16 | 17 | .fakerpress-message.fakerpress-message-error { 18 | border-left-color: #dd3d36; 19 | } 20 | 21 | .fakerpress-message.fakerpress-message-warning { 22 | border-left-color: #ffba00; 23 | } 24 | 25 | .dashicon-date { 26 | height: 25px; 27 | line-height: 26px; 28 | border: 1px solid #DDD; 29 | margin-top: 1px; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/resources/pcss/select2-wordpress.pcss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bordoni/fakerpress/9d7a27014e1fb700e0bad8a863678ed42216ed73/src/resources/pcss/select2-wordpress.pcss -------------------------------------------------------------------------------- /src/templates/fields/components/container/end.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/templates/fields/components/container/start.php: -------------------------------------------------------------------------------- 1 | 6 | 10 | -------------------------------------------------------------------------------- /src/templates/fields/components/field.php: -------------------------------------------------------------------------------- 1 | render( 'components/container/start' ); ?> 2 | 3 | render( 'fieldset/children' ); ?> 4 | 5 | render( 'components/container/end' ); ?> 6 | 7 | -------------------------------------------------------------------------------- /src/templates/fields/fieldset/children.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | get_children() as $children ) : ?> 4 | get_html(); ?> 5 | 6 | 7 |
8 | -------------------------------------------------------------------------------- /src/templates/fields/raw.php: -------------------------------------------------------------------------------- 1 | render( 'components/container/start' ); ?> 2 | 3 | get_raw_html() ; ?> 4 | 5 | render( 'components/container/end' ); ?> 6 | 7 | -------------------------------------------------------------------------------- /src/templates/pages/attachments.php: -------------------------------------------------------------------------------- 1 | 'qty', 14 | ], 15 | [ 16 | 'label' => __( 'Quantity', 'fakerpress' ), 17 | 'description' => __( 'How many posts should be generated, use both fields to get a randomized number of posts within the given range.', 'fakerpress' ), 18 | ] 19 | ); 20 | 21 | $fields[] = new Field( 22 | 'interval', 23 | [ 24 | 'id' => 'interval_date', 25 | 'value' => 'yesterday', 26 | ], 27 | [ 28 | 'label' => __( 'Date', 'fakerpress' ), 29 | 'description' => __( 'Choose the range for the posts dates.', 'fakerpress' ), 30 | ] 31 | ); 32 | 33 | $fields[] = new Field( 34 | 'dropdown', 35 | [ 36 | 'id' => 'post_parent', 37 | 'multiple' => true, 38 | 'data-source' => 'WP_Query', 39 | 'data-nonce' => wp_create_nonce( Plugin::$slug . '-select2-WP_Query' ), 40 | ], 41 | [ 42 | 'label' => __( 'Parents', 'fakerpress' ), 43 | 'description' => __( 'What posts can be chosen as Parent to the ones created', 'fakerpress' ), 44 | ] 45 | ); 46 | 47 | $fields[] = new Field( 48 | 'dropdown', 49 | [ 50 | 'id' => 'comment_status', 51 | 'multiple' => true, 52 | 'value' => 'open', 53 | 'data-options' => [ 54 | [ 55 | 'id' => 'open', 56 | 'text' => esc_attr__( 'Allow Comments', 'fakerpress' ), 57 | ], 58 | [ 59 | 'id' => 'closed', 60 | 'text' => esc_attr__( 'Comments closed', 'fakerpress' ), 61 | ], 62 | ], 63 | ], 64 | [ 65 | 'label' => __( 'Comments Status', 'fakerpress' ), 66 | 'description' => __( 'Sampling group of options for the comment status of the posts', 'fakerpress' ), 67 | ] 68 | ); 69 | 70 | $fields[] = new Field( 71 | 'checkbox', 72 | [ 73 | 'id' => 'use_html', 74 | 'options' => [ 75 | [ 76 | 'text' => __( 'Use HTML on your randomized post content?', 'fakerpress' ), 77 | 'value' => 1, 78 | ], 79 | ], 80 | 'value' => 1, 81 | ], 82 | [ 83 | 'label' => __( 'Use HTML', 'fakerpress' ), 84 | ] 85 | ); 86 | 87 | $_elements = array_merge( HTML::$sets['header'], HTML::$sets['list'], HTML::$sets['block'], HTML::$sets['self_close'] ); 88 | $fields[] = new Field( 89 | 'dropdown', 90 | [ 91 | 'id' => 'html_tags', 92 | 'multiple' => true, 93 | 'data-tags' => true, 94 | 'data-options' => $_elements, 95 | 'value' => implode( ',', $_elements ), 96 | ], 97 | [ 98 | 'label' => __( 'HTML tags', 'fakerpress' ), 99 | 'description' => __( 'Select the group of tags that can be selected to print on the Post Content', 'fakerpress' ), 100 | ] 101 | ); 102 | 103 | /* 104 | This comes back as a Meta Field Template 105 | $fields[] = new Field( 106 | 'number', 107 | [ 108 | 'id' => 'featured_image_rate', 109 | 'placeholder' => __( 'e.g.: 75', 'fakerpress' ), 110 | 'min' => 0, 111 | 'max' => 100, 112 | 'value' => 75, 113 | ], 114 | [ 115 | 'label' => __( 'Featured Image Rate', 'fakerpress' ), 116 | 'description' => __( 'Percentage of the posts created that will have an Featured Image', 'fakerpress' ), 117 | ] 118 | ); 119 | 120 | $_image_providers[] = [ 121 | 'id' => 'placeholdit', 122 | 'text' => 'Placehold.it', 123 | ]; 124 | 125 | $_image_providers[] = [ 126 | 'id' => 'lorempicsum', 127 | 'text' => 'Lorem Picsum', 128 | ]; 129 | 130 | $fields[] = new Field( 131 | 'dropdown', 132 | [ 133 | 'id' => 'images_origin', 134 | 'multiple' => true, 135 | 'value' => implode( ',', wp_list_pluck( $_image_providers, 'id' ) ), 136 | 'data-options' => $_image_providers, 137 | ], 138 | [ 139 | 'label' => __( 'Image Providers', 'fakerpress' ), 140 | 'description' => __( 'Which image services will the generator use?', 'fakerpress' ), 141 | ] 142 | ); 143 | */ 144 | 145 | // Mount the options for Users 146 | $users = get_users( 147 | [ 148 | 'blog_id' => $GLOBALS['blog_id'], 149 | 'count_total' => false, 150 | 'fields' => [ 'ID', 'display_name' ], // When you pass only one field it returns an array of the values 151 | ] 152 | ); 153 | 154 | $_json_users_output = []; 155 | foreach ( $users as $user ) { 156 | $_json_users_output[] = [ 157 | 'id' => $user->ID, 158 | 'text' => esc_attr( $user->display_name ), 159 | ]; 160 | } 161 | 162 | $fields[] = new Field( 163 | 'dropdown', 164 | [ 165 | 'id' => 'author', 166 | 'multiple' => true, 167 | 'data-options' => $_json_users_output, 168 | ], 169 | [ 170 | 'label' => __( 'Author', 'fakerpress' ), 171 | 'description' => __( 'Choose some users to be authors of posts generated.', 'fakerpress' ), 172 | ] 173 | ); 174 | 175 | $fields[] = new Field( 176 | 'meta', 177 | [ 178 | 'id' => 'meta', 179 | 'duplicate' => true, 180 | ], 181 | [ 182 | 'label' => __( 'Meta Field Rules', 'fakerpress' ), 183 | 'description' => __( 'Use the fields below to configure a set of rules for your generated Posts', 'fakerpress' ), 184 | ] 185 | ); 186 | 187 | $new_fields = [ 188 | 'type' => 'fieldset', 189 | 'children' => [ 190 | [ 191 | 'type' => 'raw', 192 | 'id' => 'my-own-raw', 193 | 'html' => 'From RAW!' 194 | ] 195 | ] 196 | ]; 197 | 198 | 199 | ?> 200 |
201 |

get_title() ); ?>

202 | 203 |
204 | 205 | 206 | 207 | output( true ); } ?> 208 | 209 | make( $new_fields )->get_html() ?> 210 | 211 |
212 | 213 |
214 |
215 | -------------------------------------------------------------------------------- /src/templates/pages/changelog.php: -------------------------------------------------------------------------------- 1 | 9 | 18 |
19 |

20 |
21 | changelog->versions as $number => $version ) : ?> 22 | 27 |

number ); ?> — date ); ?>

28 | html; ?> 29 | 30 |
31 |
32 | -------------------------------------------------------------------------------- /src/templates/pages/comments.php: -------------------------------------------------------------------------------- 1 | get_col( "SELECT `comment_type` FROM $wpdb->comments GROUP BY `comment_type`" ); 10 | 11 | // Default is the Empty value 12 | $_json_comment_types_output = [ 13 | [ 14 | 'id' => 'default', 15 | 'text' => esc_attr__( 'default', 'fakerpress' ), 16 | ], 17 | ]; 18 | 19 | foreach ( $comment_types as $comment ) { 20 | // Skip the Default Option 21 | if ( empty( $comment ) ) { 22 | continue; 23 | } 24 | 25 | $_json_comment_types_output[] = [ 26 | 'id' => $comment, 27 | 'text' => $comment, 28 | ]; 29 | } 30 | 31 | $fields[] = new Field( 32 | 'dropdown', 33 | [ 34 | 'id' => 'type', 35 | 'multiple' => true, 36 | 'data-options' => $_json_comment_types_output, 37 | 'data-tags' => true, 38 | 'value' => 'default', 39 | ], 40 | [ 41 | 'label' => __( 'Type', 'fakerpress' ), 42 | 'description' => __( 'Which type of comment are you going to generate?', 'fakerpress' ), 43 | ] 44 | ); 45 | 46 | // Mount the options for post_types 47 | $post_types = get_post_types( [ 'public' => true ], 'object' ); 48 | 49 | // Exclude Attachments as we don't support images yet 50 | if ( isset( $post_types['attachment'] ) ) { 51 | unset( $post_types['attachment'] ); 52 | } 53 | 54 | $_json_post_types_output = []; 55 | foreach ( $post_types as $key => $post_type ) { 56 | $_json_post_types_output[] = [ 57 | 'hierarchical' => $post_type->hierarchical, 58 | 'id' => $post_type->name, 59 | 'text' => $post_type->labels->name, 60 | ]; 61 | } 62 | 63 | $fields[] = new Field( 64 | 'dropdown', 65 | [ 66 | 'id' => 'post_types', 67 | 'multiple' => true, 68 | 'data-options' => $_json_post_types_output, 69 | 'value' => 'post', 70 | ], 71 | [ 72 | 'label' => __( 'Post Type', 'fakerpress' ), 73 | 'description' => __( 'Group of Post Types that the comment can be generate for', 'fakerpress' ), 74 | ] 75 | ); 76 | 77 | $fields[] = new Field( 78 | 'range', 79 | 'qty', 80 | [ 81 | 'label' => __( 'Quantity', 'fakerpress' ), 82 | 'description' => __( 'How many comments should be generated, use both fields to get a randomized number of comments within the given range.', 'fakerpress' ), 83 | ] 84 | ); 85 | 86 | $fields[] = new Field( 87 | 'interval', 88 | 'interval_date', 89 | [ 90 | 'label' => __( 'Date', 'fakerpress' ), 91 | 'description' => __( 'Choose the range for the posts dates.', 'fakerpress' ), 92 | ] 93 | ); 94 | 95 | $fields[] = new Field( 96 | 'heading', 97 | [ 98 | 'title' => __( 'Comment Content', 'fakerpress' ), 99 | ], 100 | [] 101 | ); 102 | 103 | $fields[] = new Field( 104 | 'range', 105 | [ 106 | 'id' => 'content_size', 107 | 'min' => 1, 108 | 'max' => 5, 109 | ], 110 | [ 111 | 'label' => __( 'Content Size', 'fakerpress' ), 112 | 'description' => __( 'How many paragraphs we are going to generate of content.', 'fakerpress' ), 113 | ] 114 | ); 115 | 116 | $fields[] = new Field( 117 | 'checkbox', 118 | [ 119 | 'id' => 'use_html', 120 | 'value' => 1, 121 | 'options' => [ 122 | [ 123 | 'text' => __( 'Use HTML on your randomized comment content?', 'fakerpress' ), 124 | 'value' => 1, 125 | ], 126 | ], 127 | ], 128 | [ 129 | 'label' => __( 'Use HTML', 'fakerpress' ), 130 | ] 131 | ); 132 | 133 | $_elements = array_merge( HTML::$sets['header'], HTML::$sets['list'], HTML::$sets['block'] ); 134 | $fields[] = new Field( 135 | 'dropdown', 136 | [ 137 | 'id' => 'html_tags', 138 | 'multiple' => true, 139 | 'data-options' => $_elements, 140 | 'data-tags' => true, 141 | 'value' => implode( ',', $_elements ), 142 | ], 143 | [ 144 | 'label' => __( 'HTML tags', 'fakerpress' ), 145 | 'description' => __( 'Select the group of tags that can be selected to print on the Comment Content.', 'fakerpress' ), 146 | ] 147 | ); 148 | 149 | $fields[] = new Field( 150 | 'meta', 151 | [ 152 | 'id' => 'meta', 153 | ], 154 | [ 155 | 'label' => __( 'Meta Field Rules', 'fakerpress' ), 156 | 'description' => __( 'Use the fields below to configure a set of rules for your generated Comments', 'fakerpress' ), 157 | ] 158 | ); 159 | /* 160 | 161 | */ 162 | ?> 163 | 164 |
165 |

get_title() ); ?>

166 | 167 |
168 | 169 | 170 | 171 | 172 | 173 | output( true ); 175 | } ?> 176 | 177 |
178 |
179 | 180 | 181 |
182 |
183 |
184 |
185 | -------------------------------------------------------------------------------- /src/templates/pages/error.php: -------------------------------------------------------------------------------- 1 | 'FakerPress', 5 | 'related' => 'webord', 6 | ]; 7 | $locale = get_locale(); 8 | if ( ! empty( $locale ) ){ 9 | $tweet_args['hashtags'] .= ',' . esc_attr( $locale ); 10 | } 11 | $tweet_url = esc_url_raw( add_query_arg( $tweet_args, 'https://twitter.com/intent/tweet' ) ); 12 | ?> 13 |
14 |

15 |
16 | poke us on twitter!", 'fakerpress' ), $tweet_url ) ) ); ?> 17 |
18 |
19 | 20 | -------------------------------------------------------------------------------- /src/templates/pages/posts.php: -------------------------------------------------------------------------------- 1 | 'qty', 15 | ], 16 | [ 17 | 'label' => __( 'Quantity', 'fakerpress' ), 18 | 'description' => __( 'How many posts should be generated, use both fields to get a randomized number of posts within the given range.', 'fakerpress' ), 19 | ] 20 | ); 21 | 22 | $fields[] = new Field( 23 | 'interval', 24 | [ 25 | 'id' => 'interval_date', 26 | 'value' => 'yesterday', 27 | ], 28 | [ 29 | 'label' => __( 'Date', 'fakerpress' ), 30 | 'description' => __( 'Choose the range for the posts dates.', 'fakerpress' ), 31 | ] 32 | ); 33 | 34 | // Mount the options for post_types 35 | $post_types = get_post_types( [ 'public' => true ], 'object' ); 36 | 37 | // Exclude Attachments as we don't support images yet 38 | if ( isset( $post_types['attachment'] ) ) { 39 | unset( $post_types['attachment'] ); 40 | } 41 | 42 | $_json_post_types_output = []; 43 | foreach ( $post_types as $key => $post_type ) { 44 | $_json_post_types_output[] = [ 45 | 'hierarchical' => $post_type->hierarchical, 46 | 'id' => $post_type->name, 47 | 'text' => $post_type->labels->name, 48 | ]; 49 | } 50 | 51 | $fields[] = new Field( 52 | 'dropdown', 53 | [ 54 | 'id' => 'post_types', 55 | 'multiple' => true, 56 | 'data-options' => $_json_post_types_output, 57 | 'value' => 'post', 58 | ], 59 | [ 60 | 'label' => __( 'Post Type', 'fakerpress' ), 61 | 'description' => __( 'Sampling group of Post Types', 'fakerpress' ), 62 | ] 63 | ); 64 | 65 | $fields[] = new Field( 66 | 'dropdown', 67 | [ 68 | 'id' => 'post_parent', 69 | 'multiple' => true, 70 | 'data-source' => 'WP_Query', 71 | 'data-nonce' => wp_create_nonce( Plugin::$slug . '-select2-WP_Query' ), 72 | ], 73 | [ 74 | 'label' => __( 'Parents', 'fakerpress' ), 75 | 'description' => __( 'What posts can be chosen as Parent to the ones created', 'fakerpress' ), 76 | ] 77 | ); 78 | 79 | $fields[] = new Field( 80 | 'dropdown', 81 | [ 82 | 'id' => 'comment_status', 83 | 'multiple' => true, 84 | 'value' => 'open', 85 | 'data-options' => [ 86 | [ 87 | 'id' => 'open', 88 | 'text' => esc_attr__( 'Allow Comments', 'fakerpress' ), 89 | ], 90 | [ 91 | 'id' => 'closed', 92 | 'text' => esc_attr__( 'Comments closed', 'fakerpress' ), 93 | ], 94 | ], 95 | ], 96 | [ 97 | 'label' => __( 'Comments Status', 'fakerpress' ), 98 | 'description' => __( 'Sampling group of options for the comment status of the posts', 'fakerpress' ), 99 | ] 100 | ); 101 | 102 | 103 | // Mount the options for Users 104 | $users = get_users( 105 | [ 106 | 'blog_id' => $GLOBALS['blog_id'], 107 | 'count_total' => false, 108 | 'fields' => [ 'ID', 'display_name' ], // When you pass only one field it returns an array of the values 109 | ] 110 | ); 111 | 112 | $_json_users_output = []; 113 | foreach ( $users as $user ) { 114 | $_json_users_output[] = [ 115 | 'id' => $user->ID, 116 | 'text' => esc_attr( $user->display_name ), 117 | ]; 118 | } 119 | 120 | $fields[] = new Field( 121 | 'dropdown', 122 | [ 123 | 'id' => 'author', 124 | 'multiple' => true, 125 | 'data-options' => $_json_users_output, 126 | ], 127 | [ 128 | 'label' => __( 'Author', 'fakerpress' ), 129 | 'description' => __( 'Choose some users to be authors of posts generated.', 'fakerpress' ), 130 | ] 131 | ); 132 | 133 | $fields[] = new Field( 134 | 'heading', 135 | [ 136 | 'title' => __( 'Post Content', 'fakerpress' ), 137 | ], 138 | [] 139 | ); 140 | 141 | $fields[] = new Field( 142 | 'checkbox', 143 | [ 144 | 'id' => 'use_html', 145 | 'options' => [ 146 | [ 147 | 'text' => __( 'Use HTML on your randomized post content?', 'fakerpress' ), 148 | 'value' => 1, 149 | ], 150 | ], 151 | 'value' => 1, 152 | ], 153 | [ 154 | 'label' => __( 'Use HTML', 'fakerpress' ), 155 | ] 156 | ); 157 | 158 | $fields[] = new Field( 159 | 'range', 160 | [ 161 | 'id' => 'content_size', 162 | 'min' => 5, 163 | 'max' => 15, 164 | ], 165 | [ 166 | 'label' => __( 'Content Size', 'fakerpress' ), 167 | 'description' => __( 'How many paragraphs we are going to generate of content.', 'fakerpress' ), 168 | ] 169 | ); 170 | 171 | $_elements = array_merge( HTML::$sets['header'], HTML::$sets['list'], HTML::$sets['block'], HTML::$sets['self_close'] ); 172 | $fields[] = new Field( 173 | 'dropdown', 174 | [ 175 | 'id' => 'html_tags', 176 | 'multiple' => true, 177 | 'data-tags' => true, 178 | 'data-options' => $_elements, 179 | 'value' => implode( ',', $_elements ), 180 | ], 181 | [ 182 | 'label' => __( 'HTML tags', 'fakerpress' ), 183 | 'description' => __( 'Select the group of tags that can be selected to print on the Post Content', 'fakerpress' ), 184 | ] 185 | ); 186 | 187 | $fields[] = new Field( 188 | 'dropdown', 189 | [ 190 | 'id' => 'images_origin', 191 | 'multiple' => true, 192 | 'value' => implode( ',', wp_list_pluck( Module\Attachment::get_providers(), 'id' ) ), 193 | 'data-options' => Module\Attachment::get_providers(), 194 | ], 195 | [ 196 | 'label' => __( 'Image Providers', 'fakerpress' ), 197 | 'description' => __( 'Which image services will the generator use?', 'fakerpress' ), 198 | ] 199 | ); 200 | 201 | $fields[] = new Field( 202 | 'range', 203 | [ 204 | 'id' => 'excerpt_size', 205 | 'min' => 1, 206 | 'max' => 3, 207 | ], 208 | [ 209 | 'label' => __( 'Excerpt Size', 'fakerpress' ), 210 | 'description' => __( 'How many paragraphs we are going to generate of excerpt.', 'fakerpress' ), 211 | ] 212 | ); 213 | 214 | 215 | $fields[] = new Field( 216 | 'taxonomy', 217 | [ 218 | 'id' => 'taxonomy', 219 | ], 220 | [ 221 | 'label' => __( 'Taxonomy Field Rules', 'fakerpress' ), 222 | 'description' => __( 'Use the fields below to configure the rules for the Taxonomy and Terms selected', 'fakerpress' ), 223 | ] 224 | ); 225 | 226 | $fields[] = new Field( 227 | 'meta', 228 | [ 229 | 'id' => 'meta', 230 | 'config' => [ 231 | [ 232 | 'type' => 'attachment', 233 | 'name' => '_thumbnail_id', 234 | 'weight' => 75, 235 | 'store' => 'id', 236 | ], 237 | ], 238 | ], 239 | [ 240 | 'label' => __( 'Meta Field Rules', 'fakerpress' ), 241 | 'description' => __( 'Use the fields below to configure a set of rules for your generated Posts', 'fakerpress' ), 242 | ] 243 | ); 244 | 245 | 246 | ?> 247 |
248 |

get_title() ); ?>

249 | 250 |
251 | 252 | 253 | 254 | 255 | 256 | output( true ); } ?> 257 | 258 |
259 |
260 | 261 | 262 |
263 |
264 |
265 |
266 | -------------------------------------------------------------------------------- /src/templates/pages/settings.php: -------------------------------------------------------------------------------- 1 | 'erase_phrase', 14 | 'placeholder' => 'The cold never bothered me anyway!', 15 | ], 16 | [ 17 | 'label' => __( 'Erase faked data', 'fakerpress' ), 18 | 'description' => __( 'To erase all data generated type "Let it Go!", please back up your database before you proceed!', 'fakerpress' ), 19 | 'actions' => [ 20 | 'delete' => __( 'Delete!', 'fakerpress' ), 21 | ], 22 | ] 23 | ); 24 | 25 | ?> 26 |
27 |

get_title() ); ?>

28 | 29 |
30 | 31 | 32 | 33 | 34 | output( true ); ?> 35 | 36 | 37 |
38 |
39 |
40 | -------------------------------------------------------------------------------- /src/templates/pages/terms.php: -------------------------------------------------------------------------------- 1 | __( 'Quantity', 'fakerpress' ), 9 | 'description' => __( 'How many terms should be generated, use both fields to get a randomized number of terms within the given range.', 'fakerpress' ), 10 | ] 11 | ); 12 | 13 | $fields[] = new Field( 14 | 'range', 15 | [ 16 | 'id' => 'size', 17 | 'min' => 2, 18 | 'max' => 5, 19 | ], 20 | [ 21 | 'label' => __( 'Name Size', 'fakerpress' ), 22 | 'description' => __( 'What is the size of the Term name', 'fakerpress' ), 23 | ] 24 | ); 25 | 26 | $taxonomies = get_taxonomies( [ 'public' => true ], 'object' ); 27 | 28 | $_json_taxonomies_output = []; 29 | foreach ( $taxonomies as $key => $taxonomy ) { 30 | $_json_taxonomies_output[] = [ 31 | 'id' => $taxonomy->name, 32 | 'text' => $taxonomy->labels->name, 33 | ]; 34 | } 35 | 36 | $fields[] = new Field( 37 | 'dropdown', 38 | [ 39 | 'id' => 'taxonomies', 40 | 'multiple' => true, 41 | 'value' => 'category, post_tag', 42 | 'data-options' => $_json_taxonomies_output, 43 | ], 44 | [ 45 | 'label' => __( 'Taxonomies', 'fakerpress' ), 46 | 'description' => __( 'Group of taxonomies that the terms will be created within', 'fakerpress' ), 47 | ] 48 | ); 49 | 50 | if ( version_compare( $GLOBALS['wp_version'], '4.4-beta', '>=' ) ) { 51 | $fields[] = new Field( 52 | 'meta', 53 | [ 54 | 'id' => 'meta', 55 | ], 56 | [ 57 | 'label' => __( 'Meta Field Rules', 'fakerpress' ), 58 | 'description' => __( 'Use the fields below to configure a set of rules for your generated Terms', 'fakerpress' ), 59 | ] 60 | ); 61 | } 62 | 63 | ?> 64 |
65 |

get_title() ); ?>

66 |
67 | 68 | 69 | 70 | 71 | 72 | output( true ); } ?> 73 | 74 |
75 |
76 | 77 | 78 |
79 |
80 |
81 |
82 | -------------------------------------------------------------------------------- /src/templates/pages/users.php: -------------------------------------------------------------------------------- 1 | __( 'Quantity', 'fakerpress' ), 9 | 'description' => __( 'How many users should be generated, use both fields to get a randomized number of users within the given range.', 'fakerpress' ), 10 | ] 11 | ); 12 | 13 | $roles = get_editable_roles(); 14 | 15 | $_json_roles_output = []; 16 | foreach ( $roles as $role_name => $role_data ) { 17 | $_json_roles_output[] = [ 18 | 'id' => $role_name, 19 | 'text' => esc_attr( $role_data['name'] ), 20 | ]; 21 | } 22 | 23 | $fields[] = new Field( 24 | 'dropdown', 25 | [ 26 | 'id' => 'roles', 27 | 'multiple' => true, 28 | 'data-options' => $_json_roles_output, 29 | ], 30 | [ 31 | 'label' => __( 'Roles', 'fakerpress' ), 32 | 'description' => __( 'Sampling roles to be used', 'fakerpress' ), 33 | ] 34 | ); 35 | 36 | $fields[] = new Field( 37 | 'heading', 38 | [ 39 | 'title' => __( 'User Description', 'fakerpress' ), 40 | ], 41 | [] 42 | ); 43 | 44 | $fields[] = new Field( 45 | 'range', 46 | [ 47 | 'id' => 'description_size', 48 | 'min' => 1, 49 | 'max' => 5, 50 | ], 51 | [ 52 | 'label' => __( 'Description Size', 'fakerpress' ), 53 | 'description' => __( 'How many paragraphs we are going to generate of description.', 'fakerpress' ), 54 | ] 55 | ); 56 | 57 | $fields[] = new Field( 58 | 'checkbox', 59 | [ 60 | 'id' => 'use_html', 61 | 'options' => [ 62 | [ 63 | 'text' => __( 'Use HTML on your randomized user description?', 'fakerpress' ), 64 | 'value' => 1, 65 | ], 66 | ], 67 | 'value' => 1, 68 | ], 69 | [ 70 | 'label' => __( 'Use HTML', 'fakerpress' ), 71 | ] 72 | ); 73 | 74 | $_elements = array_merge( [ 'h3', 'h4', 'h5', 'h6', 'p' ] ); 75 | $fields[] = new Field( 76 | 'dropdown', 77 | [ 78 | 'id' => 'html_tags', 79 | 'multiple' => true, 80 | 'data-options' => $_elements, 81 | 'data-tags' => true, 82 | 'value' => implode( ',', $_elements ), 83 | ], 84 | [ 85 | 'label' => __( 'HTML tags', 'fakerpress' ), 86 | 'description' => __( 'Select the group of tags that can be selected to print on the User Description.', 'fakerpress' ), 87 | ] 88 | ); 89 | 90 | $fields[] = new Field( 91 | 'meta', 92 | [ 93 | 'id' => 'meta', 94 | ], 95 | [ 96 | 'label' => __( 'Meta Field Rules', 'fakerpress' ), 97 | 'description' => __( 'Use the fields below to configure a set of rules for your generated users', 'fakerpress' ), 98 | ] 99 | ); 100 | ?> 101 |
102 |

get_title() ); ?>

103 | 104 |
105 | 106 | 107 | 108 | 109 | 110 | output( true ); 113 | } 114 | ?> 115 | 116 |
117 |
118 | 119 | 120 |
121 |
122 |
123 |
124 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const {dirname, basename, extname} = require('path'); 2 | const {readdirSync, statSync, existsSync} = require('fs'); 3 | 4 | /** 5 | * The default configuration coming from the @wordpress/scripts package. 6 | * Customized following the "Advanced Usage" section of the documentation: 7 | * See: https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/#advanced-usage 8 | */ 9 | const defaultConfig = require('@wordpress/scripts/config/webpack.config'); 10 | 11 | const { 12 | createTECLegacyJs, 13 | createTECPostCss, 14 | createTECLegacyBlocksFrontendPostCss, 15 | createTECPackage, 16 | compileCustomEntryPoints, 17 | exposeEntry, 18 | doNotPrefixSVGIdsClasses, 19 | WindowAssignPropertiesPlugin, 20 | } = require('@stellarwp/tyson'); 21 | 22 | /** 23 | * Compile a list of entry points to be compiled to the format used by WebPack to define multiple entry points. 24 | * This is akin to the compilation system used for multi-page applications. 25 | * See: https://webpack.js.org/concepts/entry-points/#multi-page-application 26 | */ 27 | const customEntryPoints = compileCustomEntryPoints({ 28 | /** 29 | * All existing Javascript files will be compiled to ES6, most will not be changed at all, 30 | * minified and cleaned up. 31 | * This is mostly a pass-thru with the additional benefit that the compiled packages will be 32 | * exposed on the `window.fakerpress` object. 33 | * E.g. the `src/resources/js/admin-ignored-events.js` file will be compiled to 34 | * `/build/js/admin-ignored-events.js` and exposed on `window.fakerpress.adminIgnoredEvents`. 35 | */ 36 | '/src/resources/js': createTECLegacyJs('fakerpress'), 37 | 38 | /** 39 | * Compile, recursively, the PostCSS file using PostCSS nesting rules. 40 | * By default, the `@wordpress/scripts` configuration would compile files using the CSS 41 | * nesting syntax (https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting) where 42 | * the `&` symbol indicates the parent element. 43 | * The PostCSS syntax followed in TEC files will instead use the `&` symbol to mean "this element". 44 | * Handling this correctly requires adding a PostCSS processor specific to the PostCSS files that 45 | * will handle the nesting correctly. 46 | * Note the plugin will need to specify the following development dependencies: postcss-nested, postcss-preset-env, 47 | * postcss-mixins, postcss-import, postcss-custom-media. 48 | */ 49 | '/src/resources/pcss': createTECPostCss('fakerpress'), 50 | 51 | /** 52 | * This deals with packages written following modern module-based approaches. 53 | * These packages are usually not Blocks and require `@wordpress/scripts` to be explicitly 54 | * instructed about them to compile correctly. 55 | * To avoid having to list each package, here the configuration schema is used to recursively 56 | * pick them up and namespace them. 57 | */ 58 | '/src/resources/packages': createTECPackage('fakerpress'), 59 | }, defaultConfig); 60 | 61 | /** 62 | * Following are static entry points, to be included in the build non-recursively. 63 | * These are built following a modern module approach where the root `index.js` file 64 | * will include the whole module. 65 | */ 66 | 67 | 68 | /** 69 | * Prepends a loader for SVG files that will be applied after the default one. Loaders are applied 70 | * in a LIFO queue in WebPack. 71 | * By default, `@wordpress/scripts` uses `@svgr/webpack` to handle SVG files and, together with it, 72 | * the default SVGO (package `svgo/svgo-loader`) configuration that includes the `prefixIds` plugin. 73 | * To avoid `id` and `class` attribute conflicts, the `prefixIds` plugin would prefix all `id` and 74 | * `class` attributes in SVG tags with a generated prefix. This would break TEC classes (already 75 | * namespaced) so here we prepend a rule to handle SVG files in the `src/modules` directory by 76 | * disabling the `prefixIds` plugin. 77 | */ 78 | doNotPrefixSVGIdsClasses(defaultConfig); 79 | 80 | /** 81 | * Finally the customizations are merged with the default WebPack configuration. 82 | */ 83 | module.exports = { 84 | ...defaultConfig, 85 | ...{ 86 | entry: (buildType) => { 87 | const defaultEntryPoints = defaultConfig.entry(buildType); 88 | return { 89 | ...defaultEntryPoints, ...customEntryPoints, 90 | }; 91 | }, 92 | output: { 93 | ...defaultConfig.output, 94 | ...{ 95 | enabledLibraryTypes: ['window'], 96 | }, 97 | }, 98 | plugins: [ 99 | ...defaultConfig.plugins, 100 | new WindowAssignPropertiesPlugin(), 101 | ], 102 | }, 103 | }; 104 | --------------------------------------------------------------------------------