├── .gitignore ├── data └── products │ └── images │ └── note.txt ├── composer.json ├── wc-cyclone.php ├── LICENSE ├── inc ├── helpers.php ├── commands.php └── generate.php ├── README.md └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/* 2 | /data/products/images/* 3 | -------------------------------------------------------------------------------- /data/products/images/note.txt: -------------------------------------------------------------------------------- 1 | Seeded images will be stored here. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "fakerphp/faker": "^1.24", 4 | "crewlabs/unsplash": "^3.2", 5 | "nesbot/carbon": "^2.72" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /wc-cyclone.php: -------------------------------------------------------------------------------- 1 | $faker->firstName, 26 | 'last_name' => $faker->lastName, 27 | 'email' => $faker->email, 28 | 'username' => $faker->userName, 29 | 'address' => [ 30 | 'street' => $faker->streetAddress, 31 | 'city' => $city, 32 | 'state' => $faker->state, 33 | 'postcode' => $faker->postcode, 34 | 'country' => $country, 35 | 'phone' => $faker->e164PhoneNumber, 36 | ], 37 | ]; 38 | 39 | return $user; 40 | } 41 | 42 | /** 43 | * Get a random weighted element from an array. 44 | * @param array $weightedValues 45 | * @return string $key 46 | */ 47 | public static function getRandomWeightedElement($weightedValues = []) { 48 | $rand = mt_rand(1, (int) array_sum($weightedValues)); 49 | 50 | foreach ($weightedValues as $key => $value) { 51 | $rand -= $value; 52 | if ($rand <= 0) { 53 | return $key; 54 | } 55 | } 56 | } 57 | 58 | /** 59 | * Check if an image exists by filename. 60 | * @param string $filename 61 | * @return bool 62 | */ 63 | public static function checkImageExists( $filename ) { 64 | $args = array( 65 | 'post_per_page' => 1, 66 | 'post_type' => 'attachment', 67 | 'name' => trim ( $filename ), 68 | ); 69 | $get_posts = new \WP_Query( $args ); 70 | 71 | if ( isset($get_posts->posts[0]) ) { 72 | return true; 73 | } 74 | return false; 75 | } 76 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WC Cyclone 2 | 3 | This is a WordPress plugin that adds several WP-CLI commands for generating fake WooCommerce data. It's still in its early days and as such doesn't yet offer coupon generating, more complicated order generating and refund generating. 4 | 5 | ### Requires 6 | 7 | * [WP-CLI](http://wp-cli.org/) 8 | * [Composer](http://getcomposer.org/) 9 | 10 | ### Installing 11 | Make sure you run `composer install` within the plugin's directly before actually using it. 12 | 13 | You'll also need to run `wp cyclone seed` before you can generate products. More on that below. 14 | 15 | ### Commands 16 | 17 | ``` 18 | wp cyclone seed [--type=] 19 | ``` 20 | 21 | Seeds the product data for WC Cyclone to use, which pretty much means downloading a lot of Unsplash images. You can optionally set the type to be `books` or `food` (books by default). 22 | 23 | --- 24 | 25 | ``` 26 | wp cyclone unsplash 27 | ``` 28 | 29 | Set the Unsplash APP Id for WC Cyclone to use. In case you don't want to use WC Cyclone's Unsplash application. You can create the app on [Unsplash's website](https://unsplash.com/developers). 30 | 31 | --- 32 | 33 | ``` 34 | wp cyclone products [--type=] 35 | ``` 36 | 37 | `` is required and should be integer # of products to generate. Note that the example data included doesn't really have more than a couple hundred unique items, so if were to generate several hundred/thousand products, they'd likely have the same name/images (but different prices, SKUs, etc.). 38 | 39 | You can also set the type here. By default it's `books` but can also be `food`. 40 | 41 | --- 42 | 43 | ``` 44 | wp cyclone customers [--from=] 45 | ``` 46 | 47 | Generate customers. `` is an integer # of customers to generate. 48 | 49 | The `from` option lets you define the # of days in the past customers should be generated from. It's a random date used, but this lets it be a random date `x` days ago. By default it's `180`. 50 | 51 | --- 52 | 53 | ``` 54 | wp cyclone orders [--from=] 55 | ``` 56 | 57 | Generate orders. `` is an integer # of orders to generate. 58 | 59 | The `from` option lets you define the # of days in the past orders should be generated from. It's a random date used, but this lets it be a random date `x` days ago. By default it's `180`. 60 | 61 | ### Pro-tip 62 | 63 | Don't just sit there watching it generate data! You can have it run as a [background job](http://unix.stackexchange.com/questions/103731/run-a-command-without-making-me-wait). Simply append `&` and optionally prepend the command with `nohup` (to generate a log). For example: 64 | 65 | ``` 66 | wp cyclone orders 100000 & 67 | ``` 68 | 69 | or... 70 | 71 | ``` 72 | nohup wp cyclone orders 100000 & 73 | ``` 74 | 75 | 76 | ### What's coming 77 | 78 | Scheduled/cron-powered generating, so you can have data generated on a random, but consistent basis. 79 | 80 | ### Contributing 81 | 82 | Contributions are definitely welcomed and encouraged. Please feel free to open a PR with any changes you think should be made. 83 | 84 | ### License 85 | [MIT](https://opensource.org/licenses/MIT) 86 | 87 | Copyright (c) 2016+ Bryce Adams / Metorik -------------------------------------------------------------------------------- /inc/commands.php: -------------------------------------------------------------------------------- 1 | ] 41 | * : The type of resource to seed. 42 | * --- 43 | * default: books 44 | * options: 45 | * - books 46 | * - food 47 | * 48 | * ## EXAMPLES 49 | * 50 | * wp cyclone seed 51 | * 52 | * @when before_wp_load 53 | */ 54 | public function seed( $args, $assoc_args ) { 55 | $app = get_option( 'wc_cyclone_unsplash_app' ) ? get_option( 'wc_cyclone_unsplash_app' ) : $this->appID; 56 | 57 | WP_CLI::line( 'We are going to download a collection of images from Unsplash now. Please be patient...' ); 58 | 59 | /** 60 | * Client. 61 | */ 62 | \Unsplash\HttpClient::init([ 63 | 'applicationId' => $app, 64 | ]); 65 | 66 | /** 67 | * Type to seed. 68 | */ 69 | $type = $assoc_args['type']; 70 | 71 | /** 72 | * Determine collection ID based on type. 73 | */ 74 | switch($type) { 75 | case 'books'; 76 | default; 77 | $collectionID = 228444; 78 | break; 79 | case 'food'; 80 | $collectionID = 140489; 81 | break; 82 | } 83 | 84 | // get collection 85 | try { 86 | $collection = \Unsplash\Collection::find($collectionID); 87 | } catch(\Unsplash\Exception $e) { 88 | WP_CLI::error( "No! Collection doesn\'t exist for " . $collectionID . "." ); 89 | return; 90 | } 91 | 92 | // make directory 93 | $path = plugin_dir_path( __FILE__ ) . '../data/products/images/' . $type; 94 | if (! file_exists($path)) { 95 | mkdir($path); 96 | } 97 | 98 | // calculate page data 99 | $total = $collection->total_photos; 100 | $pages = ceil($total / 30); 101 | 102 | // create progress bar 103 | $progress = \WP_CLI\Utils\make_progress_bar( 'Downloading images', $total ); 104 | 105 | // go through each page 106 | for($x = 1; $x < $pages; $x++) { 107 | // get page of photos from collection 108 | $photos = $collection->photos($x, 30); 109 | 110 | // go through each photo & download 111 | foreach($photos as $photo) { 112 | $url = $photo->urls['regular']; 113 | $imagePath = $path . '/' . $photo->id . '.jpg'; 114 | if (! file_exists($imagePath)) { 115 | copy($url, $imagePath); 116 | } 117 | // progress +1 118 | $progress->tick(); 119 | } 120 | } 121 | 122 | // progress done 123 | $progress->finish(); 124 | 125 | WP_CLI::success( 'All done! ' . $total . ' "' . $type . '" images were downloaded. You can now generate products.' ); 126 | 127 | // Update the 'seed' option so we know data has been seeded 128 | update_option( 'wc_cyclone_data_seeded', true ); 129 | } 130 | 131 | /** 132 | * Generates fake orders using the WC Order Simulator plugin. 133 | * 134 | * ## OPTIONS 135 | * 136 | * 137 | * : The amount of orders to generate. 138 | * 139 | * [--from=] 140 | * : The number of days from now to start creating orders from 141 | * 142 | * [--customers=] 143 | * : Whether or not to create customers too - defaults to false. 144 | * --- 145 | * default: 180 146 | * --- 147 | * 148 | * ## EXAMPLES 149 | * 150 | * wp cyclone orders 200 --from=50 151 | * 152 | * @when before_wp_load 153 | */ 154 | public function orders( $args, $assoc_args ) { 155 | global $wpdb; 156 | 157 | // handle args 158 | list( $amount ) = $args; 159 | $from = isset($assoc_args['from']) ? $assoc_args['from'] : 90; 160 | 161 | // Chances of it being an existing customer, new customer or guest 162 | $chances = apply_filters('wc_cyclone_order_customer_chances', [ 163 | 'existing' => 25, 164 | 'new' => 60, 165 | 'guest' => 15, 166 | ]); 167 | 168 | // create progress bar 169 | $progress = \WP_CLI\Utils\make_progress_bar( 'Generating orders', $amount ); 170 | 171 | for($x = 0; $x < $amount; $x++) { 172 | // Figure out the customer type 173 | $customer = Helpers::getRandomWeightedElement($chances); 174 | switch($customer) { 175 | case 'existing'; 176 | // Get random customer ID where ID is not 1 (presumed admin ID) 177 | $customer = intval($wpdb->get_var("SELECT ID FROM $wpdb->users WHERE id <> 1 ORDER BY RAND() LIMIT 1")); 178 | break; 179 | case 'new'; 180 | $customer = true; 181 | break; 182 | case 'guest'; 183 | default; 184 | $customer = false; 185 | break; 186 | } 187 | 188 | Generate::order( $from, $customer ); 189 | 190 | // +1 for progress 191 | $progress->tick(); 192 | } 193 | 194 | // progress finished 195 | $progress->finish(); 196 | 197 | // success message 198 | WP_CLI::success( $amount . ' orders generated from ' . $from . ' days ago!' ); 199 | } 200 | 201 | /** 202 | * Generates fake customers using the WC Order Simulator plugin. 203 | * 204 | * ## OPTIONS 205 | * 206 | * 207 | * : The amount of customers to generate. 208 | * 209 | * [--from=] 210 | * : The number of days from now to start creating customers from 211 | * --- 212 | * default: 180 213 | * --- 214 | * 215 | * ## EXAMPLES 216 | * 217 | * wp cyclone customers 200 --from=50 218 | * 219 | * @when before_wp_load 220 | */ 221 | public function customers( $args, $assoc_args ) { 222 | // handle args 223 | list( $amount ) = $args; 224 | $from = isset( $assoc_args['from'] ) ? $assoc_args['from'] : 90; 225 | 226 | // create progress bar 227 | $progress = \WP_CLI\Utils\make_progress_bar( 'Generating customers', $amount ); 228 | 229 | for($x = 0; $x < $amount; $x++) { 230 | Generate::customer( $from ); 231 | 232 | // progress +1 233 | $progress->tick(); 234 | } 235 | 236 | // progress done 237 | $progress->finish(); 238 | 239 | // success message 240 | WP_CLI::success( $amount . ' customers generated from ' . $from . ' days ago!' ); 241 | } 242 | 243 | /** 244 | * Generates fake products using the WC Product Generator plugin. 245 | * 246 | * ## OPTIONS 247 | * 248 | * 249 | * : The amount of products to generate. 250 | * 251 | * [--type=] 252 | * : The type of products to seed 253 | * --- 254 | * default: books 255 | * options: 256 | * - books 257 | * - food 258 | * --- 259 | * 260 | * ## EXAMPLES 261 | * 262 | * wp cyclone products 10 --type=food 263 | * 264 | * @when before_wp_load 265 | */ 266 | public function products( $args, $assoc_args ) { 267 | // first check data has been seeded 268 | if ( ! get_option( 'wc_cyclone_data_seeded' ) ) { 269 | WP_CLI::error( 'You need to seed data first. Please run `wp cyclone seed --type=books` where type is either books or food to get started.' ); 270 | } 271 | 272 | // handle args 273 | list( $amount ) = $args; 274 | $type = isset($assoc_args['type']) ? $assoc_args['type'] : 'food'; 275 | 276 | // create progress bar 277 | $progress = \WP_CLI\Utils\make_progress_bar( 'Generating products', $amount ); 278 | 279 | $success = 0; 280 | for($x = 0; $x < $amount; $x++) { 281 | $generate = Generate::product( $type ); 282 | if ( $generate ) { 283 | $success++; 284 | } 285 | 286 | // progress +1 287 | $progress->tick(); 288 | } 289 | 290 | // progress done 291 | $progress->finish(); 292 | 293 | // success message 294 | WP_CLI::success( $success . '/' . $amount . ' products generated!' ); 295 | } 296 | 297 | } 298 | 299 | WP_CLI::add_command( 'cyclone', 'Cyclone\Commands' ); 300 | -------------------------------------------------------------------------------- /inc/generate.php: -------------------------------------------------------------------------------- 1 | words( 2, true ) ); 21 | $category = $faker->randomElement( array( 'Drama', 'Mystery', 'Romance', 'Horror', 'Travel', 'Health' ) ); 22 | } while( get_page_by_title( $title, 'OBJECT', 'product' ) ); 23 | 24 | // Create product 25 | $product = [ 26 | 'title' => $title, 27 | 'category' => $category, 28 | 'sku' => strtoupper( $faker->numerify( substr( str_replace( ' ', '', $title ), 0, 5 ) . '#####' ) ), 29 | 'content' => implode( "\n\n", $faker->paragraphs( rand( 3, 6 ) ) ), 30 | 'excerpt' => $faker->paragraph( 3 ), 31 | 'price' => $faker->randomFloat( rand( 0, 2 ), 5, 125 ), 32 | ]; 33 | 34 | $post_id = wp_insert_post( array( 35 | 'post_type' => 'product', 36 | 'post_title' => $product['title'], 37 | 'post_excerpt' => $product['excerpt'], 38 | 'post_content' => $product['content'], 39 | 'post_status' => 'publish', 40 | ), true ); 41 | 42 | if ( ! ( $post_id instanceof WP_Error ) ) { 43 | 44 | // visibility 45 | update_post_meta( $post_id, '_visibility', 'visible' ); 46 | 47 | // price 48 | update_post_meta( $post_id, '_price', $product['price'] ); 49 | update_post_meta( $post_id, '_regular_price', $product['price'] ); 50 | 51 | // add categories (@todo more than one) 52 | $terms = [$product['category']]; 53 | wp_set_object_terms( $post_id, $terms, 'product_cat', true ); 54 | 55 | // add tags (@todo) 56 | // add attributes (@todo) 57 | // add variations (@todo) 58 | 59 | /** 60 | * Product image 61 | */ 62 | 63 | // figure out a random matching image that's unique 64 | do { 65 | $dir = plugin_dir_path( __FILE__ ) . '../data/products/images/' . $type . '/'; 66 | $images = glob($dir . '*.{jpg,jpeg,png,gif}', GLOB_BRACE); 67 | $image = $images[array_rand($images)]; 68 | $filename = basename($image); 69 | } while( Helpers::checkImageExists( $filename ) ); 70 | 71 | // upload the image 72 | $upload_file = wp_upload_bits( $filename, null, file_get_contents( $image ) ); 73 | if ( ! $upload_file['error'] ) { 74 | $wp_filetype = wp_check_filetype( $filename, null ); 75 | $attachment = array( 76 | 'post_mime_type' => $wp_filetype['type'], 77 | 'post_parent' => $post_id, 78 | 'post_title' => preg_replace( '/\.[^.]+$/', '', $filename ), 79 | 'post_content' => '', 80 | 'post_status' => 'inherit' 81 | ); 82 | 83 | // insert attachment 84 | $attachment_id = wp_insert_attachment( $attachment, $upload_file['file'], $post_id ); 85 | if ( ! is_wp_error( $attachment_id ) ) { 86 | require_once( ABSPATH . "wp-admin" . '/includes/image.php' ); 87 | $attachment_data = wp_generate_attachment_metadata( $attachment_id, $upload_file['file'] ); 88 | wp_update_attachment_metadata( $attachment_id, $attachment_data ); 89 | 90 | // set thumbnail 91 | set_post_thumbnail( $post_id, $attachment_id ); 92 | } 93 | } 94 | 95 | // sku 96 | update_post_meta( $post_id, '_sku', $product['sku'] ); 97 | 98 | // success 99 | return true; 100 | } 101 | 102 | // failed 103 | return false; 104 | } 105 | 106 | /** 107 | * Generate a customer. 108 | * @param [type] $from [description] 109 | * @return [type] [description] 110 | */ 111 | public static function customer( $from ) { 112 | $user = Helpers::userInfo(); 113 | 114 | // user registered date (random using from) 115 | if ( is_int( $from ) ) { 116 | $day = rand(0, $from); 117 | $hour = rand(0, 23); 118 | $registered = date( 'Y-m-d H:i:s', strtotime("-$day day -$hour hour") ); 119 | } else { 120 | $registered = $from; 121 | } 122 | 123 | // filter WC new customer data 124 | add_filter( 'woocommerce_new_customer_data', function($data) use ($user, $registered) { 125 | $data['first_name'] = $user['first_name']; 126 | $data['last_name'] = $user['last_name']; 127 | $data['user_registered'] = $registered; 128 | return $data; 129 | }); 130 | 131 | // email, username, password 132 | $user_id = wc_create_new_customer( strtolower( $user['email'] ), $user['username'], 'cyclone' ); 133 | 134 | // billing/shipping address 135 | $meta = array( 136 | 'billing_country' => $user['address']['country'], 137 | 'billing_first_name' => $user['first_name'], 138 | 'billing_last_name' => $user['last_name'], 139 | 'billing_address_1' => $user['address']['street'], 140 | 'billing_city' => $user['address']['city'], 141 | 'billing_state' => $user['address']['state'], 142 | 'billing_postcode' => $user['address']['postcode'], 143 | 'billing_email' => $user['email'], 144 | 'billing_phone' => $user['address']['phone'], 145 | 'shipping_country' => $user['address']['country'], 146 | 'shipping_first_name' => $user['first_name'], 147 | 'shipping_last_name' => $user['last_name'], 148 | 'shipping_address_1' => $user['address']['street'], 149 | 'shipping_city' => $user['address']['city'], 150 | 'shipping_state' => $user['address']['state'], 151 | 'shipping_postcode' => $user['address']['postcode'], 152 | 'shipping_email' => $user['email'], 153 | 'shipping_phone' => $user['address']['phone'], 154 | 'last_update' => strtotime($registered), 155 | ); 156 | 157 | foreach ($meta as $key => $value) { 158 | update_user_meta( $user_id, $key, $value ); 159 | } 160 | 161 | return $user_id; 162 | } 163 | 164 | /** 165 | * Generate an order. 166 | * @param [type] $from [description] 167 | * @param [type] $customer [description] 168 | * @return [type] [description] 169 | */ 170 | public static function order( $from, $customer ) { 171 | global $wpdb; 172 | 173 | // use the factory to create a Faker\Generator instance 174 | $faker = \Faker\Factory::create(); 175 | 176 | $user = false; 177 | // if no customer, order is for a guest 178 | if ( $customer ) { 179 | // have an int, find the customer - otherwise create a customer 180 | if ( is_int( $customer ) ) { 181 | // find matching user 182 | $wpUser = get_user_by( 'ID', $customer ); 183 | $user = $wpUser ? $customer : false; 184 | 185 | // make sure $from is at most the # of days ago customer was created 186 | $registeredDiff = Carbon::parse($wpUser->user_registered)->diffInDays(Carbon::now()); 187 | $from = $registeredDiff < $from ? $registeredDiff + 1 : $from; 188 | } else { 189 | $user = self::customer( $from ); 190 | } 191 | } 192 | 193 | 194 | // dates for the order/customer 195 | $gmt_offset = get_option('gmt_offset'); 196 | $day = rand(0, $from); 197 | $hour = rand(0, 23); 198 | $minute = rand(1, 5); 199 | $new_date = date( 'Y-m-d H:i:s', strtotime("-$day day -$hour hour") ); 200 | $gmt_new_date = date( 'Y-m-d H:i:s', strtotime("-$day day -$hour hour -$gmt_offset hour") ); 201 | 202 | // figure out the order status 203 | $statuses = [ 204 | 'completed' => 80, 205 | 'processing' => 5, 206 | 'on-hold' => 5, 207 | 'failed' => 10, 208 | ]; 209 | 210 | $status = Helpers::getRandomWeightedElement($statuses); 211 | // create base order 212 | $data = [ 213 | 'customer_id' => absint( $user ), 214 | 'status' => $status, 215 | 'created_via' => 'wc-cyclone', 216 | 'customer_ip_address' => $faker->ipv4, 217 | 'customer_user_agent' => $faker->userAgent, 218 | ]; 219 | $order = wc_create_order($data); 220 | 221 | // get all products 222 | $products = $wpdb->get_col("SELECT ID FROM {$wpdb->prefix}posts WHERE post_type = 'product'"); 223 | foreach ( $products as $product_id ) { 224 | $product_ids[] = $product_id; 225 | } 226 | 227 | // add random products to order 228 | $count = ( count($product_ids) < 50 ? count($product_ids) : 50); 229 | for ( $i = 0; $i < rand( 1, $count ); $i++ ) { 230 | // get random product id & unset so we don't add twice 231 | $key = rand(1, count($product_ids)) - 1; 232 | $id = $product_ids[$key]; 233 | 234 | // unset item and reset array keys 235 | unset($product_ids[$key]); 236 | $product_ids = array_values($product_ids); 237 | 238 | $quantities = apply_filters('wc_cyclone_order_items_count', [ 239 | 1 => 50, 240 | 2 => 25, 241 | 3 => 15, 242 | 4 => 8, 243 | 5 => 2, 244 | ]); 245 | 246 | if (is_object(wc_get_product($id))) { 247 | $quantity = Helpers::getRandomWeightedElement($quantities); 248 | $order->add_product( wc_get_product($id), $quantity ); 249 | } 250 | } 251 | 252 | // no user? let's generate guest info 253 | if (! $user) { 254 | $info = Helpers::userInfo(); 255 | } 256 | 257 | // create addresses 258 | $billing = [ 259 | 'country' => $user ? get_user_meta( $user, 'billing_country', true ) : $info['address']['country'], 260 | 'first_name'=> $user ? get_user_meta( $user, 'billing_first_name', true ) : $info['first_name'], 261 | 'last_name' => $user ? get_user_meta( $user, 'billing_last_name', true ) : $info['last_name'], 262 | 'company' => '', 263 | 'address_1' => $user ? get_user_meta( $user, 'billing_address_1', true ) : $info['address']['street'], 264 | 'address_2' => '', 265 | 'city' => $user ? get_user_meta( $user, 'billing_city', true ) : $info['address']['city'], 266 | 'state' => $user ? get_user_meta( $user, 'billing_state', true ) : $info['address']['state'], 267 | 'postcode' => $user ? get_user_meta( $user, 'billing_postcode', true ) : $info['address']['postcode'], 268 | 'email' => $user ? get_user_meta( $user, 'billing_email', true ) : $info['email'], 269 | 'phone' => $user ? get_user_meta( $user, 'billing_phone', true ) : $info['address']['phone'], 270 | ]; 271 | $shipping = [ 272 | 'country' => $user ? get_user_meta( $user, 'shipping_country', true ) : $info['address']['country'], 273 | 'first_name'=> $user ? get_user_meta( $user, 'shipping_first_name', true ) : $info['first_name'], 274 | 'last_name' => $user ? get_user_meta( $user, 'shipping_last_name', true ) : $info['last_name'], 275 | 'company' => '', 276 | 'address_1' => $user ? get_user_meta( $user, 'shipping_address_1', true ) : $info['address']['street'], 277 | 'address_2' => '', 278 | 'city' => $user ? get_user_meta( $user, 'shipping_city', true ) : $info['address']['city'], 279 | 'state' => $user ? get_user_meta( $user, 'shipping_state', true ) : $info['address']['state'], 280 | 'postcode' => $user ? get_user_meta( $user, 'shipping_postcode', true ) : $info['address']['postcode'], 281 | 'email' => $user ? get_user_meta( $user, 'shipping_email', true ) : $info['email'], 282 | 'phone' => $user ? get_user_meta( $user, 'shipping_phone', true ) : $info['address']['phone'], 283 | ]; 284 | 285 | // attach addresses to order 286 | $order->set_address( $billing, 'billing' ); 287 | $order->set_address( $shipping, 'shipping' ); 288 | 289 | // @todo apply coupon sometimes 290 | // @todo sometimes add fee 291 | 292 | $order->calculate_totals(); 293 | $order_id = $order->get_id(); 294 | 295 | if ( $order_id ) { 296 | $gateways = [ 297 | 'bacs' => 20, 298 | 'stripe' => 40, 299 | 'paypal' => 30, 300 | 'cod' => 10, 301 | ]; 302 | 303 | $gateway = Helpers::getRandomWeightedElement($gateways); 304 | update_post_meta( $order_id, '_payment_method', $gateway ); 305 | update_post_meta( $order_id, '_payment_method_title', ucfirst($gateway) ); 306 | // @todo more stripe/paypal data like customer id, payment id, etc. 307 | 308 | // @todo more shipping methods + adding line items for them 309 | update_post_meta( $order_id, '_shipping_method', 'free_shipping' ); 310 | update_post_meta( $order_id, '_shipping_method_title', 'Free Shipping' ); 311 | 312 | foreach ( $data as $key => $value ) { 313 | update_post_meta( $order_id, '_'.$key, $value ); 314 | } 315 | 316 | // paid? 317 | $paid_odds = [ 318 | 'paid' => 90, 319 | 'not_paid' => 10, 320 | ]; 321 | $paid = Helpers::getRandomWeightedElement($paid_odds); 322 | 323 | if ($paid == 'paid') { 324 | $id = strtoupper($gateway) . $faker->ean13; 325 | $order->payment_complete($id); 326 | update_post_meta( $order->get_id(), '_paid_date', $new_date ); 327 | } 328 | 329 | // update order date 330 | wp_update_post([ 331 | 'ID' => $order->get_id(), 332 | 'post_date' => $new_date, 333 | 'post_modified' => $new_date, 334 | 'post_date_gmt' => $gmt_new_date, 335 | 'post_modified_gmt' => $gmt_new_date, 336 | ]); 337 | } 338 | 339 | return true; 340 | } 341 | } 342 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "1ece1403c21f68ef4d48a68f07873800", 8 | "packages": [ 9 | { 10 | "name": "carbonphp/carbon-doctrine-types", 11 | "version": "3.2.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", 15 | "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", 20 | "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^8.1" 25 | }, 26 | "conflict": { 27 | "doctrine/dbal": "<4.0.0 || >=5.0.0" 28 | }, 29 | "require-dev": { 30 | "doctrine/dbal": "^4.0.0", 31 | "nesbot/carbon": "^2.71.0 || ^3.0.0", 32 | "phpunit/phpunit": "^10.3" 33 | }, 34 | "type": "library", 35 | "autoload": { 36 | "psr-4": { 37 | "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" 38 | } 39 | }, 40 | "notification-url": "https://packagist.org/downloads/", 41 | "license": [ 42 | "MIT" 43 | ], 44 | "authors": [ 45 | { 46 | "name": "KyleKatarn", 47 | "email": "kylekatarnls@gmail.com" 48 | } 49 | ], 50 | "description": "Types to use Carbon in Doctrine", 51 | "keywords": [ 52 | "carbon", 53 | "date", 54 | "datetime", 55 | "doctrine", 56 | "time" 57 | ], 58 | "support": { 59 | "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", 60 | "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" 61 | }, 62 | "funding": [ 63 | { 64 | "url": "https://github.com/kylekatarnls", 65 | "type": "github" 66 | }, 67 | { 68 | "url": "https://opencollective.com/Carbon", 69 | "type": "open_collective" 70 | }, 71 | { 72 | "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", 73 | "type": "tidelift" 74 | } 75 | ], 76 | "time": "2024-02-09T16:56:22+00:00" 77 | }, 78 | { 79 | "name": "crewlabs/unsplash", 80 | "version": "3.2.1", 81 | "source": { 82 | "type": "git", 83 | "url": "https://github.com/unsplash/unsplash-php.git", 84 | "reference": "cdb174beaf62d187db1a777cf5fb11ee554d85cf" 85 | }, 86 | "dist": { 87 | "type": "zip", 88 | "url": "https://api.github.com/repos/unsplash/unsplash-php/zipball/cdb174beaf62d187db1a777cf5fb11ee554d85cf", 89 | "reference": "cdb174beaf62d187db1a777cf5fb11ee554d85cf", 90 | "shasum": "" 91 | }, 92 | "require": { 93 | "guzzlehttp/guzzle": "^6.3.0|^7.0", 94 | "hughbertd/oauth2-unsplash": ">=1.0.3", 95 | "league/oauth2-client": ">=1.4.2", 96 | "php": ">=7.3.0" 97 | }, 98 | "require-dev": { 99 | "mockery/mockery": "~1.4.0", 100 | "php-vcr/php-vcr": "~1.4", 101 | "php-vcr/phpunit-testlistener-vcr": "~3.1", 102 | "phpunit/phpunit": "~9.0", 103 | "vlucas/phpdotenv": "~4.1.4" 104 | }, 105 | "type": "library", 106 | "autoload": { 107 | "psr-4": { 108 | "Unsplash\\": "src/" 109 | } 110 | }, 111 | "notification-url": "https://packagist.org/downloads/", 112 | "license": [ 113 | "MIT" 114 | ], 115 | "authors": [ 116 | { 117 | "name": "Aaron Klaassen", 118 | "email": "aaron@unsplash.com" 119 | }, 120 | { 121 | "name": "Luke Chesser", 122 | "email": "luke@unsplash.com" 123 | }, 124 | { 125 | "name": "Charles Lalonde", 126 | "email": "charles@pickcrew.com" 127 | }, 128 | { 129 | "name": "Hugh Downer", 130 | "email": "hugh.downer@gmail.com" 131 | } 132 | ], 133 | "description": "Wrapper to access the Unsplash API and photo library", 134 | "support": { 135 | "issues": "https://github.com/unsplash/unsplash-php/issues", 136 | "source": "https://github.com/unsplash/unsplash-php/tree/3.2.1" 137 | }, 138 | "time": "2022-01-17T20:32:58+00:00" 139 | }, 140 | { 141 | "name": "fakerphp/faker", 142 | "version": "v1.24.1", 143 | "source": { 144 | "type": "git", 145 | "url": "https://github.com/FakerPHP/Faker.git", 146 | "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" 147 | }, 148 | "dist": { 149 | "type": "zip", 150 | "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", 151 | "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", 152 | "shasum": "" 153 | }, 154 | "require": { 155 | "php": "^7.4 || ^8.0", 156 | "psr/container": "^1.0 || ^2.0", 157 | "symfony/deprecation-contracts": "^2.2 || ^3.0" 158 | }, 159 | "conflict": { 160 | "fzaninotto/faker": "*" 161 | }, 162 | "require-dev": { 163 | "bamarni/composer-bin-plugin": "^1.4.1", 164 | "doctrine/persistence": "^1.3 || ^2.0", 165 | "ext-intl": "*", 166 | "phpunit/phpunit": "^9.5.26", 167 | "symfony/phpunit-bridge": "^5.4.16" 168 | }, 169 | "suggest": { 170 | "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", 171 | "ext-curl": "Required by Faker\\Provider\\Image to download images.", 172 | "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", 173 | "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", 174 | "ext-mbstring": "Required for multibyte Unicode string functionality." 175 | }, 176 | "type": "library", 177 | "autoload": { 178 | "psr-4": { 179 | "Faker\\": "src/Faker/" 180 | } 181 | }, 182 | "notification-url": "https://packagist.org/downloads/", 183 | "license": [ 184 | "MIT" 185 | ], 186 | "authors": [ 187 | { 188 | "name": "François Zaninotto" 189 | } 190 | ], 191 | "description": "Faker is a PHP library that generates fake data for you.", 192 | "keywords": [ 193 | "data", 194 | "faker", 195 | "fixtures" 196 | ], 197 | "support": { 198 | "issues": "https://github.com/FakerPHP/Faker/issues", 199 | "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" 200 | }, 201 | "time": "2024-11-21T13:46:39+00:00" 202 | }, 203 | { 204 | "name": "guzzlehttp/guzzle", 205 | "version": "7.9.3", 206 | "source": { 207 | "type": "git", 208 | "url": "https://github.com/guzzle/guzzle.git", 209 | "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77" 210 | }, 211 | "dist": { 212 | "type": "zip", 213 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", 214 | "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", 215 | "shasum": "" 216 | }, 217 | "require": { 218 | "ext-json": "*", 219 | "guzzlehttp/promises": "^1.5.3 || ^2.0.3", 220 | "guzzlehttp/psr7": "^2.7.0", 221 | "php": "^7.2.5 || ^8.0", 222 | "psr/http-client": "^1.0", 223 | "symfony/deprecation-contracts": "^2.2 || ^3.0" 224 | }, 225 | "provide": { 226 | "psr/http-client-implementation": "1.0" 227 | }, 228 | "require-dev": { 229 | "bamarni/composer-bin-plugin": "^1.8.2", 230 | "ext-curl": "*", 231 | "guzzle/client-integration-tests": "3.0.2", 232 | "php-http/message-factory": "^1.1", 233 | "phpunit/phpunit": "^8.5.39 || ^9.6.20", 234 | "psr/log": "^1.1 || ^2.0 || ^3.0" 235 | }, 236 | "suggest": { 237 | "ext-curl": "Required for CURL handler support", 238 | "ext-intl": "Required for Internationalized Domain Name (IDN) support", 239 | "psr/log": "Required for using the Log middleware" 240 | }, 241 | "type": "library", 242 | "extra": { 243 | "bamarni-bin": { 244 | "bin-links": true, 245 | "forward-command": false 246 | } 247 | }, 248 | "autoload": { 249 | "files": [ 250 | "src/functions_include.php" 251 | ], 252 | "psr-4": { 253 | "GuzzleHttp\\": "src/" 254 | } 255 | }, 256 | "notification-url": "https://packagist.org/downloads/", 257 | "license": [ 258 | "MIT" 259 | ], 260 | "authors": [ 261 | { 262 | "name": "Graham Campbell", 263 | "email": "hello@gjcampbell.co.uk", 264 | "homepage": "https://github.com/GrahamCampbell" 265 | }, 266 | { 267 | "name": "Michael Dowling", 268 | "email": "mtdowling@gmail.com", 269 | "homepage": "https://github.com/mtdowling" 270 | }, 271 | { 272 | "name": "Jeremy Lindblom", 273 | "email": "jeremeamia@gmail.com", 274 | "homepage": "https://github.com/jeremeamia" 275 | }, 276 | { 277 | "name": "George Mponos", 278 | "email": "gmponos@gmail.com", 279 | "homepage": "https://github.com/gmponos" 280 | }, 281 | { 282 | "name": "Tobias Nyholm", 283 | "email": "tobias.nyholm@gmail.com", 284 | "homepage": "https://github.com/Nyholm" 285 | }, 286 | { 287 | "name": "Márk Sági-Kazár", 288 | "email": "mark.sagikazar@gmail.com", 289 | "homepage": "https://github.com/sagikazarmark" 290 | }, 291 | { 292 | "name": "Tobias Schultze", 293 | "email": "webmaster@tubo-world.de", 294 | "homepage": "https://github.com/Tobion" 295 | } 296 | ], 297 | "description": "Guzzle is a PHP HTTP client library", 298 | "keywords": [ 299 | "client", 300 | "curl", 301 | "framework", 302 | "http", 303 | "http client", 304 | "psr-18", 305 | "psr-7", 306 | "rest", 307 | "web service" 308 | ], 309 | "support": { 310 | "issues": "https://github.com/guzzle/guzzle/issues", 311 | "source": "https://github.com/guzzle/guzzle/tree/7.9.3" 312 | }, 313 | "funding": [ 314 | { 315 | "url": "https://github.com/GrahamCampbell", 316 | "type": "github" 317 | }, 318 | { 319 | "url": "https://github.com/Nyholm", 320 | "type": "github" 321 | }, 322 | { 323 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", 324 | "type": "tidelift" 325 | } 326 | ], 327 | "time": "2025-03-27T13:37:11+00:00" 328 | }, 329 | { 330 | "name": "guzzlehttp/promises", 331 | "version": "2.2.0", 332 | "source": { 333 | "type": "git", 334 | "url": "https://github.com/guzzle/promises.git", 335 | "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c" 336 | }, 337 | "dist": { 338 | "type": "zip", 339 | "url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c", 340 | "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c", 341 | "shasum": "" 342 | }, 343 | "require": { 344 | "php": "^7.2.5 || ^8.0" 345 | }, 346 | "require-dev": { 347 | "bamarni/composer-bin-plugin": "^1.8.2", 348 | "phpunit/phpunit": "^8.5.39 || ^9.6.20" 349 | }, 350 | "type": "library", 351 | "extra": { 352 | "bamarni-bin": { 353 | "bin-links": true, 354 | "forward-command": false 355 | } 356 | }, 357 | "autoload": { 358 | "psr-4": { 359 | "GuzzleHttp\\Promise\\": "src/" 360 | } 361 | }, 362 | "notification-url": "https://packagist.org/downloads/", 363 | "license": [ 364 | "MIT" 365 | ], 366 | "authors": [ 367 | { 368 | "name": "Graham Campbell", 369 | "email": "hello@gjcampbell.co.uk", 370 | "homepage": "https://github.com/GrahamCampbell" 371 | }, 372 | { 373 | "name": "Michael Dowling", 374 | "email": "mtdowling@gmail.com", 375 | "homepage": "https://github.com/mtdowling" 376 | }, 377 | { 378 | "name": "Tobias Nyholm", 379 | "email": "tobias.nyholm@gmail.com", 380 | "homepage": "https://github.com/Nyholm" 381 | }, 382 | { 383 | "name": "Tobias Schultze", 384 | "email": "webmaster@tubo-world.de", 385 | "homepage": "https://github.com/Tobion" 386 | } 387 | ], 388 | "description": "Guzzle promises library", 389 | "keywords": [ 390 | "promise" 391 | ], 392 | "support": { 393 | "issues": "https://github.com/guzzle/promises/issues", 394 | "source": "https://github.com/guzzle/promises/tree/2.2.0" 395 | }, 396 | "funding": [ 397 | { 398 | "url": "https://github.com/GrahamCampbell", 399 | "type": "github" 400 | }, 401 | { 402 | "url": "https://github.com/Nyholm", 403 | "type": "github" 404 | }, 405 | { 406 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", 407 | "type": "tidelift" 408 | } 409 | ], 410 | "time": "2025-03-27T13:27:01+00:00" 411 | }, 412 | { 413 | "name": "guzzlehttp/psr7", 414 | "version": "2.7.1", 415 | "source": { 416 | "type": "git", 417 | "url": "https://github.com/guzzle/psr7.git", 418 | "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16" 419 | }, 420 | "dist": { 421 | "type": "zip", 422 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16", 423 | "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16", 424 | "shasum": "" 425 | }, 426 | "require": { 427 | "php": "^7.2.5 || ^8.0", 428 | "psr/http-factory": "^1.0", 429 | "psr/http-message": "^1.1 || ^2.0", 430 | "ralouphie/getallheaders": "^3.0" 431 | }, 432 | "provide": { 433 | "psr/http-factory-implementation": "1.0", 434 | "psr/http-message-implementation": "1.0" 435 | }, 436 | "require-dev": { 437 | "bamarni/composer-bin-plugin": "^1.8.2", 438 | "http-interop/http-factory-tests": "0.9.0", 439 | "phpunit/phpunit": "^8.5.39 || ^9.6.20" 440 | }, 441 | "suggest": { 442 | "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" 443 | }, 444 | "type": "library", 445 | "extra": { 446 | "bamarni-bin": { 447 | "bin-links": true, 448 | "forward-command": false 449 | } 450 | }, 451 | "autoload": { 452 | "psr-4": { 453 | "GuzzleHttp\\Psr7\\": "src/" 454 | } 455 | }, 456 | "notification-url": "https://packagist.org/downloads/", 457 | "license": [ 458 | "MIT" 459 | ], 460 | "authors": [ 461 | { 462 | "name": "Graham Campbell", 463 | "email": "hello@gjcampbell.co.uk", 464 | "homepage": "https://github.com/GrahamCampbell" 465 | }, 466 | { 467 | "name": "Michael Dowling", 468 | "email": "mtdowling@gmail.com", 469 | "homepage": "https://github.com/mtdowling" 470 | }, 471 | { 472 | "name": "George Mponos", 473 | "email": "gmponos@gmail.com", 474 | "homepage": "https://github.com/gmponos" 475 | }, 476 | { 477 | "name": "Tobias Nyholm", 478 | "email": "tobias.nyholm@gmail.com", 479 | "homepage": "https://github.com/Nyholm" 480 | }, 481 | { 482 | "name": "Márk Sági-Kazár", 483 | "email": "mark.sagikazar@gmail.com", 484 | "homepage": "https://github.com/sagikazarmark" 485 | }, 486 | { 487 | "name": "Tobias Schultze", 488 | "email": "webmaster@tubo-world.de", 489 | "homepage": "https://github.com/Tobion" 490 | }, 491 | { 492 | "name": "Márk Sági-Kazár", 493 | "email": "mark.sagikazar@gmail.com", 494 | "homepage": "https://sagikazarmark.hu" 495 | } 496 | ], 497 | "description": "PSR-7 message implementation that also provides common utility methods", 498 | "keywords": [ 499 | "http", 500 | "message", 501 | "psr-7", 502 | "request", 503 | "response", 504 | "stream", 505 | "uri", 506 | "url" 507 | ], 508 | "support": { 509 | "issues": "https://github.com/guzzle/psr7/issues", 510 | "source": "https://github.com/guzzle/psr7/tree/2.7.1" 511 | }, 512 | "funding": [ 513 | { 514 | "url": "https://github.com/GrahamCampbell", 515 | "type": "github" 516 | }, 517 | { 518 | "url": "https://github.com/Nyholm", 519 | "type": "github" 520 | }, 521 | { 522 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", 523 | "type": "tidelift" 524 | } 525 | ], 526 | "time": "2025-03-27T12:30:47+00:00" 527 | }, 528 | { 529 | "name": "hughbertd/oauth2-unsplash", 530 | "version": "1.0.3", 531 | "source": { 532 | "type": "git", 533 | "url": "https://github.com/HughbertD/oauth2-unsplash.git", 534 | "reference": "f451f4a49dca4027f6edaa850d2fccdfa8721bfe" 535 | }, 536 | "dist": { 537 | "type": "zip", 538 | "url": "https://api.github.com/repos/HughbertD/oauth2-unsplash/zipball/f451f4a49dca4027f6edaa850d2fccdfa8721bfe", 539 | "reference": "f451f4a49dca4027f6edaa850d2fccdfa8721bfe", 540 | "shasum": "" 541 | }, 542 | "require": { 543 | "league/oauth2-client": ">=1.0", 544 | "php": ">=5.6.0" 545 | }, 546 | "require-dev": { 547 | "mockery/mockery": "~0.9", 548 | "phpunit/phpunit": "~5.0" 549 | }, 550 | "type": "library", 551 | "autoload": { 552 | "psr-4": { 553 | "Unsplash\\OAuth2\\Client\\": "src/" 554 | } 555 | }, 556 | "notification-url": "https://packagist.org/downloads/", 557 | "license": [ 558 | "MIT" 559 | ], 560 | "authors": [ 561 | { 562 | "name": "Hugh Downer", 563 | "email": "hugh.downer@gmail.com" 564 | } 565 | ], 566 | "description": "Unsplash OAuth 2.0 Client Provider for The PHP League OAuth2-Client", 567 | "keywords": [ 568 | "Authentication", 569 | "SSO", 570 | "Unsplash", 571 | "authorization", 572 | "identity", 573 | "idp", 574 | "oauth", 575 | "oauth2", 576 | "single sign on" 577 | ], 578 | "support": { 579 | "issues": "https://github.com/HughbertD/oauth2-unsplash/issues", 580 | "source": "https://github.com/HughbertD/oauth2-unsplash/tree/master" 581 | }, 582 | "time": "2017-12-14T13:08:42+00:00" 583 | }, 584 | { 585 | "name": "league/oauth2-client", 586 | "version": "2.8.1", 587 | "source": { 588 | "type": "git", 589 | "url": "https://github.com/thephpleague/oauth2-client.git", 590 | "reference": "9df2924ca644736c835fc60466a3a60390d334f9" 591 | }, 592 | "dist": { 593 | "type": "zip", 594 | "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/9df2924ca644736c835fc60466a3a60390d334f9", 595 | "reference": "9df2924ca644736c835fc60466a3a60390d334f9", 596 | "shasum": "" 597 | }, 598 | "require": { 599 | "ext-json": "*", 600 | "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", 601 | "php": "^7.1 || >=8.0.0 <8.5.0" 602 | }, 603 | "require-dev": { 604 | "mockery/mockery": "^1.3.5", 605 | "php-parallel-lint/php-parallel-lint": "^1.4", 606 | "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", 607 | "squizlabs/php_codesniffer": "^3.11" 608 | }, 609 | "type": "library", 610 | "autoload": { 611 | "psr-4": { 612 | "League\\OAuth2\\Client\\": "src/" 613 | } 614 | }, 615 | "notification-url": "https://packagist.org/downloads/", 616 | "license": [ 617 | "MIT" 618 | ], 619 | "authors": [ 620 | { 621 | "name": "Alex Bilbie", 622 | "email": "hello@alexbilbie.com", 623 | "homepage": "http://www.alexbilbie.com", 624 | "role": "Developer" 625 | }, 626 | { 627 | "name": "Woody Gilk", 628 | "homepage": "https://github.com/shadowhand", 629 | "role": "Contributor" 630 | } 631 | ], 632 | "description": "OAuth 2.0 Client Library", 633 | "keywords": [ 634 | "Authentication", 635 | "SSO", 636 | "authorization", 637 | "identity", 638 | "idp", 639 | "oauth", 640 | "oauth2", 641 | "single sign on" 642 | ], 643 | "support": { 644 | "issues": "https://github.com/thephpleague/oauth2-client/issues", 645 | "source": "https://github.com/thephpleague/oauth2-client/tree/2.8.1" 646 | }, 647 | "time": "2025-02-26T04:37:30+00:00" 648 | }, 649 | { 650 | "name": "nesbot/carbon", 651 | "version": "2.73.0", 652 | "source": { 653 | "type": "git", 654 | "url": "https://github.com/CarbonPHP/carbon.git", 655 | "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075" 656 | }, 657 | "dist": { 658 | "type": "zip", 659 | "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/9228ce90e1035ff2f0db84b40ec2e023ed802075", 660 | "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075", 661 | "shasum": "" 662 | }, 663 | "require": { 664 | "carbonphp/carbon-doctrine-types": "*", 665 | "ext-json": "*", 666 | "php": "^7.1.8 || ^8.0", 667 | "psr/clock": "^1.0", 668 | "symfony/polyfill-mbstring": "^1.0", 669 | "symfony/polyfill-php80": "^1.16", 670 | "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" 671 | }, 672 | "provide": { 673 | "psr/clock-implementation": "1.0" 674 | }, 675 | "require-dev": { 676 | "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0", 677 | "doctrine/orm": "^2.7 || ^3.0", 678 | "friendsofphp/php-cs-fixer": "^3.0", 679 | "kylekatarnls/multi-tester": "^2.0", 680 | "ondrejmirtes/better-reflection": "<6", 681 | "phpmd/phpmd": "^2.9", 682 | "phpstan/extension-installer": "^1.0", 683 | "phpstan/phpstan": "^0.12.99 || ^1.7.14", 684 | "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", 685 | "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", 686 | "squizlabs/php_codesniffer": "^3.4" 687 | }, 688 | "bin": [ 689 | "bin/carbon" 690 | ], 691 | "type": "library", 692 | "extra": { 693 | "laravel": { 694 | "providers": [ 695 | "Carbon\\Laravel\\ServiceProvider" 696 | ] 697 | }, 698 | "phpstan": { 699 | "includes": [ 700 | "extension.neon" 701 | ] 702 | }, 703 | "branch-alias": { 704 | "dev-2.x": "2.x-dev", 705 | "dev-master": "3.x-dev" 706 | } 707 | }, 708 | "autoload": { 709 | "psr-4": { 710 | "Carbon\\": "src/Carbon/" 711 | } 712 | }, 713 | "notification-url": "https://packagist.org/downloads/", 714 | "license": [ 715 | "MIT" 716 | ], 717 | "authors": [ 718 | { 719 | "name": "Brian Nesbitt", 720 | "email": "brian@nesbot.com", 721 | "homepage": "https://markido.com" 722 | }, 723 | { 724 | "name": "kylekatarnls", 725 | "homepage": "https://github.com/kylekatarnls" 726 | } 727 | ], 728 | "description": "An API extension for DateTime that supports 281 different languages.", 729 | "homepage": "https://carbon.nesbot.com", 730 | "keywords": [ 731 | "date", 732 | "datetime", 733 | "time" 734 | ], 735 | "support": { 736 | "docs": "https://carbon.nesbot.com/docs", 737 | "issues": "https://github.com/briannesbitt/Carbon/issues", 738 | "source": "https://github.com/briannesbitt/Carbon" 739 | }, 740 | "funding": [ 741 | { 742 | "url": "https://github.com/sponsors/kylekatarnls", 743 | "type": "github" 744 | }, 745 | { 746 | "url": "https://opencollective.com/Carbon#sponsor", 747 | "type": "opencollective" 748 | }, 749 | { 750 | "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", 751 | "type": "tidelift" 752 | } 753 | ], 754 | "time": "2025-01-08T20:10:23+00:00" 755 | }, 756 | { 757 | "name": "psr/clock", 758 | "version": "1.0.0", 759 | "source": { 760 | "type": "git", 761 | "url": "https://github.com/php-fig/clock.git", 762 | "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" 763 | }, 764 | "dist": { 765 | "type": "zip", 766 | "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", 767 | "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", 768 | "shasum": "" 769 | }, 770 | "require": { 771 | "php": "^7.0 || ^8.0" 772 | }, 773 | "type": "library", 774 | "autoload": { 775 | "psr-4": { 776 | "Psr\\Clock\\": "src/" 777 | } 778 | }, 779 | "notification-url": "https://packagist.org/downloads/", 780 | "license": [ 781 | "MIT" 782 | ], 783 | "authors": [ 784 | { 785 | "name": "PHP-FIG", 786 | "homepage": "https://www.php-fig.org/" 787 | } 788 | ], 789 | "description": "Common interface for reading the clock.", 790 | "homepage": "https://github.com/php-fig/clock", 791 | "keywords": [ 792 | "clock", 793 | "now", 794 | "psr", 795 | "psr-20", 796 | "time" 797 | ], 798 | "support": { 799 | "issues": "https://github.com/php-fig/clock/issues", 800 | "source": "https://github.com/php-fig/clock/tree/1.0.0" 801 | }, 802 | "time": "2022-11-25T14:36:26+00:00" 803 | }, 804 | { 805 | "name": "psr/container", 806 | "version": "2.0.2", 807 | "source": { 808 | "type": "git", 809 | "url": "https://github.com/php-fig/container.git", 810 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" 811 | }, 812 | "dist": { 813 | "type": "zip", 814 | "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", 815 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", 816 | "shasum": "" 817 | }, 818 | "require": { 819 | "php": ">=7.4.0" 820 | }, 821 | "type": "library", 822 | "extra": { 823 | "branch-alias": { 824 | "dev-master": "2.0.x-dev" 825 | } 826 | }, 827 | "autoload": { 828 | "psr-4": { 829 | "Psr\\Container\\": "src/" 830 | } 831 | }, 832 | "notification-url": "https://packagist.org/downloads/", 833 | "license": [ 834 | "MIT" 835 | ], 836 | "authors": [ 837 | { 838 | "name": "PHP-FIG", 839 | "homepage": "https://www.php-fig.org/" 840 | } 841 | ], 842 | "description": "Common Container Interface (PHP FIG PSR-11)", 843 | "homepage": "https://github.com/php-fig/container", 844 | "keywords": [ 845 | "PSR-11", 846 | "container", 847 | "container-interface", 848 | "container-interop", 849 | "psr" 850 | ], 851 | "support": { 852 | "issues": "https://github.com/php-fig/container/issues", 853 | "source": "https://github.com/php-fig/container/tree/2.0.2" 854 | }, 855 | "time": "2021-11-05T16:47:00+00:00" 856 | }, 857 | { 858 | "name": "psr/http-client", 859 | "version": "1.0.3", 860 | "source": { 861 | "type": "git", 862 | "url": "https://github.com/php-fig/http-client.git", 863 | "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" 864 | }, 865 | "dist": { 866 | "type": "zip", 867 | "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", 868 | "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", 869 | "shasum": "" 870 | }, 871 | "require": { 872 | "php": "^7.0 || ^8.0", 873 | "psr/http-message": "^1.0 || ^2.0" 874 | }, 875 | "type": "library", 876 | "extra": { 877 | "branch-alias": { 878 | "dev-master": "1.0.x-dev" 879 | } 880 | }, 881 | "autoload": { 882 | "psr-4": { 883 | "Psr\\Http\\Client\\": "src/" 884 | } 885 | }, 886 | "notification-url": "https://packagist.org/downloads/", 887 | "license": [ 888 | "MIT" 889 | ], 890 | "authors": [ 891 | { 892 | "name": "PHP-FIG", 893 | "homepage": "https://www.php-fig.org/" 894 | } 895 | ], 896 | "description": "Common interface for HTTP clients", 897 | "homepage": "https://github.com/php-fig/http-client", 898 | "keywords": [ 899 | "http", 900 | "http-client", 901 | "psr", 902 | "psr-18" 903 | ], 904 | "support": { 905 | "source": "https://github.com/php-fig/http-client" 906 | }, 907 | "time": "2023-09-23T14:17:50+00:00" 908 | }, 909 | { 910 | "name": "psr/http-factory", 911 | "version": "1.1.0", 912 | "source": { 913 | "type": "git", 914 | "url": "https://github.com/php-fig/http-factory.git", 915 | "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" 916 | }, 917 | "dist": { 918 | "type": "zip", 919 | "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", 920 | "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", 921 | "shasum": "" 922 | }, 923 | "require": { 924 | "php": ">=7.1", 925 | "psr/http-message": "^1.0 || ^2.0" 926 | }, 927 | "type": "library", 928 | "extra": { 929 | "branch-alias": { 930 | "dev-master": "1.0.x-dev" 931 | } 932 | }, 933 | "autoload": { 934 | "psr-4": { 935 | "Psr\\Http\\Message\\": "src/" 936 | } 937 | }, 938 | "notification-url": "https://packagist.org/downloads/", 939 | "license": [ 940 | "MIT" 941 | ], 942 | "authors": [ 943 | { 944 | "name": "PHP-FIG", 945 | "homepage": "https://www.php-fig.org/" 946 | } 947 | ], 948 | "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", 949 | "keywords": [ 950 | "factory", 951 | "http", 952 | "message", 953 | "psr", 954 | "psr-17", 955 | "psr-7", 956 | "request", 957 | "response" 958 | ], 959 | "support": { 960 | "source": "https://github.com/php-fig/http-factory" 961 | }, 962 | "time": "2024-04-15T12:06:14+00:00" 963 | }, 964 | { 965 | "name": "psr/http-message", 966 | "version": "2.0", 967 | "source": { 968 | "type": "git", 969 | "url": "https://github.com/php-fig/http-message.git", 970 | "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" 971 | }, 972 | "dist": { 973 | "type": "zip", 974 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", 975 | "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", 976 | "shasum": "" 977 | }, 978 | "require": { 979 | "php": "^7.2 || ^8.0" 980 | }, 981 | "type": "library", 982 | "extra": { 983 | "branch-alias": { 984 | "dev-master": "2.0.x-dev" 985 | } 986 | }, 987 | "autoload": { 988 | "psr-4": { 989 | "Psr\\Http\\Message\\": "src/" 990 | } 991 | }, 992 | "notification-url": "https://packagist.org/downloads/", 993 | "license": [ 994 | "MIT" 995 | ], 996 | "authors": [ 997 | { 998 | "name": "PHP-FIG", 999 | "homepage": "https://www.php-fig.org/" 1000 | } 1001 | ], 1002 | "description": "Common interface for HTTP messages", 1003 | "homepage": "https://github.com/php-fig/http-message", 1004 | "keywords": [ 1005 | "http", 1006 | "http-message", 1007 | "psr", 1008 | "psr-7", 1009 | "request", 1010 | "response" 1011 | ], 1012 | "support": { 1013 | "source": "https://github.com/php-fig/http-message/tree/2.0" 1014 | }, 1015 | "time": "2023-04-04T09:54:51+00:00" 1016 | }, 1017 | { 1018 | "name": "ralouphie/getallheaders", 1019 | "version": "3.0.3", 1020 | "source": { 1021 | "type": "git", 1022 | "url": "https://github.com/ralouphie/getallheaders.git", 1023 | "reference": "120b605dfeb996808c31b6477290a714d356e822" 1024 | }, 1025 | "dist": { 1026 | "type": "zip", 1027 | "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", 1028 | "reference": "120b605dfeb996808c31b6477290a714d356e822", 1029 | "shasum": "" 1030 | }, 1031 | "require": { 1032 | "php": ">=5.6" 1033 | }, 1034 | "require-dev": { 1035 | "php-coveralls/php-coveralls": "^2.1", 1036 | "phpunit/phpunit": "^5 || ^6.5" 1037 | }, 1038 | "type": "library", 1039 | "autoload": { 1040 | "files": [ 1041 | "src/getallheaders.php" 1042 | ] 1043 | }, 1044 | "notification-url": "https://packagist.org/downloads/", 1045 | "license": [ 1046 | "MIT" 1047 | ], 1048 | "authors": [ 1049 | { 1050 | "name": "Ralph Khattar", 1051 | "email": "ralph.khattar@gmail.com" 1052 | } 1053 | ], 1054 | "description": "A polyfill for getallheaders.", 1055 | "support": { 1056 | "issues": "https://github.com/ralouphie/getallheaders/issues", 1057 | "source": "https://github.com/ralouphie/getallheaders/tree/develop" 1058 | }, 1059 | "time": "2019-03-08T08:55:37+00:00" 1060 | }, 1061 | { 1062 | "name": "symfony/deprecation-contracts", 1063 | "version": "v3.6.0", 1064 | "source": { 1065 | "type": "git", 1066 | "url": "https://github.com/symfony/deprecation-contracts.git", 1067 | "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" 1068 | }, 1069 | "dist": { 1070 | "type": "zip", 1071 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", 1072 | "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", 1073 | "shasum": "" 1074 | }, 1075 | "require": { 1076 | "php": ">=8.1" 1077 | }, 1078 | "type": "library", 1079 | "extra": { 1080 | "thanks": { 1081 | "url": "https://github.com/symfony/contracts", 1082 | "name": "symfony/contracts" 1083 | }, 1084 | "branch-alias": { 1085 | "dev-main": "3.6-dev" 1086 | } 1087 | }, 1088 | "autoload": { 1089 | "files": [ 1090 | "function.php" 1091 | ] 1092 | }, 1093 | "notification-url": "https://packagist.org/downloads/", 1094 | "license": [ 1095 | "MIT" 1096 | ], 1097 | "authors": [ 1098 | { 1099 | "name": "Nicolas Grekas", 1100 | "email": "p@tchwork.com" 1101 | }, 1102 | { 1103 | "name": "Symfony Community", 1104 | "homepage": "https://symfony.com/contributors" 1105 | } 1106 | ], 1107 | "description": "A generic function and convention to trigger deprecation notices", 1108 | "homepage": "https://symfony.com", 1109 | "support": { 1110 | "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" 1111 | }, 1112 | "funding": [ 1113 | { 1114 | "url": "https://symfony.com/sponsor", 1115 | "type": "custom" 1116 | }, 1117 | { 1118 | "url": "https://github.com/fabpot", 1119 | "type": "github" 1120 | }, 1121 | { 1122 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1123 | "type": "tidelift" 1124 | } 1125 | ], 1126 | "time": "2024-09-25T14:21:43+00:00" 1127 | }, 1128 | { 1129 | "name": "symfony/polyfill-mbstring", 1130 | "version": "v1.32.0", 1131 | "source": { 1132 | "type": "git", 1133 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1134 | "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" 1135 | }, 1136 | "dist": { 1137 | "type": "zip", 1138 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", 1139 | "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", 1140 | "shasum": "" 1141 | }, 1142 | "require": { 1143 | "ext-iconv": "*", 1144 | "php": ">=7.2" 1145 | }, 1146 | "provide": { 1147 | "ext-mbstring": "*" 1148 | }, 1149 | "suggest": { 1150 | "ext-mbstring": "For best performance" 1151 | }, 1152 | "type": "library", 1153 | "extra": { 1154 | "thanks": { 1155 | "url": "https://github.com/symfony/polyfill", 1156 | "name": "symfony/polyfill" 1157 | } 1158 | }, 1159 | "autoload": { 1160 | "files": [ 1161 | "bootstrap.php" 1162 | ], 1163 | "psr-4": { 1164 | "Symfony\\Polyfill\\Mbstring\\": "" 1165 | } 1166 | }, 1167 | "notification-url": "https://packagist.org/downloads/", 1168 | "license": [ 1169 | "MIT" 1170 | ], 1171 | "authors": [ 1172 | { 1173 | "name": "Nicolas Grekas", 1174 | "email": "p@tchwork.com" 1175 | }, 1176 | { 1177 | "name": "Symfony Community", 1178 | "homepage": "https://symfony.com/contributors" 1179 | } 1180 | ], 1181 | "description": "Symfony polyfill for the Mbstring extension", 1182 | "homepage": "https://symfony.com", 1183 | "keywords": [ 1184 | "compatibility", 1185 | "mbstring", 1186 | "polyfill", 1187 | "portable", 1188 | "shim" 1189 | ], 1190 | "support": { 1191 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" 1192 | }, 1193 | "funding": [ 1194 | { 1195 | "url": "https://symfony.com/sponsor", 1196 | "type": "custom" 1197 | }, 1198 | { 1199 | "url": "https://github.com/fabpot", 1200 | "type": "github" 1201 | }, 1202 | { 1203 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1204 | "type": "tidelift" 1205 | } 1206 | ], 1207 | "time": "2024-12-23T08:48:59+00:00" 1208 | }, 1209 | { 1210 | "name": "symfony/polyfill-php80", 1211 | "version": "v1.32.0", 1212 | "source": { 1213 | "type": "git", 1214 | "url": "https://github.com/symfony/polyfill-php80.git", 1215 | "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" 1216 | }, 1217 | "dist": { 1218 | "type": "zip", 1219 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", 1220 | "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", 1221 | "shasum": "" 1222 | }, 1223 | "require": { 1224 | "php": ">=7.2" 1225 | }, 1226 | "type": "library", 1227 | "extra": { 1228 | "thanks": { 1229 | "url": "https://github.com/symfony/polyfill", 1230 | "name": "symfony/polyfill" 1231 | } 1232 | }, 1233 | "autoload": { 1234 | "files": [ 1235 | "bootstrap.php" 1236 | ], 1237 | "psr-4": { 1238 | "Symfony\\Polyfill\\Php80\\": "" 1239 | }, 1240 | "classmap": [ 1241 | "Resources/stubs" 1242 | ] 1243 | }, 1244 | "notification-url": "https://packagist.org/downloads/", 1245 | "license": [ 1246 | "MIT" 1247 | ], 1248 | "authors": [ 1249 | { 1250 | "name": "Ion Bazan", 1251 | "email": "ion.bazan@gmail.com" 1252 | }, 1253 | { 1254 | "name": "Nicolas Grekas", 1255 | "email": "p@tchwork.com" 1256 | }, 1257 | { 1258 | "name": "Symfony Community", 1259 | "homepage": "https://symfony.com/contributors" 1260 | } 1261 | ], 1262 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 1263 | "homepage": "https://symfony.com", 1264 | "keywords": [ 1265 | "compatibility", 1266 | "polyfill", 1267 | "portable", 1268 | "shim" 1269 | ], 1270 | "support": { 1271 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" 1272 | }, 1273 | "funding": [ 1274 | { 1275 | "url": "https://symfony.com/sponsor", 1276 | "type": "custom" 1277 | }, 1278 | { 1279 | "url": "https://github.com/fabpot", 1280 | "type": "github" 1281 | }, 1282 | { 1283 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1284 | "type": "tidelift" 1285 | } 1286 | ], 1287 | "time": "2025-01-02T08:10:11+00:00" 1288 | }, 1289 | { 1290 | "name": "symfony/translation", 1291 | "version": "v6.4.23", 1292 | "source": { 1293 | "type": "git", 1294 | "url": "https://github.com/symfony/translation.git", 1295 | "reference": "de8afa521e04a5220e9e58a1dc99971ab7cac643" 1296 | }, 1297 | "dist": { 1298 | "type": "zip", 1299 | "url": "https://api.github.com/repos/symfony/translation/zipball/de8afa521e04a5220e9e58a1dc99971ab7cac643", 1300 | "reference": "de8afa521e04a5220e9e58a1dc99971ab7cac643", 1301 | "shasum": "" 1302 | }, 1303 | "require": { 1304 | "php": ">=8.1", 1305 | "symfony/deprecation-contracts": "^2.5|^3", 1306 | "symfony/polyfill-mbstring": "~1.0", 1307 | "symfony/translation-contracts": "^2.5|^3.0" 1308 | }, 1309 | "conflict": { 1310 | "symfony/config": "<5.4", 1311 | "symfony/console": "<5.4", 1312 | "symfony/dependency-injection": "<5.4", 1313 | "symfony/http-client-contracts": "<2.5", 1314 | "symfony/http-kernel": "<5.4", 1315 | "symfony/service-contracts": "<2.5", 1316 | "symfony/twig-bundle": "<5.4", 1317 | "symfony/yaml": "<5.4" 1318 | }, 1319 | "provide": { 1320 | "symfony/translation-implementation": "2.3|3.0" 1321 | }, 1322 | "require-dev": { 1323 | "nikic/php-parser": "^4.18|^5.0", 1324 | "psr/log": "^1|^2|^3", 1325 | "symfony/config": "^5.4|^6.0|^7.0", 1326 | "symfony/console": "^5.4|^6.0|^7.0", 1327 | "symfony/dependency-injection": "^5.4|^6.0|^7.0", 1328 | "symfony/finder": "^5.4|^6.0|^7.0", 1329 | "symfony/http-client-contracts": "^2.5|^3.0", 1330 | "symfony/http-kernel": "^5.4|^6.0|^7.0", 1331 | "symfony/intl": "^5.4|^6.0|^7.0", 1332 | "symfony/polyfill-intl-icu": "^1.21", 1333 | "symfony/routing": "^5.4|^6.0|^7.0", 1334 | "symfony/service-contracts": "^2.5|^3", 1335 | "symfony/yaml": "^5.4|^6.0|^7.0" 1336 | }, 1337 | "type": "library", 1338 | "autoload": { 1339 | "files": [ 1340 | "Resources/functions.php" 1341 | ], 1342 | "psr-4": { 1343 | "Symfony\\Component\\Translation\\": "" 1344 | }, 1345 | "exclude-from-classmap": [ 1346 | "/Tests/" 1347 | ] 1348 | }, 1349 | "notification-url": "https://packagist.org/downloads/", 1350 | "license": [ 1351 | "MIT" 1352 | ], 1353 | "authors": [ 1354 | { 1355 | "name": "Fabien Potencier", 1356 | "email": "fabien@symfony.com" 1357 | }, 1358 | { 1359 | "name": "Symfony Community", 1360 | "homepage": "https://symfony.com/contributors" 1361 | } 1362 | ], 1363 | "description": "Provides tools to internationalize your application", 1364 | "homepage": "https://symfony.com", 1365 | "support": { 1366 | "source": "https://github.com/symfony/translation/tree/v6.4.23" 1367 | }, 1368 | "funding": [ 1369 | { 1370 | "url": "https://symfony.com/sponsor", 1371 | "type": "custom" 1372 | }, 1373 | { 1374 | "url": "https://github.com/fabpot", 1375 | "type": "github" 1376 | }, 1377 | { 1378 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1379 | "type": "tidelift" 1380 | } 1381 | ], 1382 | "time": "2025-06-26T21:24:02+00:00" 1383 | }, 1384 | { 1385 | "name": "symfony/translation-contracts", 1386 | "version": "v3.6.0", 1387 | "source": { 1388 | "type": "git", 1389 | "url": "https://github.com/symfony/translation-contracts.git", 1390 | "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d" 1391 | }, 1392 | "dist": { 1393 | "type": "zip", 1394 | "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d", 1395 | "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d", 1396 | "shasum": "" 1397 | }, 1398 | "require": { 1399 | "php": ">=8.1" 1400 | }, 1401 | "type": "library", 1402 | "extra": { 1403 | "thanks": { 1404 | "url": "https://github.com/symfony/contracts", 1405 | "name": "symfony/contracts" 1406 | }, 1407 | "branch-alias": { 1408 | "dev-main": "3.6-dev" 1409 | } 1410 | }, 1411 | "autoload": { 1412 | "psr-4": { 1413 | "Symfony\\Contracts\\Translation\\": "" 1414 | }, 1415 | "exclude-from-classmap": [ 1416 | "/Test/" 1417 | ] 1418 | }, 1419 | "notification-url": "https://packagist.org/downloads/", 1420 | "license": [ 1421 | "MIT" 1422 | ], 1423 | "authors": [ 1424 | { 1425 | "name": "Nicolas Grekas", 1426 | "email": "p@tchwork.com" 1427 | }, 1428 | { 1429 | "name": "Symfony Community", 1430 | "homepage": "https://symfony.com/contributors" 1431 | } 1432 | ], 1433 | "description": "Generic abstractions related to translation", 1434 | "homepage": "https://symfony.com", 1435 | "keywords": [ 1436 | "abstractions", 1437 | "contracts", 1438 | "decoupling", 1439 | "interfaces", 1440 | "interoperability", 1441 | "standards" 1442 | ], 1443 | "support": { 1444 | "source": "https://github.com/symfony/translation-contracts/tree/v3.6.0" 1445 | }, 1446 | "funding": [ 1447 | { 1448 | "url": "https://symfony.com/sponsor", 1449 | "type": "custom" 1450 | }, 1451 | { 1452 | "url": "https://github.com/fabpot", 1453 | "type": "github" 1454 | }, 1455 | { 1456 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1457 | "type": "tidelift" 1458 | } 1459 | ], 1460 | "time": "2024-09-27T08:32:26+00:00" 1461 | } 1462 | ], 1463 | "packages-dev": [], 1464 | "aliases": [], 1465 | "minimum-stability": "stable", 1466 | "stability-flags": {}, 1467 | "prefer-stable": false, 1468 | "prefer-lowest": false, 1469 | "platform": {}, 1470 | "platform-dev": {}, 1471 | "plugin-api-version": "2.6.0" 1472 | } 1473 | --------------------------------------------------------------------------------