├── inc ├── test.xls ├── test_pro.xls ├── upgrade.php ├── test.csv ├── test_pro.csv ├── helpers.php ├── integration.php ├── errors-handler.php ├── excel │ └── oleread.php ├── admin-page.php └── creator.php ├── uninstall.php ├── .gitignore ├── assets ├── images │ └── batchcreatepro.jpg ├── jquery-ui │ ├── images │ │ ├── animated-overlay.gif │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_228ef1_256x240.png │ │ ├── ui-icons_ef8c08_256x240.png │ │ ├── ui-icons_ffd27a_256x240.png │ │ ├── ui-icons_ffffff_256x240.png │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ └── ui-bg_highlight-soft_75_ffe45c_1x100.png │ ├── jquery.ui.progressbar.js │ ├── jquery-ui-1.10.3.custom.min.css │ └── jquery-ui-1.10.3.custom.css └── css │ └── icons.css ├── .gitmodules ├── sql.txt ├── package.json ├── dev-README.md ├── changelog.txt ├── Gruntfile.js ├── admin ├── tables │ └── queue-table.php └── pages │ └── network-main-page.php ├── batch-create.php ├── model └── model.php ├── README.md ├── languages └── incsub_batch_create.pot └── license.txt /inc/test.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/inc/test.xls -------------------------------------------------------------------------------- /inc/test_pro.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/inc/test_pro.xls -------------------------------------------------------------------------------- /uninstall.php: -------------------------------------------------------------------------------- 1 | create_schema(); 6 | } -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "externals"] 2 | path = externals 3 | url = git@bitbucket.org:incsub/wpmudev-dashboard-notification.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /assets/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/batch-create/master/assets/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /inc/test.csv: -------------------------------------------------------------------------------- 1 | demoblogname1,Demo Blog Title 1,username1,userpass1,useremail@domain.com,administrator 2 | demoblogname2,Demo Blog Title 2,username2,userpass2,useremail2@domain.com,editor 3 | -------------------------------------------------------------------------------- /inc/test_pro.csv: -------------------------------------------------------------------------------- 1 | demoblogname1,Demo Blog Title 1,username,userpass1,username@domain.com,administrator,1,permanent 2 | demoblogname2,Demo Blog Title 2,username,userpass2,username@domain.com,administrator,2,2016-03-21 -------------------------------------------------------------------------------- /sql.txt: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS `wp_batch_create_queue` ( 2 | `batch_create_ID` bigint(20) unsigned NOT NULL auto_increment, 3 | `batch_create_site` bigint(20), 4 | `batch_create_blog_name` varchar(255) NOT NULL default 'null', 5 | `batch_create_blog_title` varchar(255) NOT NULL default 'null', 6 | `batch_create_user_name` varchar(255) NOT NULL default 'null', 7 | `batch_create_user_pass` varchar(255) NOT NULL default 'null', 8 | `batch_create_user_email` varchar(255) NOT NULL default 'null', 9 | `batch_create_user_role` varchar(255) NOT NULL default 'null', 10 | PRIMARY KEY (`batch_create_ID`) 11 | ) ENGINE=MyISAM; 12 | -------------------------------------------------------------------------------- /assets/css/icons.css: -------------------------------------------------------------------------------- 1 | #icon-origin { 2 | background: transparent url( '../images/icon32.png' ) no-repeat ; 3 | } 4 | 5 | #toplevel_page_origin_main_page .wp-menu-image, 6 | #toplevel_page_origin_network_page .wp-menu-image { 7 | background: transparent url( '../images/icons.png' ) no-repeat 0px -27px; 8 | } 9 | 10 | #toplevel_page_origin_main_page.wp-has-current-submenu .wp-menu-image, 11 | #toplevel_page_origin_main_page:hover .wp-menu-image, 12 | #toplevel_page_origin_network_page.wp-has-current-submenu .wp-menu-image, 13 | #toplevel_page_origin_network_page:hover .wp-menu-image { 14 | background: transparent url( '../images/icons.png' ) no-repeat 0px -0px; 15 | } 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "batch-create", 3 | "version": "1.5.2", 4 | "main": "batch-create.php", 5 | "projectEditUrl": "https://premium.wpmudev.org/wp-admin/edit.php?post_type=project&page=projects-manage&manage_files=84", 6 | "description": "", 7 | "scripts": { 8 | "build": "grunt build" 9 | }, 10 | "dependencies": {}, 11 | "devDependencies": { 12 | "grunt": "~0.4.5", 13 | "grunt-checktextdomain": "^0.1.1", 14 | "grunt-contrib-clean": "~0.5.0", 15 | "grunt-contrib-compress": "~0.8.0", 16 | "grunt-contrib-copy": "~0.5.0", 17 | "grunt-contrib-jshint": "^1.0.0", 18 | "grunt-contrib-uglify": "^1.0.1", 19 | "grunt-contrib-watch": "^1.0.0", 20 | "grunt-exec": "~0.4.5", 21 | "grunt-open": "^0.2.3", 22 | "grunt-phpunit": "^0.3.6", 23 | "grunt-potomo": "~2.1.0", 24 | "grunt-search": "^0.1.8", 25 | "grunt-wp-i18n": "~0.5.0", 26 | "load-grunt-tasks": "~0.2.0" 27 | }, 28 | "author": "WPMU DEV", 29 | "license": "GPLv2" 30 | } 31 | -------------------------------------------------------------------------------- /dev-README.md: -------------------------------------------------------------------------------- 1 | # Batch Create 2 | 3 | ## Development guide 4 | 5 | ### Branches 6 | There are two main branches: 7 | 8 | * `development`: Every development work should be done here first 9 | * `master`: Whenever a new version is ready, merge `development` branch into this one and push 10 | 11 | ### Development workflow 12 | 13 | Batch Create contains a few automated tasks that helps the developer to make faster and less buggy releases. 14 | 15 | #### Requirements: 16 | 17 | 1. Install nodejs: [https://github.com/joyent/node/wiki/installing-node.js-via-package-manager] 18 | 2. Install Grunt globally `sudo npm install -g grunt` 19 | 3. Execute `git submodule update --init --recursive` to download every submodule 20 | 21 | #### Dependencies installation 22 | 23 | Batch Create requires a few node dependencies for development. Use `npm install` to install all of them. 24 | 25 | #### Releasing versions 26 | 27 | 1. Make sure that the version in `batch-create.php` matches with the version in `package.json`, otherwise the build will fail. 28 | 2. Update all Git submodules with `git submodule update --remote` 29 | 3. Now execute `npm run build`. A new folder called `build` will be created where you can grab the zip file for the new version. 30 | 4. Language files, JS Lint and text domains verification are done during the execution of this script so developer doesn't need to worry about these tasks. 31 | 32 | Don't forget to create a new tag in Git! 33 | -------------------------------------------------------------------------------- /inc/helpers.php: -------------------------------------------------------------------------------- 1 | batch_create_ID; 36 | 37 | $extend = get_metadata( 'batch_create_queue', $queue_id, 'pro_site_extend', true ); 38 | $level = get_metadata( 'batch_create_queue', $queue_id, 'pro_site_level', true ); 39 | 40 | if ( $level && $extend ) { 41 | $extend = $extend < 9999999999 ? $extend - time() : $extend; 42 | $psts->extend( $blog_id, $extend, __('Manual', INCSUB_BATCH_CREATE_LANG_DOMAIN), $level ); 43 | } 44 | } 45 | add_action( 'batch_create_blog_created', 'batch_create_set_pro_status', 10, 2 ); 46 | 47 | function batch_create_add_pro_sites_columns( $columns ) { 48 | $columns['level'] = __( 'Pro Site Level', INCSUB_BATCH_CREATE_LANG_DOMAIN ); 49 | $columns['extend'] = __( 'Until', INCSUB_BATCH_CREATE_LANG_DOMAIN ); 50 | return $columns; 51 | } 52 | add_filter( 'batch_create_queue_columns', 'batch_create_add_pro_sites_columns' ); 53 | 54 | function batch_create_display_pro_sites_columns( $content, $column, $item ) { 55 | if ( $column == 'level' ) { 56 | $level = get_metadata( 'batch_create_queue', $item['batch_create_ID'], 'pro_site_level', true ); 57 | return $level ? $level : __( 'Not Pro', INCSUB_BATCH_CREATE_LANG_DOMAIN ); 58 | } 59 | if ( $column == 'extend' ) { 60 | $extend = get_metadata( 'batch_create_queue', $item['batch_create_ID'], 'pro_site_extend', true ); 61 | $extend = is_numeric( $extend ) && $extend < 9999999999 ? date_i18n( get_option( 'date_format' ), $extend ) : __( 'Permanent', INCSUB_BATCH_CREATE_LANG_DOMAIN ); 62 | return $extend; 63 | } 64 | } 65 | add_filter( 'batch_create_display_queue_column', 'batch_create_display_pro_sites_columns', 10, 3 ); 66 | 67 | function batch_create_add_pro_sites_instructions() { 68 | $test_xls_url = INCSUB_BATCH_CREATE_PLUGIN_URL . 'inc/test_pro.xls'; 69 | $test_csv_url = INCSUB_BATCH_CREATE_PLUGIN_URL . 'inc/test_pro.csv'; 70 | ?> 71 |

72 |

73 |

this .xls or this .csv file and use it as a template to create your batch file with Pro Sites columns.', INCSUB_BATCH_CREATE_LANG_DOMAIN ), $test_xls_url, $test_csv_url ); ?>

74 |

75 | 27 |
28 |

%s plugin error: %s', INCSUB_BATCH_CREATE_LANG_DOMAIN ), $plugin_data['Name'], $message ); ?> 29 |

30 | 102 |

103 | 113 |

114 | 132 |
137 | " ) 42 | .appendTo( this.element ); 43 | 44 | this._refreshValue(); 45 | }, 46 | 47 | _destroy: function() { 48 | this.element 49 | .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 50 | .removeAttr( "role" ) 51 | .removeAttr( "aria-valuemin" ) 52 | .removeAttr( "aria-valuemax" ) 53 | .removeAttr( "aria-valuenow" ); 54 | 55 | this.valueDiv.remove(); 56 | }, 57 | 58 | value: function( newValue ) { 59 | if ( newValue === undefined ) { 60 | return this.options.value; 61 | } 62 | 63 | this.options.value = this._constrainedValue( newValue ); 64 | this._refreshValue(); 65 | }, 66 | 67 | _constrainedValue: function( newValue ) { 68 | if ( newValue === undefined ) { 69 | newValue = this.options.value; 70 | } 71 | 72 | this.indeterminate = newValue === false; 73 | 74 | // sanitize value 75 | if ( typeof newValue !== "number" ) { 76 | newValue = 0; 77 | } 78 | 79 | return this.indeterminate ? false : 80 | Math.min( this.options.max, Math.max( this.min, newValue ) ); 81 | }, 82 | 83 | _setOptions: function( options ) { 84 | // Ensure "value" option is set after other values (like max) 85 | var value = options.value; 86 | delete options.value; 87 | 88 | this._super( options ); 89 | 90 | this.options.value = this._constrainedValue( value ); 91 | this._refreshValue(); 92 | }, 93 | 94 | _setOption: function( key, value ) { 95 | if ( key === "max" ) { 96 | // Don't allow a max less than min 97 | value = Math.max( this.min, value ); 98 | } 99 | 100 | this._super( key, value ); 101 | }, 102 | 103 | _percentage: function() { 104 | return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 105 | }, 106 | 107 | _refreshValue: function() { 108 | var value = this.options.value, 109 | percentage = this._percentage(); 110 | 111 | this.valueDiv 112 | .toggle( this.indeterminate || value > this.min ) 113 | .toggleClass( "ui-corner-right", value === this.options.max ) 114 | .width( percentage.toFixed(0) + "%" ); 115 | 116 | this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 117 | 118 | if ( this.indeterminate ) { 119 | this.element.removeAttr( "aria-valuenow" ); 120 | if ( !this.overlayDiv ) { 121 | this.overlayDiv = $( "
" ).appendTo( this.valueDiv ); 122 | } 123 | } else { 124 | this.element.attr({ 125 | "aria-valuemax": this.options.max, 126 | "aria-valuenow": value 127 | }); 128 | if ( this.overlayDiv ) { 129 | this.overlayDiv.remove(); 130 | this.overlayDiv = null; 131 | } 132 | } 133 | 134 | if ( this.oldValue !== value ) { 135 | this.oldValue = value; 136 | this._trigger( "change" ); 137 | } 138 | if ( value === this.options.max ) { 139 | this._trigger( "complete" ); 140 | } 141 | } 142 | }); 143 | })( jQuery ); -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | Plugin Name: Batch Create 2 | Author: WPMUDEV 3 | 4 | Change Log: 5 | ---------------------------------------------------------------------- 6 | ---------------------------------------------------------------------- 7 | 8 | 1.5.2 - 2016-12-13 9 | ---------------------------------------------------------------------- 10 | - Fixed: Wrong textdomain in pot file 11 | - Fixed: Blog title language encoding 12 | - Fixed: Users with a different role than Administrator were not created in some cases 13 | 14 | 1.5.1 - 2015-10-26 15 | ---------------------------------------------------------------------- 16 | - Fixed: New users notifications were not sent since WP 4.3.1 17 | - Fixed warnings 18 | 19 | 1.5 - 2014-09-11 Ignacio Cruz 20 | ---------------------------------------------------------------------- 21 | - Enhancement: CSV,XLS files now accept Blog IDs and not only domains 22 | - Enhancement: UI Improvement 23 | 24 | 1.4 - 2014-03-28 Ignacio Cruz 25 | ---------------------------------------------------------------------- 26 | - Added: Pro Sites Integration 27 | - Added: New hooks. 28 | - Other minor improvements 29 | 30 | 1.3.3 - 2013-09-30 Ignacio Cruz 31 | ---------------------------------------------------------------------- 32 | - Fixed: Users were being added to main blog with the same role 33 | 34 | 1.3.2 - 2013-09-23 Ignacio Cruz 35 | ---------------------------------------------------------------------- 36 | - Users were not being added to existing blogs 37 | 38 | 1.3.1 - 2013-09-11 Ignacio Cruz 39 | ---------------------------------------------------------------------- 40 | - Fixed error when creating upload folder 41 | 42 | 1.3 - 2013-09-11 Ignacio Cruz 43 | ---------------------------------------------------------------------- 44 | - Plugin recoded 45 | - Added a new table where the queue is displayed 46 | - Better admin styles 47 | - Fixed problem with spanish characters 48 | - Added link to download a CSV 49 | 50 | 1.2.3 - 11/25/2011 - Vladislav Bailovic 51 | ---------------------------------------------------------------------- 52 | - More persistent queue processing. 53 | - Additional checks for files padded with empty columns. 54 | 55 | 56 | 1.2.2 - 11/16/2011 - Vladislav Bailovic 57 | ---------------------------------------------------------------------- 58 | - Enforcing time limit to prevent script timeout issues. 59 | 60 | 61 | 1.2.1 - 10/23/2011 - Vladislav Bailovic 62 | ---------------------------------------------------------------------- 63 | - Fixed parsing for supported CSV file formats. 64 | 65 | 66 | 1.2 - 10/22/2011 - Vladislav Bailovic 67 | ---------------------------------------------------------------------- 68 | - Removing source files as soon as they're no longer needed. 69 | - Manual removing of any remaining source files 70 | - Improved logging 71 | - Added log viewing interface 72 | 73 | 74 | 1.1.5 - 10/19/2011 - Vladislav Bailovic 75 | ---------------------------------------------------------------------- 76 | - Applied whitespace trim for roles fix. 77 | 78 | 79 | 1.1.4 - 09/25/2011 - Vladislav Bailovic 80 | ---------------------------------------------------------------------- 81 | - Applied lowercasing role fix. 82 | 83 | 84 | 1.1.3 - 05/15/2011 - Aaron Edwards 85 | ---------------------------------------------------------------------- 86 | - Make created blogs default to public 87 | 88 | 89 | 1.1.2 - 05/15/2011 - Vladislav Bailovic 90 | ---------------------------------------------------------------------- 91 | - Added log file clearing option. 92 | 93 | 1.1.1 - 04/20/2011 - Vladislav Bailovic 94 | ---------------------------------------------------------------------- 95 | - Fix for adding users with roles. 96 | - Fix for adding existing users. 97 | - Fix for Excel processing. 98 | - Fix for 404 redirection. 99 | - Fix for identical emails for different users in queue. 100 | - Fix for error handling. 101 | - Added adding users to main site. 102 | - Added basic blog_name sanitization. 103 | - Added support for batch files with header rows. 104 | 105 | 1.1 - 01/26/2010 106 | ---------------------------------------------------------------------- 107 | - New feature: allows addition of users to existing blogs 108 | - New feature: allows choosing the role of users 109 | - Enhancement: support for .csv and .xls files 110 | - Enhancement: internationalization 111 | - Enhancement: compatibility with WordPress 2.8 - 3.1 112 | - Enhancement: log plugin actions in a file when queue is processed 113 | - Enhancement: admin page rewrite so that it works correctly without js enabled 114 | - Enhancement: rewrite code per our coding standards 115 | - Enhancement: example files 116 | - Enhancement: updated install and sql files 117 | - Enhancement: better instructions on admin page 118 | 119 | 1.0.1 - 06/01/2010 120 | ---------------------------------------------------------------------- 121 | - 3.0+ compatibility update 122 | 123 | 1.0.0 - 06/22/2009 124 | ---------------------------------------------------------------------- 125 | - Initial Release. 126 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | require('load-grunt-tasks')(grunt); 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | 6 | checktextdomain: { 7 | options:{ 8 | report_missing: false, 9 | text_domain: 'incsub_batch_create', 10 | keywords: [ 11 | '__:1,2d', 12 | '_e:1,2d', 13 | '_x:1,2c,3d', 14 | 'esc_html__:1,2d', 15 | 'esc_html_e:1,2d', 16 | 'esc_html_x:1,2c,3d', 17 | 'esc_attr__:1,2d', 18 | 'esc_attr_e:1,2d', 19 | 'esc_attr_x:1,2c,3d', 20 | '_ex:1,2c,3d', 21 | '_n:1,2,4d', 22 | '_nx:1,2,4c,5d', 23 | '_n_noop:1,2,3d', 24 | '_nx_noop:1,2,3c,4d' 25 | ] 26 | }, 27 | files: { 28 | src: [ 29 | '**/*.php', // Include all files 30 | '!node_modules/**', // Exclude node_modules/ 31 | '!tests/**', // Exclude tests/ 32 | '!admin/assets/shared-ui/**', // Exclude WPMU DEV Shared UI 33 | '!externals/**' 34 | ], 35 | expand: true 36 | } 37 | }, 38 | 39 | copy: { 40 | main: { 41 | src: [ 42 | '**', 43 | '!npm-debug.log', 44 | '!node_modules/**', 45 | '!build/**', 46 | '!bin/**', 47 | '!.git/**', 48 | '!Gruntfile.js', 49 | '!package.json', 50 | '!.gitignore', 51 | '!.gitmodules', 52 | '!sourceMap.map', 53 | '!phpunit.xml.dist', 54 | '!travis.yml', 55 | '!tests/**', 56 | '!**/Gruntfile.js', 57 | '!**/package.json', 58 | '!**/README.md', 59 | '!lite-vs-pro.txt', 60 | '!composer.json', 61 | '!vendor/**', 62 | '!tmp/**', 63 | '!**/*~' 64 | ], 65 | dest: 'build/<%= pkg.name %>/' 66 | } 67 | }, 68 | 69 | // Generate POT files. 70 | makepot: { 71 | options: { 72 | type: 'wp-plugin', 73 | domainPath: 'languages', 74 | potHeaders: { 75 | 'report-msgid-bugs-to': 'https://wpmudev.org', 76 | 'language-team': 'LANGUAGE ' 77 | } 78 | }, 79 | dist: { 80 | options: { 81 | potFilename: 'incsub_batch_create.pot', 82 | exclude: [ 83 | 'tests/.*', 84 | 'node_modules/.*', 85 | 'includes/external/*' 86 | ] 87 | } 88 | } 89 | }, 90 | 91 | clean: { 92 | main: ['build/*'] 93 | }, 94 | 95 | compress: { 96 | main: { 97 | options: { 98 | mode: 'zip', 99 | archive: './build/<%= pkg.name %>-<%= pkg.version %>.zip' 100 | }, 101 | expand: true, 102 | cwd: 'build/<%= pkg.name %>/', 103 | src: ['**/*'], 104 | dest: '<%= pkg.name %>/' 105 | } 106 | }, 107 | 108 | search: { 109 | files: { 110 | src: ['<%= pkg.main %>'] 111 | }, 112 | options: { 113 | logFile: 'tmp/log-search.log', 114 | searchString: /^[ \t\/*#@]*Version:(.*)$/mig, 115 | onMatch: function(match) { 116 | var regExp = /^[ \t\/*#@]*Version:(.*)$/mig; 117 | var groupedMatches = regExp.exec( match.match ); 118 | var versionFound = groupedMatches[1].trim(); 119 | if ( versionFound != grunt.file.readJSON('package.json').version ) { 120 | grunt.fail.fatal("Plugin version does not match with package.json version. Please, fix."); 121 | } 122 | }, 123 | onComplete: function( matches ) { 124 | if ( ! matches.numMatches ) { 125 | if ( ! grunt.file.readJSON('package.json').main ) { 126 | grunt.fail.fatal("main field is not defined in package.json. Please, add the plugin main file on that field."); 127 | } 128 | else { 129 | grunt.fail.fatal("Version Plugin header not found in " + grunt.file.readJSON('package.json').main + " file or the file does not exist" ); 130 | } 131 | 132 | } 133 | } 134 | } 135 | }, 136 | 137 | open: { 138 | dev : { 139 | path: '<%= pkg.projectEditUrl %>', 140 | app: 'Google Chrome' 141 | } 142 | } 143 | }); 144 | 145 | grunt.loadNpmTasks('grunt-search'); 146 | 147 | grunt.registerTask('version-compare', [ 'search' ] ); 148 | 149 | grunt.registerTask('build', [ 150 | 'version-compare', 151 | 'clean', 152 | 'checktextdomain', 153 | 'makepot', 154 | 'copy', 155 | 'compress' 156 | ]); 157 | }; 158 | -------------------------------------------------------------------------------- /admin/tables/queue-table.php: -------------------------------------------------------------------------------- 1 | 'item', 14 | 'plural' => 'items', 15 | 'ajax' => false 16 | ) ); 17 | 18 | } 19 | 20 | function column_default($item, $column) { 21 | return apply_filters( 'batch_create_display_queue_column', '', $column, $item ); 22 | } 23 | 24 | function column_cb($item){ 25 | return sprintf( 26 | '', 27 | 'item', 28 | $item['batch_create_ID'] 29 | ); 30 | } 31 | 32 | function column_blogname( $item ) { 33 | 34 | $actions = array( 35 | 'delete' => sprintf( __( '%s', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 36 | esc_url( add_query_arg( array( 'action' => 'delete', 'item' => absint( $item['batch_create_ID'] ) ) ) ), 37 | __( 'Delete', INCSUB_BATCH_CREATE_LANG_DOMAIN ) 38 | ) 39 | ); 40 | 41 | return $item['batch_create_blog_name'] . $this->row_actions( $actions ); 42 | } 43 | 44 | function column_blogtitle( $item ) { 45 | return $item['batch_create_blog_title']; 46 | } 47 | 48 | function column_username( $item ) { 49 | return $item['batch_create_user_name']; 50 | } 51 | 52 | function column_userpass( $item ) { 53 | return $item['batch_create_user_pass']; 54 | } 55 | 56 | function column_user_email( $item ) { 57 | return $item['batch_create_user_email']; 58 | } 59 | 60 | function column_user_role( $item ) { 61 | return $item['batch_create_user_role']; 62 | } 63 | 64 | function column_meta( $item ) { 65 | $meta = batch_create_get_queue_meta( $item['batch_create_ID'] ); 66 | if ( ! empty ( $meta ) && is_array( $meta ) ) { 67 | foreach( $meta as $meta_key => $value ) { 68 | echo '' . $meta_key . ''; 69 | ?> 70 |
71 | '', //Render a checkbox instead of text 78 | 'blogname' => __( 'Blog name/Blog ID', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 79 | 'blogtitle' => __( 'Blog title', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 80 | 'username' => __( 'Username', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 81 | 'userpass' => __( 'User password', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 82 | 'user_email' => __( 'User email', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 83 | 'user_role' => __( 'User role', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 84 | 'meta' => __( 'Additional options', INCSUB_BATCH_CREATE_LANG_DOMAIN ) 85 | )); 86 | 87 | if ( ! isset( $_GET['display_meta'] ) ) 88 | unset( $columns['meta'] ); 89 | 90 | return $columns; 91 | } 92 | 93 | function get_bulk_actions() { 94 | $actions = array( 95 | 'delete' => __( 'Delete items', INCSUB_BATCH_CREATE_LANG_DOMAIN ) 96 | ); 97 | return $actions; 98 | } 99 | 100 | function process_bulk_action() { 101 | 102 | if( 'delete' === $this->current_action() ) { 103 | 104 | $model = batch_create_get_model(); 105 | if ( ! isset( $_POST['item'] ) && isset( $_GET['item'] ) ) { 106 | $model->delete_queue_item( absint( $_GET['item'] ) ); 107 | } 108 | else { 109 | $items = $_POST['item']; 110 | if ( ! empty( $items ) ) { 111 | foreach ( $items as $item ) { 112 | $model->delete_queue_item( absint( $item ) ); 113 | } 114 | } 115 | } 116 | 117 | ?> 118 |
119 |

120 |
121 | get_columns(); 132 | $hidden = array(); 133 | $sortable = array(); 134 | 135 | $this->_column_headers = array($columns, $hidden, $sortable); 136 | 137 | $this->process_bulk_action(); 138 | $current_page = $this->get_pagenum(); 139 | 140 | $model = batch_create_get_model(); 141 | 142 | $items = $model->get_queue_items( $current_page, $per_page ); 143 | 144 | $this->items = $items; 145 | 146 | $total = $model->count_queue_items(); 147 | $this->set_pagination_args( array( 148 | 'total_items' => $model->count_queue_items(), 149 | 'per_page' => $per_page, 150 | 'total_pages' => ceil( $total / $per_page ) 151 | ) ); 152 | } 153 | } -------------------------------------------------------------------------------- /batch-create.php: -------------------------------------------------------------------------------- 1 | set_globals(); 31 | 32 | $this->includes(); 33 | 34 | add_action( 'init', array( &$this, 'maybe_upgrade' ) ); 35 | 36 | add_action( 'init', array( &$this, 'init_plugin' ) ); 37 | 38 | add_action( 'plugins_loaded', array( &$this, 'load_text_domain' ) ); 39 | 40 | register_activation_hook( __FILE__, array( $this, 'activate' ) ); 41 | register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) ); 42 | 43 | } 44 | 45 | public function activate() { 46 | $model = batch_create_get_model(); 47 | $model->create_schema(); 48 | update_site_option( self::$version_option_slug, INCSUB_BATCH_CREATE_VERSION ); 49 | } 50 | 51 | public function deactivate() { 52 | delete_site_option( self::$version_option_slug ); 53 | } 54 | 55 | 56 | 57 | 58 | /** 59 | * Set the plugin constants 60 | */ 61 | private function set_globals() { 62 | 63 | //TODO: Change the constant names 64 | 65 | // Basics 66 | define( 'INCSUB_BATCH_CREATE_VERSION', '1.5.1' ); 67 | define( 'INCSUB_BATCH_CREATE_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); 68 | define( 'INCSUB_BATCH_CREATE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 69 | define( 'INCSUB_BATCH_CREATE_PLUGIN_FILE_DIR', plugin_dir_path( __FILE__ ) . 'batch-create.php' ); 70 | 71 | // Language domain 72 | define( 'INCSUB_BATCH_CREATE_LANG_DOMAIN', 'incsub_batch_create' ); 73 | 74 | // URLs 75 | define( 'INCSUB_BATCH_CREATE_ASSETS_URL', INCSUB_BATCH_CREATE_PLUGIN_URL . 'assets/' ); 76 | 77 | // Dirs 78 | define( 'INCSUB_BATCH_CREATE_ADMIN_DIR', INCSUB_BATCH_CREATE_PLUGIN_DIR . 'admin/' ); 79 | define( 'INCSUB_BATCH_CREATE_MODEL_DIR', INCSUB_BATCH_CREATE_PLUGIN_DIR . 'model/' ); 80 | define( 'INCSUB_BATCH_CREATE_INCLUDES_DIR', INCSUB_BATCH_CREATE_PLUGIN_DIR . 'inc/' ); 81 | 82 | } 83 | 84 | /** 85 | * Include files needed 86 | */ 87 | private function includes() { 88 | // Model 89 | require_once( INCSUB_BATCH_CREATE_MODEL_DIR . 'model.php' ); 90 | 91 | // Libraries 92 | require_once( INCSUB_BATCH_CREATE_INCLUDES_DIR . 'admin-page.php' ); 93 | require_once( INCSUB_BATCH_CREATE_INCLUDES_DIR . 'errors-handler.php' ); 94 | require_once( INCSUB_BATCH_CREATE_INCLUDES_DIR . 'helpers.php' ); 95 | require_once( INCSUB_BATCH_CREATE_INCLUDES_DIR . 'integration.php' ); 96 | 97 | // Admin Pages 98 | require_once( INCSUB_BATCH_CREATE_ADMIN_DIR . 'pages/network-main-page.php' ); 99 | require_once( INCSUB_BATCH_CREATE_ADMIN_DIR . 'tables/queue-table.php' ); 100 | 101 | global $wpmudev_notices; 102 | $wpmudev_notices[] = array( 'id'=> 84,'name'=> 'Batch Create', 'screens' => array( 'settings_page_batch-create-menu-network' ) ); 103 | include_once( 'externals/wpmudev-dash-notification.php' ); 104 | } 105 | 106 | /** 107 | * Upgrade the plugin when a new version is uploaded 108 | */ 109 | public function maybe_upgrade() { 110 | $current_version = get_site_option( self::$version_option_slug ); 111 | 112 | if ( $current_version === INCSUB_BATCH_CREATE_VERSION ) 113 | return; 114 | 115 | if ( $current_version === false ) { 116 | $this->activate(); 117 | return; 118 | } 119 | 120 | // For the second version, we're just saving the version in DB 121 | if ( version_compare( $current_version, '1.4', '<' ) ) { 122 | require_once( INCSUB_BATCH_CREATE_INCLUDES_DIR . 'upgrade.php' ); 123 | batch_create_upgrade_14(); 124 | } 125 | 126 | update_site_option( self::$version_option_slug, INCSUB_BATCH_CREATE_VERSION ); 127 | } 128 | 129 | 130 | /** 131 | * Load the plugin text domain and MO files 132 | * 133 | * These can be uploaded to the main WP Languages folder 134 | * or the plugin one 135 | */ 136 | public function load_text_domain() { 137 | load_plugin_textdomain( INCSUB_BATCH_CREATE_LANG_DOMAIN, false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); 138 | } 139 | 140 | /** 141 | * Initialize the plugin 142 | */ 143 | public function init_plugin() { 144 | global $wpdb; 145 | 146 | require_once( INCSUB_BATCH_CREATE_INCLUDES_DIR . 'creator.php' ); 147 | 148 | $wpdb->batch_create_queuemeta = $wpdb->base_prefix . 'batch_create_queuemeta'; 149 | 150 | // A network menu 151 | $args = array( 152 | 'parent' => 'settings.php', 153 | 'menu_title' => __( 'Batch Create', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 154 | 'page_title' => __( 'Batch Create', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 155 | 'network_menu' => true, 156 | 'screen_icon_slug' => 'batch-create', 157 | 'tabs' => array( 158 | 'upload' => __( 'Batch Create', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 159 | 'queue' => __( 'Current queue', INCSUB_BATCH_CREATE_LANG_DOMAIN ), 160 | 'log-file' => __( 'Log File', INCSUB_BATCH_CREATE_LANG_DOMAIN ) 161 | 162 | ) 163 | ); 164 | self::$network_main_menu_page = new Batch_Create_Network_Main_Menu( 'batch-create-menu', 'manage_network', $args ); 165 | 166 | self::$batch_creator = new Incsub_Batch_Create_Creator(); 167 | } 168 | } 169 | 170 | new Incsub_Batch_Create(); 171 | -------------------------------------------------------------------------------- /model/model.php: -------------------------------------------------------------------------------- 1 | queue = $wpdb->base_prefix . 'batch_create_queue'; 46 | $this->queue_meta = $wpdb->base_prefix . 'batch_create_queuemeta'; 47 | 48 | // Get the correct character collate 49 | $db_charset_collate = ''; 50 | if ( ! empty($wpdb->charset) ) 51 | $this->db_charset_collate = "DEFAULT CHARACTER SET $wpdb->charset"; 52 | if ( ! empty($wpdb->collate) ) 53 | $this->db_charset_collate .= " COLLATE $wpdb->collate"; 54 | } 55 | 56 | /** 57 | * Create the required DB schema 58 | * 59 | * @since 0.1 60 | */ 61 | public function create_schema() { 62 | $this->create_queue_table(); 63 | $this->create_queue_meta_table(); 64 | } 65 | 66 | /** 67 | * Create the table 1 68 | * @return type 69 | */ 70 | private function create_queue_table() { 71 | require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); 72 | 73 | $sql = "CREATE TABLE $this->queue ( 74 | batch_create_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT, 75 | batch_create_site bigint(20) DEFAULT NULL, 76 | batch_create_blog_name varchar(255) NOT NULL DEFAULT 'null', 77 | batch_create_blog_title varchar(255) NOT NULL DEFAULT 'null', 78 | batch_create_user_name varchar(255) NOT NULL DEFAULT 'null', 79 | batch_create_user_pass varchar(255) NOT NULL DEFAULT 'null', 80 | batch_create_user_email varchar(255) NOT NULL DEFAULT 'null', 81 | batch_create_user_role varchar(255) NOT NULL DEFAULT 'null', 82 | PRIMARY KEY (batch_create_ID) 83 | ) ENGINE=InnoDB $this->db_charset_collate;"; 84 | 85 | dbDelta($sql); 86 | } 87 | 88 | private function create_queue_meta_table() { 89 | require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); 90 | 91 | $sql = "CREATE TABLE IF NOT EXISTS $this->queue_meta ( 92 | meta_id bigint(20) NOT NULL AUTO_INCREMENT, 93 | batch_create_queue_id bigint(20) NOT NULL, 94 | meta_key varchar(255) DEFAULT NULL, 95 | meta_value longtext, 96 | PRIMARY KEY (meta_id), 97 | KEY batch_create_queue_id (batch_create_queue_id), 98 | KEY meta_key (meta_key) 99 | ) ENGINE=InnoDB $this->db_charset_collate;"; 100 | 101 | dbDelta($sql); 102 | } 103 | 104 | /** 105 | * Drop the schema 106 | */ 107 | public function delete_tables() { 108 | global $wpdb; 109 | 110 | $wpdb->query( "DROP TABLE $this->queue;" ); 111 | $wpdb->query( "DROP TABLE $this->queue_meta;" ); 112 | } 113 | 114 | 115 | public function count_queue_items() { 116 | global $wpdb, $current_site; 117 | 118 | $result = $wpdb->get_var( 119 | $wpdb->prepare( 120 | "SELECT COUNT(*) FROM $this->queue WHERE batch_create_site = %d", $current_site->id 121 | ) 122 | ); 123 | 124 | return absint( $result ); 125 | } 126 | 127 | 128 | /** 129 | * Add entry into the database 130 | * 131 | * Since Batch Create 1.1.0 132 | */ 133 | function insert_queue( $args ) { 134 | global $wpdb, $current_site; 135 | 136 | array_unshift( $args, $current_site->id ); 137 | 138 | if ( 'Windows-1252' === mb_detect_encoding( $args[ 2 ] ) ) { 139 | $args[ 2 ] = iconv( "Windows-1252", "UTF-8", $args[2] ); 140 | } 141 | 142 | $wpdb->insert( 143 | $this->queue, 144 | array( 145 | 'batch_create_site' => $args[0], 146 | 'batch_create_blog_name' => $args[1], 147 | 'batch_create_blog_title' => $args[2], 148 | 'batch_create_user_name' => $args[3], 149 | 'batch_create_user_pass' => $args[4], 150 | 'batch_create_user_email' => $args[5], 151 | 'batch_create_user_role' => $args[6], 152 | ), 153 | array( '%d', '%s', '%s', '%s', '%s', '%s', '%s' ) 154 | ); 155 | 156 | return $wpdb->insert_id; 157 | 158 | } 159 | 160 | function clear_queue() { 161 | $queue_item = $this->get_queue_item(); 162 | while( ! empty( $queue_item ) ) { 163 | $this->delete_queue_item( $queue_item->batch_create_ID ); 164 | $queue_item = $this->get_queue_item(); 165 | } 166 | } 167 | 168 | public function get_queue_item() { 169 | global $wpdb, $current_site; 170 | 171 | return $wpdb->get_row( 172 | $wpdb->prepare( "SELECT * FROM $this->queue WHERE batch_create_site = %d", $current_site->id ) 173 | ); 174 | } 175 | 176 | 177 | public function delete_queue_item( $id ) { 178 | global $wpdb; 179 | 180 | $wpdb->query( 181 | $wpdb->prepare( 182 | "DELETE FROM $this->queue WHERE batch_create_ID = %d", 183 | $id 184 | ) 185 | ); 186 | 187 | $meta_keys = $wpdb->get_col( 188 | $wpdb->prepare( 189 | "SELECT meta_key FROM $this->queue_meta WHERE batch_create_queue_id = %d", 190 | $id 191 | ) 192 | ); 193 | 194 | if ( ! empty( $meta_keys ) ) { 195 | foreach ( $meta_keys as $meta_key ) { 196 | batch_create_delete_queue_meta( $id, $meta_key ); 197 | } 198 | } 199 | } 200 | 201 | public function get_queue_items( $current_page, $per_page ) { 202 | global $wpdb, $current_site; 203 | 204 | return $wpdb->get_results( 205 | $wpdb->prepare( 206 | "SELECT * FROM $this->queue WHERE batch_create_site = %d LIMIT %d, %d", 207 | $current_site->id, 208 | intval( ( $current_page - 1 ) * $per_page), 209 | intval( $per_page ) 210 | ), ARRAY_A 211 | ); 212 | } 213 | 214 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Batch Create 2 | 3 | **INACTIVE NOTICE: This plugin is unsupported by WPMUDEV, we've published it here for those technical types who might want to fork and maintain it for their needs.** 4 | 5 | ## Translations 6 | 7 | Translation files can be found at https://github.com/wpmudev/translations 8 | 9 | ## Batch Create lets you create hundreds or thousands of sites and users all at once. 10 | 11 | Whether you're setting up accounts for an entire University or creating a huge network on a heap of different topics batch create can save you countless hours. 12 | 13 | ### Speed and Efficiency 14 | 15 | There are many reasons to automate the creation of sites and users, and for adding lots of users to a site quickly – and this plugin serves precisely that purpose. 16 | 17 | ### Activate and Go 18 | 19 | Simply install and activate the plugin and 'Batch Create' will be added to the network admin 'Settings' menu. 20 | 21 | ![Settings > Batch Create in network admin dashboard](http://premium.wpmudev.org/wp-content/uploads/2011/04/bcreate61.jpg) 22 | 23 | Easy access from network admin 24 | 25 | Now Super Admin users can batch create new sites, new users and add users to existing sites by simply uploading a .xls or .csv file. 26 | 27 | ![Uploading to batch create](http://premium.wpmudev.org/wp-content/uploads/2011/04/bcreate62.jpg) 28 | 29 | Just choose a file and upload 30 | 31 | Creating the batch file is as simple as downloading the .xls template, following the included instructions and uploading. Choose URLs, site titles, usernames, user roles and user passwords. 32 | 33 | ![Using the Batch Create template](http://premium.wpmudev.org/wp-content/uploads/2011/04/bcreate63.jpg) 34 | 35 | Includes easy-to-follow template 36 | 37 | Bulk create sites and users quickly and efficiently using Batch Create. 38 | 39 | ## Usage 40 | 41 | Start by reading [Installing plugins](https://premium.wpmudev.org/wpmu-manual/using-regular-plugins-on-wpmu/) section in our comprehensive [WordPress and WordPress Multisite Manual](https://premium.wpmudev.org/wpmu-manual/) if you are new to WordPress Multisite. 42 | 43 | ### To install: 44 | 45 | 1\. Download the plugin file 2.Unzip the file into a folder on your hard drive 3\. Upload **/batch-create/** folder to **/wp-content/plugins/** folder on your site 4\. Visit **Network Admin -> Plugins** and **Network Activate** it there. _Note: If you have an older version of the plugin installed in /mu-plugins/ please delete it._ **That's it! No configuration necessary!** 46 | 47 | ### To Use: 48 | 49 | A new menu item called **Batch Create** should appear under the **Settings** navigation menu in the network admin dashboard once the plugin has been network activated. It is designed for quickly creating sites and/or usernames or adding users to an existing site in batches of 10's, 100's or 1000's by uploading a .xls file or .csv text file. 1\. Go to **Settings > Batch Create** in the network admin dashboard2\. Download the template file by clicking on the 'this .xls' link 3\. Follow the instructions in the header row of the .xls template file to replace your site and users details with the provided examples. 4\. Save your batch file as Excel 97-2003 or a .csv file. 5\. Now upload and process your batch file. 50 | 51 | ![Using Batch Create](https://premium.wpmudev.org/wp-content/uploads/2011/04/bcreate63.jpg) 52 | 53 | ### Some Facts About Batch Create 54 | 55 | * The easiest option for creating your batch create file is to use Excel and save it as a Excel 97-2003 Workbook 56 | * It needs to be written in this order --Site Name,Site Title, username, password, user email and user role 57 | * Each new user must be on a separate row and each of a users details in a new column 58 | * WordPress doesn't allow multiple user to have the same email address 59 | * When the system encounters an error creating a user in the batch file, the error log will be updated and all other processing will stop. That way the admin can go through the batch file and correct the problematic entry 60 | 61 | **Site Name** 62 | 63 | * The name of the site you want created or the user added to (if that site already exists). 64 | * If you do not want the user to have a site, please set this to 'null' without the quotation marks. 65 | * This will be part of the URL for the site (ex. site-name.myblogs.org or myblogs.org/site-name) 66 | * You can only use lowercase letters, numbers and dashes in site URLs (site address). Dots, underscore, special characters and spaces in site URLs aren't allowed. 67 | 68 | **Site Title** 69 | 70 | * The title of the site. 71 | * This can be changed later in **Settings > General** in the site admin dashboard 72 | 73 | **User Name** 74 | 75 | * The login or username of the user. 76 | * No spaces allowed. This can't be changed later. 77 | * You can only use lowercase letters and numbers in usernames. Dots, underscore, dashes, special characters and spaces in usernames aren't allowed and can result in problems with usernames. 78 | 79 | **User password** 80 | 81 | * If you would like a password auto-generated please set this to 'null' without the quotation marks. 82 | * No spaces are allowed in passwords 83 | * The user will get an email with the password. 84 | 85 | **User Email ** 86 | 87 | * You must provide a valid email for each user as these are required for functions like password resets, comment notification and deleting sites. 88 | * WordPress doesn’t allow multiple users to have the same email address. This means that the email addresses for new users in the batch file should be unique not only in the batch file, but across system too. 89 | * Spam filters, especially strict ones for institutional email addresses, may well block username and login information from reaching users. In this case you should recommend users use free webmail accounts that won’t block the emails (such as gmail.com, hotmail.com or mail.yahoo.com) 90 | 91 | **User Role** 92 | 93 | * The user role (when the user is added to an existing site). 94 | * Role can be set to subscriber, contributor, author, editor, or administrator. 95 | * If user role isn't specified they are automatically added as an administrator. 96 | * If a new site is being created and the assigned user's role isn't administrator the Super Admin will be assigned to the site as an adminstrator 97 | 98 | **Here are some examples of how you can use batch create:** 99 | 100 | ![Using Batch Create](https://premium.wpmudev.org/wp-content/uploads/2011/04/batchcreateex.jpg) 101 | 102 | -------------------------------------------------------------------------------- /inc/excel/oleread.php: -------------------------------------------------------------------------------- 1 | =4294967294) 30 | { 31 | $value=-2; 32 | } 33 | return $value; 34 | } 35 | 36 | 37 | class OLERead { 38 | var $data = ''; 39 | 40 | 41 | function OLERead(){ 42 | 43 | 44 | } 45 | 46 | function read($sFileName){ 47 | 48 | // check if file exist and is readable (Darko Miljanovic) 49 | if(!is_readable($sFileName)) { 50 | $this->error = 1; 51 | return false; 52 | } 53 | 54 | $this->data = @file_get_contents($sFileName); 55 | if (!$this->data) { 56 | $this->error = 1; 57 | return false; 58 | } 59 | //echo IDENTIFIER_OLE; 60 | //echo 'start'; 61 | if (substr($this->data, 0, 8) != IDENTIFIER_OLE) { 62 | $this->error = 1; 63 | return false; 64 | } 65 | $this->numBigBlockDepotBlocks = GetInt4d($this->data, NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); 66 | $this->sbdStartBlock = GetInt4d($this->data, SMALL_BLOCK_DEPOT_BLOCK_POS); 67 | $this->rootStartBlock = GetInt4d($this->data, ROOT_START_BLOCK_POS); 68 | $this->extensionBlock = GetInt4d($this->data, EXTENSION_BLOCK_POS); 69 | $this->numExtensionBlocks = GetInt4d($this->data, NUM_EXTENSION_BLOCK_POS); 70 | 71 | /* 72 | echo $this->numBigBlockDepotBlocks." "; 73 | echo $this->sbdStartBlock." "; 74 | echo $this->rootStartBlock." "; 75 | echo $this->extensionBlock." "; 76 | echo $this->numExtensionBlocks." "; 77 | */ 78 | //echo "sbdStartBlock = $this->sbdStartBlock\n"; 79 | $bigBlockDepotBlocks = array(); 80 | $pos = BIG_BLOCK_DEPOT_BLOCKS_POS; 81 | // echo "pos = $pos"; 82 | $bbdBlocks = $this->numBigBlockDepotBlocks; 83 | 84 | if ($this->numExtensionBlocks != 0) { 85 | $bbdBlocks = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4; 86 | } 87 | 88 | for ($i = 0; $i < $bbdBlocks; $i++) { 89 | $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos); 90 | $pos += 4; 91 | } 92 | 93 | 94 | for ($j = 0; $j < $this->numExtensionBlocks; $j++) { 95 | $pos = ($this->extensionBlock + 1) * BIG_BLOCK_SIZE; 96 | $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, BIG_BLOCK_SIZE / 4 - 1); 97 | 98 | for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; $i++) { 99 | $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos); 100 | $pos += 4; 101 | } 102 | 103 | $bbdBlocks += $blocksToRead; 104 | if ($bbdBlocks < $this->numBigBlockDepotBlocks) { 105 | $this->extensionBlock = GetInt4d($this->data, $pos); 106 | } 107 | } 108 | 109 | // var_dump($bigBlockDepotBlocks); 110 | 111 | // readBigBlockDepot 112 | $pos = 0; 113 | $index = 0; 114 | $this->bigBlockChain = array(); 115 | 116 | for ($i = 0; $i < $this->numBigBlockDepotBlocks; $i++) { 117 | $pos = ($bigBlockDepotBlocks[$i] + 1) * BIG_BLOCK_SIZE; 118 | //echo "pos = $pos"; 119 | for ($j = 0 ; $j < BIG_BLOCK_SIZE / 4; $j++) { 120 | $this->bigBlockChain[$index] = GetInt4d($this->data, $pos); 121 | $pos += 4 ; 122 | $index++; 123 | } 124 | } 125 | 126 | //var_dump($this->bigBlockChain); 127 | //echo '=====2'; 128 | // readSmallBlockDepot(); 129 | $pos = 0; 130 | $index = 0; 131 | $sbdBlock = $this->sbdStartBlock; 132 | $this->smallBlockChain = array(); 133 | 134 | while ($sbdBlock != -2) { 135 | 136 | $pos = ($sbdBlock + 1) * BIG_BLOCK_SIZE; 137 | 138 | for ($j = 0; $j < BIG_BLOCK_SIZE / 4; $j++) { 139 | $this->smallBlockChain[$index] = GetInt4d($this->data, $pos); 140 | $pos += 4; 141 | $index++; 142 | } 143 | 144 | $sbdBlock = $this->bigBlockChain[$sbdBlock]; 145 | } 146 | 147 | 148 | // readData(rootStartBlock) 149 | $block = $this->rootStartBlock; 150 | $pos = 0; 151 | $this->entry = $this->__readData($block); 152 | 153 | /* 154 | while ($block != -2) { 155 | $pos = ($block + 1) * BIG_BLOCK_SIZE; 156 | $this->entry = $this->entry.substr($this->data, $pos, BIG_BLOCK_SIZE); 157 | $block = $this->bigBlockChain[$block]; 158 | } 159 | */ 160 | //echo '==='.$this->entry."==="; 161 | $this->__readPropertySets(); 162 | 163 | } 164 | 165 | function __readData($bl) { 166 | $block = $bl; 167 | $pos = 0; 168 | $data = ''; 169 | 170 | while ($block != -2) { 171 | $pos = ($block + 1) * BIG_BLOCK_SIZE; 172 | $data = $data.substr($this->data, $pos, BIG_BLOCK_SIZE); 173 | //echo "pos = $pos data=$data\n"; 174 | $block = $this->bigBlockChain[$block]; 175 | } 176 | return $data; 177 | } 178 | 179 | function __readPropertySets(){ 180 | $offset = 0; 181 | //var_dump($this->entry); 182 | while ($offset < strlen($this->entry)) { 183 | $d = substr($this->entry, $offset, PROPERTY_STORAGE_BLOCK_SIZE); 184 | 185 | $nameSize = ord($d[SIZE_OF_NAME_POS]) | (ord($d[SIZE_OF_NAME_POS+1]) << 8); 186 | 187 | $type = ord($d[TYPE_POS]); 188 | //$maxBlock = strlen($d) / BIG_BLOCK_SIZE - 1; 189 | 190 | $startBlock = GetInt4d($d, START_BLOCK_POS); 191 | $size = GetInt4d($d, SIZE_POS); 192 | 193 | $name = ''; 194 | for ($i = 0; $i < $nameSize ; $i++) { 195 | $name .= $d[$i]; 196 | } 197 | 198 | $name = str_replace("\x00", "", $name); 199 | 200 | $this->props[] = array ( 201 | 'name' => $name, 202 | 'type' => $type, 203 | 'startBlock' => $startBlock, 204 | 'size' => $size); 205 | 206 | if (($name == "Workbook") || ($name == "Book")) { 207 | $this->wrkbook = count($this->props) - 1; 208 | } 209 | 210 | if ($name == "Root Entry") { 211 | $this->rootentry = count($this->props) - 1; 212 | } 213 | 214 | //echo "name ==$name=\n"; 215 | 216 | 217 | $offset += PROPERTY_STORAGE_BLOCK_SIZE; 218 | } 219 | 220 | } 221 | 222 | 223 | function getWorkBook(){ 224 | if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){ 225 | // getSmallBlockStream(PropertyStorage ps) 226 | 227 | $rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']); 228 | 229 | $streamData = ''; 230 | $block = $this->props[$this->wrkbook]['startBlock']; 231 | //$count = 0; 232 | $pos = 0; 233 | while ($block != -2) { 234 | $pos = $block * SMALL_BLOCK_SIZE; 235 | $streamData .= substr($rootdata, $pos, SMALL_BLOCK_SIZE); 236 | 237 | $block = $this->smallBlockChain[$block]; 238 | } 239 | 240 | return $streamData; 241 | 242 | 243 | }else{ 244 | 245 | $numBlocks = $this->props[$this->wrkbook]['size'] / BIG_BLOCK_SIZE; 246 | if ($this->props[$this->wrkbook]['size'] % BIG_BLOCK_SIZE != 0) { 247 | $numBlocks++; 248 | } 249 | 250 | if ($numBlocks == 0) return ''; 251 | 252 | //echo "numBlocks = $numBlocks\n"; 253 | //byte[] streamData = new byte[numBlocks * BIG_BLOCK_SIZE]; 254 | //print_r($this->wrkbook); 255 | $streamData = ''; 256 | $block = $this->props[$this->wrkbook]['startBlock']; 257 | //$count = 0; 258 | $pos = 0; 259 | //echo "block = $block"; 260 | while ($block != -2) { 261 | $pos = ($block + 1) * BIG_BLOCK_SIZE; 262 | $streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE); 263 | $block = $this->bigBlockChain[$block]; 264 | } 265 | //echo 'stream'.$streamData; 266 | return $streamData; 267 | } 268 | } 269 | 270 | } 271 | ?> -------------------------------------------------------------------------------- /inc/admin-page.php: -------------------------------------------------------------------------------- 1 | Array of tabs [tab_slug] => Tab Name 46 | * parent => Slug of the parent menu or false if is a main menu 47 | * menu_title => Title of the Menu 48 | * page_title => Title of the page 49 | * screen_icon_slug => Allows applying styles to screen icons 50 | * network_menu => Boolean. Determines if the page is a Network Menu or Blog Menu 51 | * enqueue_scripts => Boolean. Determines if the page need some additional scripts. 52 | * Then, a custom function needs to be added to the subclass 53 | * enqueue_scripts => Boolean. Determines if the page need some additional styles. 54 | * Then, a custom function needs to be added to the subclass 55 | * forbidden_message => String. Message displayed when the user has no permissions to see this page 56 | */ 57 | public function __construct( $slug, $capability = 'manage_options', $args = array() ) { 58 | 59 | // Default arguments 60 | $defaults = array( 61 | 'tabs' => array(), 62 | 'parent' => false, 63 | 'menu_title' => 'Menu title', 64 | 'page_title' => 'Page title', 65 | 'screen_icon_slug' => '', 66 | 'network_menu' => false, 67 | 'enqueue_scripts' => false, 68 | 'enqueue_styles' => false, 69 | 'forbidden_message' => 'You do not have enough permissions to access to this page' 70 | ); 71 | 72 | $args = wp_parse_args( $args, $defaults ); 73 | extract( $args ); 74 | 75 | 76 | if ( empty( $slug ) ) 77 | return; 78 | 79 | $this->tabs = ! empty( $tabs ) ? $tabs : array(); 80 | $this->menu_slug = $slug; 81 | $this->parent = $parent; 82 | $this->menu_title = $menu_title; 83 | $this->page_title = $page_title; 84 | $this->capability = $capability; 85 | $this->screen_icon_slug = $screen_icon_slug; 86 | $this->network_menu = $network_menu; 87 | 88 | // Network menu? 89 | if ( ! $network_menu ) 90 | add_action( 'admin_menu', array( &$this, 'add_menu' ) ); 91 | else 92 | add_action( 'network_admin_menu', array( &$this, 'add_menu' ) ); 93 | 94 | // Need some scripts? 95 | if ( $enqueue_scripts ) 96 | add_action( 'admin_enqueue_scripts', array( &$this, 'check_for_scripts' ) ); 97 | 98 | // Need some styles? 99 | if ( $enqueue_styles ) 100 | add_action( 'admin_enqueue_scripts', array( &$this, 'check_for_styles' ) ); 101 | } 102 | 103 | /** 104 | * If the admin page need scripts, this function 105 | * will check if the method is declared in the child class 106 | * and will call it or throw an exception 107 | * 108 | * @param String $hook Hook of the page 109 | */ 110 | public function check_for_scripts( $hook ) { 111 | if ( $hook === $this->page_id ) { 112 | 113 | // Checking if enqueue_scripts method exists in he subclass 114 | try { 115 | if ( method_exists( $this, 'enqueue_scripts' ) ) 116 | $this->enqueue_scripts(); 117 | else 118 | throw new Exception( 'You need to declare enqueue_scripts method in ' . get_class( $this ) . ' class', 1); 119 | } catch (Exception $e) { 120 | // There's no function declared in the subclass 121 | Incsub_Batch_Create_Errors_Handler::show_exception( $e->getMessage() ); 122 | } 123 | 124 | } 125 | } 126 | 127 | /** 128 | * If the admin page need styles, this function 129 | * will check if the method is declared in the child class 130 | * and will call it or throw an exception 131 | */ 132 | public function check_for_styles( $hook ) { 133 | if ( $hook === $this->page_id ) { 134 | 135 | // Checking if enqueue_styles method exists in he subclass 136 | try { 137 | if ( method_exists( $this, 'enqueue_styles' ) ) 138 | $this->enqueue_styles(); 139 | else 140 | throw new Exception( 'You need to declare enqueue_styles method in ' . get_class( $this ) . ' class', 1); 141 | 142 | } catch ( Exception $e ) { 143 | // There's no function declared in the subclass 144 | Incsub_Batch_Create_Errors_Handler::show_exception( $e->getMessage() ); 145 | } 146 | 147 | } 148 | 149 | } 150 | 151 | /** 152 | * Add the menu to the WP Menu 153 | */ 154 | public function add_menu() { 155 | 156 | if ( ! empty( $this->parent ) ) { 157 | // For submenus 158 | $this->page_id = add_submenu_page( 159 | $this->parent, 160 | $this->page_title, 161 | $this->menu_title, 162 | $this->capability, 163 | $this->menu_slug, 164 | array( &$this, 'render_page' ) 165 | ); 166 | } 167 | else { 168 | // For main menus 169 | $this->page_id = add_menu_page( 170 | $this->page_title, 171 | $this->menu_title, 172 | $this->capability, 173 | $this->menu_slug, 174 | array( &$this, 'render_page' ), 175 | 'div' 176 | ); 177 | } 178 | } 179 | 180 | 181 | /** 182 | * Render the main wrap of the page. 183 | * 184 | * This is common to all the pages. 185 | * 186 | * @return type 187 | */ 188 | public function render_page() { 189 | 190 | if ( ! current_user_can( $this->get_capability() ) ) 191 | wp_die( $this->forbidden_message ); 192 | 193 | ?> 194 |
195 | 196 | show_notice(); ?> 197 | 198 | screen_icon_slug ); ?> 199 | 200 | tabs ) ): ?> 201 | the_tabs(); ?> 202 | 203 |

204 | 205 | 206 | render_content(); ?> 207 | 208 |
209 | 210 | get_current_tab(); 218 | 219 | echo '