Version Description
- New: Add special admin notice if plugin is not tested with latest WordPress version
- New: Compatible up to WordPress 5.5.2
New: Allow deleting of orphaned staging site entries if staging site was deleted manually before
Fix: Activation hook is not fired after first time installation and wpstg optimizer and cron tasks are not set up
Fix: Staging site does not work if database password contains dollar sign in password
Fix: Prevent fatal error when the plugin is activated, but there is no permission to create folder wp-content/uploads/wp-staging or wp-content/uploads/wp-staging/logs.
Dev: Add new DI container implementation
Dev: Add composer 2
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 2.7.8 |
Comparing to | |
See all releases |
Code changes from version 2.7.7 to 2.7.8
- Backend/Administrator.php +2 -2
- Backend/Modules/Jobs/CloningProcess.php +50 -11
- Backend/Modules/Jobs/Database.php +1 -1
- Backend/Modules/Jobs/Delete.php +42 -25
- Backend/Notices/Notices.php +66 -42
- Backend/views/_main/header.php +2 -2
- Backend/views/clone/ajax/delete-confirmation.php +19 -15
- Backend/views/clone/ajax/mail-setting.php +1 -1
- Backend/views/clone/multi-site/index.php +1 -1
- Backend/views/clone/staging-site/index.php +2 -2
- Backend/views/notices/cache-directory-permission-problem.php +9 -3
- Backend/views/notices/logs-directory-permission-problem.php +9 -3
- Backend/views/notices/no-license-key.php +1 -1
- Backend/views/notices/rating.php +1 -1
- Backend/views/notices/transient.php +2 -2
- Backend/views/notices/uploads-cache-directory-permission-problem.php +0 -10
- Backend/views/notices/wp-version-compatible-message.php +1 -1
- Backend/views/welcome/welcome.php +3 -3
- Core/Utils/Cache.php +7 -1
- Core/Utils/Logger.php +7 -1
- Core/Utils/functions.php +5 -5
- Framework/CloningProcess/Data/UpdateWpConfigConstants.php +13 -4
- Requirements/WpstgFreeRequirements.php +125 -104
- _init.php +8 -45
- constants.php +35 -11
- install.php +14 -20
- readme.txt +25 -35
- vendor/composer/autoload_classmap.php +7 -0
- vendor/composer/autoload_namespaces.php +2 -0
- vendor/composer/autoload_static.php +25 -0
- vendor/composer/installed.json +109 -11
- vendor/lucatume/di52/.github/workflows/test-php-52.yml +17 -0
- vendor/lucatume/di52/.github/workflows/test.yml +33 -0
- vendor/lucatume/di52/.gitignore +11 -0
- vendor/lucatume/di52/.phpstorm.meta.php +9 -0
- vendor/lucatume/di52/CHANGELOG.md +232 -0
- vendor/lucatume/di52/README.md +688 -0
- vendor/lucatume/di52/_build/check_exports.sh +35 -0
- vendor/lucatume/di52/_build/composer-hash.sh +15 -0
- vendor/lucatume/di52/_build/containers/php-52/Dockerfile +3 -0
- vendor/lucatume/di52/_build/dir_hash.sh +16 -0
- vendor/lucatume/di52/_build/release.php +230 -0
- vendor/lucatume/di52/autoload.php +27 -0
- vendor/lucatume/di52/composer-5-3-plus.json +36 -0
- vendor/lucatume/di52/composer.json +53 -0
- vendor/lucatume/di52/composer.lock +535 -0
- vendor/lucatume/di52/makefile +38 -0
- vendor/lucatume/di52/phpunit.xml +17 -0
- vendor/lucatume/di52/src/tad/DI52/Container.php +906 -0
- vendor/lucatume/di52/src/tad/DI52/ContainerInterface.php +181 -0
- vendor/lucatume/di52/src/tad/DI52/ProtectedValue.php +27 -0
- vendor/lucatume/di52/src/tad/DI52/ServiceProvider.php +58 -0
- vendor/lucatume/di52/src/tad/DI52/ServiceProviderInterface.php +28 -0
- vendor/lucatume/di52/src/tad/DI52/closuresSupport.php +68 -0
- vendor/lucatume/di52/tests/52-compat/Container52CompatTest.php +1448 -0
- vendor/lucatume/di52/tests/52-compat/autoloadTest.php +32 -0
- vendor/lucatume/di52/tests/53-above/Container53CompatTest.php +811 -0
- vendor/lucatume/di52/tests/bootstrap.php +7 -0
- vendor/lucatume/di52/tests/data/namespaced-test-classes.php +170 -0
- vendor/lucatume/di52/tests/data/test-classes.php +435 -0
- vendor/lucatume/di52/tests/data/test-providers.php +80 -0
- vendor/lucatume/di52/todo.txt +1 -0
- vendor/symfony/polyfill-ctype/bootstrap.php +11 -11
- vendor/symfony/polyfill-ctype/composer.json +1 -1
- vendor/xrstf/composer-php52/.gitignore +1 -0
- vendor/xrstf/composer-php52/LICENSE +19 -0
- vendor/xrstf/composer-php52/README.md +37 -0
- vendor/xrstf/composer-php52/composer.json +26 -0
- vendor/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php +346 -0
- vendor/xrstf/composer-php52/lib/xrstf/Composer52/ClassLoader.php +271 -0
- vendor/xrstf/composer-php52/lib/xrstf/Composer52/Generator.php +39 -0
- wp-staging.php +23 -8
Backend/Administrator.php
CHANGED
@@ -712,12 +712,12 @@ class Administrator extends InjectionAware
|
|
712 |
*/
|
713 |
public function ajaxDeleteConfirmation()
|
714 |
{
|
715 |
-
if (
|
716 |
return false;
|
717 |
}
|
718 |
|
719 |
$delete = new Delete();
|
720 |
-
$delete->setData();
|
721 |
|
722 |
$clone = $delete->getClone();
|
723 |
|
712 |
*/
|
713 |
public function ajaxDeleteConfirmation()
|
714 |
{
|
715 |
+
if (!$this->isAuthenticated()) {
|
716 |
return false;
|
717 |
}
|
718 |
|
719 |
$delete = new Delete();
|
720 |
+
$isDatabaseConnected = $delete->setData();
|
721 |
|
722 |
$clone = $delete->getClone();
|
723 |
|
Backend/Modules/Jobs/CloningProcess.php
CHANGED
@@ -22,23 +22,62 @@ abstract class CloningProcess extends JobExecutable
|
|
22 |
protected function initializeDbObjects()
|
23 |
{
|
24 |
$this->productionDb = WPStaging::getInstance()->get("wpdb");
|
|
|
25 |
if ($this->isExternal()) {
|
26 |
-
$this->
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
return false;
|
31 |
}
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
exit;
|
38 |
}
|
39 |
-
|
40 |
-
|
|
|
|
|
41 |
}
|
|
|
42 |
}
|
43 |
|
44 |
protected function isExternal()
|
22 |
protected function initializeDbObjects()
|
23 |
{
|
24 |
$this->productionDb = WPStaging::getInstance()->get("wpdb");
|
25 |
+
|
26 |
if ($this->isExternal()) {
|
27 |
+
$this->setExternalDatabase();
|
28 |
+
} else {
|
29 |
+
$this->setLocalDatabase();
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
protected function setLocalDatabase()
|
34 |
+
{
|
35 |
+
$this->stagingDb = WPStaging::getInstance()->get("wpdb");
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @return bool
|
40 |
+
*/
|
41 |
+
protected function setExternalDatabase()
|
42 |
+
{
|
43 |
+
$this->stagingDb = new \wpdb($this->options->databaseUser, $this->options->databasePassword, $this->options->databaseDatabase, $this->options->databaseServer);
|
44 |
+
|
45 |
+
// Check if there were any error when connecting
|
46 |
+
if (
|
47 |
+
property_exists($this->stagingDb, 'error') &&
|
48 |
+
$this->stagingDb->error instanceof \WP_Error
|
49 |
+
) {
|
50 |
+
/** @var \WP_Error $wp_error */
|
51 |
+
$wp_error = $this->stagingDb->error;
|
52 |
+
if ($wp_error->get_error_code() === 'db_connect_fail') {
|
53 |
+
$this->returnException(sprintf('Can not connect to external database %s. Reason: %s', $this->options->databaseDatabase, $wp_error->get_error_message()));
|
54 |
return false;
|
55 |
}
|
56 |
+
}
|
57 |
+
|
58 |
+
$this->stagingDb->select($this->options->databaseDatabase);
|
59 |
+
if (!$this->stagingDb->ready) {
|
60 |
+
if (
|
61 |
+
property_exists($this->stagingDb, 'error') &&
|
62 |
+
$this->stagingDb->error instanceof \WP_Error
|
63 |
+
) {
|
64 |
+
/** @var \WP_Error $wp_error */
|
65 |
+
$wp_error = $this->stagingDb->error;
|
66 |
+
if ($wp_error->get_error_code() === 'db_select_fail') {
|
67 |
+
$this->returnException($wp_error->get_error_message());
|
68 |
+
exit;
|
69 |
+
}
|
70 |
+
|
71 |
+
// Generic error
|
72 |
+
$this->returnException(sprintf('Error: Can\'t select database %s. Either it does not exist or you don\'t have privileges to access it.', $this->options->databaseDatabase));
|
73 |
exit;
|
74 |
}
|
75 |
+
|
76 |
+
// Generic error
|
77 |
+
$this->returnException(sprintf('Error: Can\'t select database %s. Either it does not exist or you don\'t have privileges to access it.', $this->options->databaseDatabase));
|
78 |
+
exit;
|
79 |
}
|
80 |
+
return true;
|
81 |
}
|
82 |
|
83 |
protected function isExternal()
|
Backend/Modules/Jobs/Database.php
CHANGED
@@ -150,7 +150,7 @@ class Database extends CloningProcess
|
|
150 |
if (defined('WPSTGPRO_VERSION')) {
|
151 |
return false;
|
152 |
}
|
153 |
-
$this->returnException(__("This staging site is located in another database and needs to be edited with <a href='https://wp-staging.com' target='_blank'>WP
|
154 |
return true;
|
155 |
}
|
156 |
|
150 |
if (defined('WPSTGPRO_VERSION')) {
|
151 |
return false;
|
152 |
}
|
153 |
+
$this->returnException(__("This staging site is located in another database and needs to be edited with <a href='https://wp-staging.com' target='_blank'>WP STAGING Pro</a>", "wp-staging"));
|
154 |
return true;
|
155 |
}
|
156 |
|
Backend/Modules/Jobs/Delete.php
CHANGED
@@ -3,7 +3,6 @@
|
|
3 |
namespace WPStaging\Backend\Modules\Jobs;
|
4 |
|
5 |
use WPStaging\Backend\Modules\Jobs\Exceptions\CloneNotFoundException;
|
6 |
-
use WPStaging\Utils\Directories;
|
7 |
use WPStaging\Utils\Logger;
|
8 |
use WPStaging\WPStaging;
|
9 |
|
@@ -14,13 +13,13 @@ use WPStaging\WPStaging;
|
|
14 |
class Delete extends Job {
|
15 |
|
16 |
/**
|
17 |
-
* @var
|
18 |
*/
|
19 |
private $clone = false;
|
20 |
|
21 |
/**
|
22 |
* The path to delete
|
23 |
-
* @var
|
24 |
*/
|
25 |
private $deleteDir = '';
|
26 |
|
@@ -61,22 +60,30 @@ class Delete extends Job {
|
|
61 |
/**
|
62 |
* Sets Clone and Table Records
|
63 |
* @param null|array $clone
|
|
|
64 |
*/
|
65 |
-
public function setData(
|
66 |
-
|
|
|
67 |
$this->getCloneRecords();
|
68 |
} else {
|
69 |
-
$this->clone
|
70 |
$this->forceDeleteDirectories = true;
|
71 |
}
|
72 |
|
73 |
-
if(
|
74 |
-
$this->wpdb =
|
75 |
-
|
76 |
-
|
77 |
}
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
79 |
$this->getTableRecords();
|
|
|
80 |
}
|
81 |
|
82 |
/**
|
@@ -88,7 +95,7 @@ class Delete extends Job {
|
|
88 |
|
89 |
/**
|
90 |
* Date database name
|
91 |
-
* @return
|
92 |
*/
|
93 |
public function getDbName() {
|
94 |
return $this->wpdb->dbname;
|
@@ -117,19 +124,17 @@ class Delete extends Job {
|
|
117 |
private function getCloneRecords( $name = null ) {
|
118 |
if( null === $name && !isset( $_POST["clone"] ) ) {
|
119 |
$this->log( "Clone name is not set", Logger::TYPE_FATAL );
|
120 |
-
//throw new CloneNotFoundException();
|
121 |
$this->returnException( "Clone name is not set" );
|
122 |
}
|
123 |
|
124 |
if( null === $name ) {
|
125 |
-
$name = $_POST["clone"];
|
126 |
}
|
127 |
|
128 |
$clones = get_option( "wpstg_existing_clones_beta", array() );
|
129 |
|
130 |
if( empty( $clones ) || !isset( $clones[$name] ) ) {
|
131 |
$this->log( "Couldn't find clone name {$name} or no existing clone", Logger::TYPE_FATAL );
|
132 |
-
//throw new CloneNotFoundException();
|
133 |
$this->returnException( "Couldn't find clone name {$name} or no existing clone" );
|
134 |
}
|
135 |
|
@@ -327,9 +332,9 @@ class Delete extends Job {
|
|
327 |
if( !$this->isExternalDatabase() && $this->startsWith( $table, $this->wpdb->prefix ) ) {
|
328 |
$this->log( "Fatal Error: Trying to delete table {$table} of main WP installation!", Logger::TYPE_CRITICAL );
|
329 |
return false;
|
330 |
-
} else {
|
331 |
-
$this->wpdb->query( "DROP TABLE {$table}" );
|
332 |
}
|
|
|
|
|
333 |
}
|
334 |
|
335 |
// Move on to the next
|
@@ -349,9 +354,9 @@ class Delete extends Job {
|
|
349 |
}
|
350 |
|
351 |
/**
|
|
|
352 |
* Delete complete directory including all files and subfolders
|
353 |
-
*
|
354 |
-
* @throws InvalidArgumentException
|
355 |
*/
|
356 |
public function deleteDirectory() {
|
357 |
if( $this->isFatalError() ) {
|
@@ -379,7 +384,6 @@ class Delete extends Job {
|
|
379 |
|
380 |
// Check if threshold is reached
|
381 |
if( $this->isOverThreshold() ) {
|
382 |
-
//$this->returnException('Maximum PHP execution time exceeded. Run again and repeat the deletion process until it is sucessfully finished.');
|
383 |
return;
|
384 |
}
|
385 |
|
@@ -389,7 +393,6 @@ class Delete extends Job {
|
|
389 |
foreach ( $ri as $file ) {
|
390 |
$this->deleteFile( $file );
|
391 |
if( $this->isOverThreshold() ) {
|
392 |
-
//$this->returnException('Maximum PHP execution time exceeded. Run again and repeat the deletion process until it is sucessfully finished.');
|
393 |
return;
|
394 |
}
|
395 |
}
|
@@ -458,10 +461,7 @@ class Delete extends Job {
|
|
458 |
*/
|
459 |
public function isFatalError() {
|
460 |
$homePath = rtrim( get_home_path(), "/" );
|
461 |
-
|
462 |
-
return true;
|
463 |
-
}
|
464 |
-
return false;
|
465 |
}
|
466 |
|
467 |
/**
|
@@ -495,4 +495,21 @@ class Delete extends Job {
|
|
495 |
wp_die( json_encode( $response ) );
|
496 |
}
|
497 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
498 |
}
|
3 |
namespace WPStaging\Backend\Modules\Jobs;
|
4 |
|
5 |
use WPStaging\Backend\Modules\Jobs\Exceptions\CloneNotFoundException;
|
|
|
6 |
use WPStaging\Utils\Logger;
|
7 |
use WPStaging\WPStaging;
|
8 |
|
13 |
class Delete extends Job {
|
14 |
|
15 |
/**
|
16 |
+
* @var \stdClass
|
17 |
*/
|
18 |
private $clone = false;
|
19 |
|
20 |
/**
|
21 |
* The path to delete
|
22 |
+
* @var string
|
23 |
*/
|
24 |
private $deleteDir = '';
|
25 |
|
60 |
/**
|
61 |
* Sets Clone and Table Records
|
62 |
* @param null|array $clone
|
63 |
+
* @return bool
|
64 |
*/
|
65 |
+
public function setData($clone = null)
|
66 |
+
{
|
67 |
+
if(!is_array($clone)) {
|
68 |
$this->getCloneRecords();
|
69 |
} else {
|
70 |
+
$this->clone = (object) $clone;
|
71 |
$this->forceDeleteDirectories = true;
|
72 |
}
|
73 |
|
74 |
+
if(!$this->isExternalDatabase()) {
|
75 |
+
$this->wpdb = WPStaging::getInstance()->get("wpdb");
|
76 |
+
$this->getTableRecords();
|
77 |
+
return true;
|
78 |
}
|
79 |
+
|
80 |
+
if ($this->isExternalDatabaseError()) {
|
81 |
+
return false;
|
82 |
+
}
|
83 |
+
|
84 |
+
$this->wpdb = $this->getStagingDb();
|
85 |
$this->getTableRecords();
|
86 |
+
return true;
|
87 |
}
|
88 |
|
89 |
/**
|
95 |
|
96 |
/**
|
97 |
* Date database name
|
98 |
+
* @return string
|
99 |
*/
|
100 |
public function getDbName() {
|
101 |
return $this->wpdb->dbname;
|
124 |
private function getCloneRecords( $name = null ) {
|
125 |
if( null === $name && !isset( $_POST["clone"] ) ) {
|
126 |
$this->log( "Clone name is not set", Logger::TYPE_FATAL );
|
|
|
127 |
$this->returnException( "Clone name is not set" );
|
128 |
}
|
129 |
|
130 |
if( null === $name ) {
|
131 |
+
$name = (string)$_POST["clone"];
|
132 |
}
|
133 |
|
134 |
$clones = get_option( "wpstg_existing_clones_beta", array() );
|
135 |
|
136 |
if( empty( $clones ) || !isset( $clones[$name] ) ) {
|
137 |
$this->log( "Couldn't find clone name {$name} or no existing clone", Logger::TYPE_FATAL );
|
|
|
138 |
$this->returnException( "Couldn't find clone name {$name} or no existing clone" );
|
139 |
}
|
140 |
|
332 |
if( !$this->isExternalDatabase() && $this->startsWith( $table, $this->wpdb->prefix ) ) {
|
333 |
$this->log( "Fatal Error: Trying to delete table {$table} of main WP installation!", Logger::TYPE_CRITICAL );
|
334 |
return false;
|
|
|
|
|
335 |
}
|
336 |
+
|
337 |
+
$this->wpdb->query( "DROP TABLE {$table}" );
|
338 |
}
|
339 |
|
340 |
// Move on to the next
|
354 |
}
|
355 |
|
356 |
/**
|
357 |
+
*
|
358 |
* Delete complete directory including all files and subfolders
|
359 |
+
* @throws \Exception
|
|
|
360 |
*/
|
361 |
public function deleteDirectory() {
|
362 |
if( $this->isFatalError() ) {
|
384 |
|
385 |
// Check if threshold is reached
|
386 |
if( $this->isOverThreshold() ) {
|
|
|
387 |
return;
|
388 |
}
|
389 |
|
393 |
foreach ( $ri as $file ) {
|
394 |
$this->deleteFile( $file );
|
395 |
if( $this->isOverThreshold() ) {
|
|
|
396 |
return;
|
397 |
}
|
398 |
}
|
461 |
*/
|
462 |
public function isFatalError() {
|
463 |
$homePath = rtrim( get_home_path(), "/" );
|
464 |
+
return rtrim($this->deleteDir, "/") == $homePath;
|
|
|
|
|
|
|
465 |
}
|
466 |
|
467 |
/**
|
495 |
wp_die( json_encode( $response ) );
|
496 |
}
|
497 |
|
498 |
+
/**
|
499 |
+
* Check if there is error in external database connection
|
500 |
+
* can happen if the external database does not exist or stored credentials are wrong
|
501 |
+
* @return bool
|
502 |
+
*
|
503 |
+
* @todo replace it logic with DbInfo once collation check PR is merged.
|
504 |
+
*/
|
505 |
+
private function isExternalDatabaseError()
|
506 |
+
{
|
507 |
+
$db = new \mysqli($this->clone->databaseServer, $this->clone->databaseUser, $this->clone->databasePassword, $this->clone->databaseDatabase);
|
508 |
+
if ($db->connect_error) {
|
509 |
+
return true;
|
510 |
+
}
|
511 |
+
|
512 |
+
return false;
|
513 |
+
}
|
514 |
+
|
515 |
}
|
Backend/Notices/Notices.php
CHANGED
@@ -7,18 +7,21 @@ namespace WPStaging\Backend\Notices;
|
|
7 |
*/
|
8 |
|
9 |
// No Direct Access
|
10 |
-
if(
|
11 |
die;
|
12 |
}
|
13 |
|
14 |
use WPStaging\Backend\Pro\Notices\Notices as ProNotices;
|
|
|
|
|
|
|
15 |
|
16 |
/**
|
17 |
* Class Notices
|
18 |
* @package WPStaging\Backend\Notices
|
19 |
*/
|
20 |
-
class Notices
|
21 |
-
|
22 |
/**
|
23 |
* @var string
|
24 |
*/
|
@@ -29,67 +32,81 @@ class Notices {
|
|
29 |
*/
|
30 |
private $url;
|
31 |
|
32 |
-
public function __construct(
|
|
|
33 |
$this->path = $path;
|
34 |
-
$this->url
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
* Check whether the page is admin page or not
|
39 |
* @return bool
|
40 |
*/
|
41 |
-
public function isAdminPage()
|
|
|
42 |
$currentPage = (isset( $_GET["page"] )) ? $_GET["page"] : null;
|
43 |
|
44 |
$availablePages = array(
|
45 |
"wpstg-settings", "wpstg-addons", "wpstg-tools", "wpstg-clone", "wpstg_clone"
|
46 |
);
|
47 |
|
48 |
-
if(
|
49 |
return false;
|
50 |
}
|
51 |
|
52 |
return true;
|
53 |
}
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
/**
|
56 |
* Check if notice should be shown after certain days of installation
|
57 |
* @param int $days default 10
|
58 |
* @return bool
|
59 |
*/
|
60 |
-
private function canShow(
|
61 |
-
|
62 |
// Do not show notice
|
63 |
-
if(
|
64 |
return false;
|
65 |
}
|
66 |
|
67 |
-
$dbOption = get_option(
|
68 |
|
69 |
// Do not show notice
|
70 |
-
if ("no" === $dbOption){
|
71 |
return false;
|
72 |
}
|
73 |
|
74 |
-
$now = new \DateTime(
|
75 |
|
76 |
// Check if user clicked on "rate later" button and if there is a valid 'later' date
|
77 |
-
if(
|
78 |
// Do not show before this date
|
79 |
-
$show = new \DateTime(
|
80 |
-
if ($now < $show){
|
81 |
return false;
|
82 |
}
|
83 |
}
|
84 |
|
85 |
|
86 |
// Show X days after installation
|
87 |
-
$installDate = new \DateTime(
|
88 |
|
89 |
// get number of days between installation date and today
|
90 |
-
$difference = $now->diff(
|
91 |
|
92 |
-
if(
|
93 |
return true;
|
94 |
}
|
95 |
|
@@ -100,8 +117,9 @@ class Notices {
|
|
100 |
* Get current page
|
101 |
* @return string | post, page
|
102 |
*/
|
103 |
-
private function getCurrentScreen()
|
104 |
-
|
|
|
105 |
return \get_current_screen()->post_type;
|
106 |
}
|
107 |
}
|
@@ -115,47 +133,52 @@ class Notices {
|
|
115 |
$viewsNoticesPath = "{$this->path}views/notices/";
|
116 |
|
117 |
// Show "rate the plugin". Free version only
|
118 |
-
if (
|
119 |
-
if ($this->canShow("wpstg_rating", 7)
|
120 |
require_once "{$viewsNoticesPath}rating.php";
|
121 |
}
|
122 |
|
123 |
}
|
124 |
|
125 |
// Show all pro version notices
|
126 |
-
if (
|
127 |
$proNotices = new ProNotices($this);
|
128 |
$proNotices->getNotices();
|
129 |
}
|
130 |
|
131 |
// Display notices below in wp staging admin pages only
|
132 |
-
if(
|
133 |
return;
|
134 |
}
|
135 |
|
136 |
-
// Cache directory
|
137 |
-
$
|
138 |
-
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
141 |
|
142 |
// Staging directory is not writable
|
143 |
-
if(
|
144 |
require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
|
145 |
}
|
146 |
|
147 |
-
// Version Control
|
148 |
-
if( version_compare(
|
149 |
require_once "{$viewsNoticesPath}wp-version-compatible-message.php";
|
150 |
}
|
151 |
|
152 |
-
// Beta
|
153 |
-
/*if( false === get_option( "wpstg_beta" ) || "no" !== get_option( "wpstg_beta" ) ) {
|
154 |
-
require_once "{$viewsNoticesPath}beta.php";
|
155 |
-
}*/
|
156 |
-
|
157 |
// Different scheme in home and siteurl
|
158 |
-
if(
|
159 |
require_once "{$viewsNoticesPath}wrong-scheme.php";
|
160 |
}
|
161 |
}
|
@@ -164,11 +187,12 @@ class Notices {
|
|
164 |
* Check if the url scheme of siteurl and home is identical
|
165 |
* @return boolean
|
166 |
*/
|
167 |
-
private function isDifferentScheme()
|
168 |
-
|
169 |
-
$
|
|
|
170 |
|
171 |
-
if(
|
172 |
return false;
|
173 |
}
|
174 |
return true;
|
7 |
*/
|
8 |
|
9 |
// No Direct Access
|
10 |
+
if (!defined("WPINC")) {
|
11 |
die;
|
12 |
}
|
13 |
|
14 |
use WPStaging\Backend\Pro\Notices\Notices as ProNotices;
|
15 |
+
use WPStaging\Utils\Cache;
|
16 |
+
use WPStaging\Utils\Logger;
|
17 |
+
use WPStaging\WPStaging;
|
18 |
|
19 |
/**
|
20 |
* Class Notices
|
21 |
* @package WPStaging\Backend\Notices
|
22 |
*/
|
23 |
+
class Notices
|
24 |
+
{
|
25 |
/**
|
26 |
* @var string
|
27 |
*/
|
32 |
*/
|
33 |
private $url;
|
34 |
|
35 |
+
public function __construct($path, $url)
|
36 |
+
{
|
37 |
$this->path = $path;
|
38 |
+
$this->url = $url;
|
39 |
}
|
40 |
|
41 |
/**
|
42 |
* Check whether the page is admin page or not
|
43 |
* @return bool
|
44 |
*/
|
45 |
+
public function isAdminPage()
|
46 |
+
{
|
47 |
$currentPage = (isset( $_GET["page"] )) ? $_GET["page"] : null;
|
48 |
|
49 |
$availablePages = array(
|
50 |
"wpstg-settings", "wpstg-addons", "wpstg-tools", "wpstg-clone", "wpstg_clone"
|
51 |
);
|
52 |
|
53 |
+
if(!is_admin() || !in_array( $currentPage, $availablePages, true)) {
|
54 |
return false;
|
55 |
}
|
56 |
|
57 |
return true;
|
58 |
}
|
59 |
|
60 |
+
/**
|
61 |
+
* check whether the plugin is pro version
|
62 |
+
*
|
63 |
+
* @todo Implement this in a separate class related to plugin. Then replace it with dependency injection. Add filters
|
64 |
+
*
|
65 |
+
* @return boolean
|
66 |
+
*/
|
67 |
+
protected function isPro()
|
68 |
+
{
|
69 |
+
return defined('WPSTGPRO_VERSION');
|
70 |
+
}
|
71 |
+
|
72 |
/**
|
73 |
* Check if notice should be shown after certain days of installation
|
74 |
* @param int $days default 10
|
75 |
* @return bool
|
76 |
*/
|
77 |
+
private function canShow($option, $days = 10)
|
78 |
+
{
|
79 |
// Do not show notice
|
80 |
+
if (empty($option)) {
|
81 |
return false;
|
82 |
}
|
83 |
|
84 |
+
$dbOption = get_option($option);
|
85 |
|
86 |
// Do not show notice
|
87 |
+
if ("no" === $dbOption) {
|
88 |
return false;
|
89 |
}
|
90 |
|
91 |
+
$now = new \DateTime("now");
|
92 |
|
93 |
// Check if user clicked on "rate later" button and if there is a valid 'later' date
|
94 |
+
if (wpstg_is_valid_date($dbOption)) {
|
95 |
// Do not show before this date
|
96 |
+
$show = new \DateTime($dbOption);
|
97 |
+
if ($now < $show) {
|
98 |
return false;
|
99 |
}
|
100 |
}
|
101 |
|
102 |
|
103 |
// Show X days after installation
|
104 |
+
$installDate = new \DateTime(get_option("wpstg_installDate"));
|
105 |
|
106 |
// get number of days between installation date and today
|
107 |
+
$difference = $now->diff($installDate)->days;
|
108 |
|
109 |
+
if ($days <= $difference) {
|
110 |
return true;
|
111 |
}
|
112 |
|
117 |
* Get current page
|
118 |
* @return string | post, page
|
119 |
*/
|
120 |
+
private function getCurrentScreen()
|
121 |
+
{
|
122 |
+
if (function_exists('get_current_screen')) {
|
123 |
return \get_current_screen()->post_type;
|
124 |
}
|
125 |
}
|
133 |
$viewsNoticesPath = "{$this->path}views/notices/";
|
134 |
|
135 |
// Show "rate the plugin". Free version only
|
136 |
+
if (!$this->isPro()) {
|
137 |
+
if ($this->canShow("wpstg_rating", 7) && $this->getCurrentScreen() !== 'page' && $this->getCurrentScreen() !== 'post') {
|
138 |
require_once "{$viewsNoticesPath}rating.php";
|
139 |
}
|
140 |
|
141 |
}
|
142 |
|
143 |
// Show all pro version notices
|
144 |
+
if ($this->isPro()) {
|
145 |
$proNotices = new ProNotices($this);
|
146 |
$proNotices->getNotices();
|
147 |
}
|
148 |
|
149 |
// Display notices below in wp staging admin pages only
|
150 |
+
if (!current_user_can("update_plugins") || !$this->isAdminPage()) {
|
151 |
return;
|
152 |
}
|
153 |
|
154 |
+
// Cache directory is not writable
|
155 |
+
/** @var Cache $cache */
|
156 |
+
$cache = WPStaging::getInstance()->get("cache");
|
157 |
+
$cacheDir = $cache->getCacheDir();
|
158 |
+
if (!is_dir($cacheDir) || !is_writable($cacheDir)) {
|
159 |
+
require_once "{$viewsNoticesPath}/cache-directory-permission-problem.php";
|
160 |
+
}
|
161 |
+
|
162 |
+
// Logger directory is not writable
|
163 |
+
/** @var Logger $logger */
|
164 |
+
$logger = WPStaging::getInstance()->get("logger");
|
165 |
+
$logsDir = $logger->getLogDir();
|
166 |
+
if (!is_dir($logsDir) || !is_writable($logsDir)) {
|
167 |
+
require_once "{$viewsNoticesPath}/logs-directory-permission-problem.php";
|
168 |
}
|
169 |
|
170 |
// Staging directory is not writable
|
171 |
+
if (!is_writeable(ABSPATH)) {
|
172 |
require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
|
173 |
}
|
174 |
|
175 |
+
// Version Control for Free
|
176 |
+
if(!$this->isPro() && version_compare(WPStaging::getInstance()->get('WPSTG_COMPATIBLE'), get_bloginfo("version"), "<")) {
|
177 |
require_once "{$viewsNoticesPath}wp-version-compatible-message.php";
|
178 |
}
|
179 |
|
|
|
|
|
|
|
|
|
|
|
180 |
// Different scheme in home and siteurl
|
181 |
+
if ($this->isDifferentScheme()) {
|
182 |
require_once "{$viewsNoticesPath}wrong-scheme.php";
|
183 |
}
|
184 |
}
|
187 |
* Check if the url scheme of siteurl and home is identical
|
188 |
* @return boolean
|
189 |
*/
|
190 |
+
private function isDifferentScheme()
|
191 |
+
{
|
192 |
+
$siteurlScheme = parse_url(get_option('siteurl'), PHP_URL_SCHEME);
|
193 |
+
$homeScheme = parse_url(get_option('home'), PHP_URL_SCHEME);
|
194 |
|
195 |
+
if ($siteurlScheme === $homeScheme) {
|
196 |
return false;
|
197 |
}
|
198 |
return true;
|
Backend/views/_main/header.php
CHANGED
@@ -49,8 +49,8 @@
|
|
49 |
?>
|
50 |
|
51 |
<div id="wpstg-update-notify" style="display:<?php echo $display; ?>">
|
52 |
-
<strong><?php echo sprintf( __( 'WP
|
53 |
-
<?php echo sprintf( __( 'Important: Please update WP
|
54 |
</div>
|
55 |
|
56 |
</div>
|
49 |
?>
|
50 |
|
51 |
<div id="wpstg-update-notify" style="display:<?php echo $display; ?>">
|
52 |
+
<strong><?php echo sprintf( __( 'WP STAGING Pro %s is available!', 'wp-staging' ), $version ); ?></strong> <br/>
|
53 |
+
<?php echo sprintf( __( 'Important: Please update WP STAGING Pro before pushing the staging site to production site. <a href="%s" target="_blank">What\'s New? ', 'wp-staging' ), 'https://wp-staging.com/wp-staging-pro-changelog' ); ?></a>
|
54 |
</div>
|
55 |
|
56 |
</div>
|
Backend/views/clone/ajax/delete-confirmation.php
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
-
|
2 |
-
|
|
|
3 |
<?php
|
4 |
-
_e("
|
5 |
?>
|
6 |
-
</
|
7 |
|
8 |
<p>
|
9 |
<?php _e('Clone Name:', 'wp-staging'); ?>
|
@@ -22,20 +23,22 @@
|
|
22 |
?>
|
23 |
</span>
|
24 |
</p>
|
|
|
|
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
?>
|
34 |
-
</p>
|
35 |
</div>
|
|
|
36 |
|
37 |
<div class="wpstg-tabs-wrapper">
|
38 |
|
|
|
39 |
<a href="#" class="wpstg-tab-header active" data-id="#wpstg-scanning-db">
|
40 |
<span class="wpstg-tab-triangle">►</span>
|
41 |
<?php echo __("Database tables to remove", "wp-staging")?>
|
@@ -48,7 +51,7 @@
|
|
48 |
</h4>
|
49 |
<div style="margin-bottom:6px;margin-top:6px;">
|
50 |
<a href="#" class="wpstg-button-unselect">
|
51 |
-
|
52 |
</a>
|
53 |
</div>
|
54 |
|
@@ -65,10 +68,11 @@
|
|
65 |
<?php endforeach ?>
|
66 |
<div style="margin-bottom:6px;margin-top:6px;">
|
67 |
<a href="#" class="wpstg-button-unselect">
|
68 |
-
|
69 |
</a>
|
70 |
</div>
|
71 |
</div>
|
|
|
72 |
<!-- /Database -->
|
73 |
|
74 |
<a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
|
1 |
+
<?php if ($isDatabaseConnected) { ?>
|
2 |
+
<div class="wpstg-notice-alert">
|
3 |
+
<h3 style="margin:0;padding-bottom:5px;">
|
4 |
<?php
|
5 |
+
_e("This staging site will be deleted:", "wp-staging")
|
6 |
?>
|
7 |
+
</h3>
|
8 |
|
9 |
<p>
|
10 |
<?php _e('Clone Name:', 'wp-staging'); ?>
|
23 |
?>
|
24 |
</span>
|
25 |
</p>
|
26 |
+
</div>
|
27 |
+
<?php } ?>
|
28 |
|
29 |
+
<?php if (!$isDatabaseConnected) { ?>
|
30 |
+
<div class="wpstg-notice-alert wpstg-failed">
|
31 |
+
<h4 class="wpstg-mb-0"><?php _e('Error: Can not connect to external database: ', 'wp-staging'); echo $clone->databaseDatabase; ?></h4>
|
32 |
+
<ul class="wpstg-mb-0">
|
33 |
+
<li><?php _e('This can happen if the password of the external database has been changed or if the database was deleted', 'wp-staging') ?></li>
|
34 |
+
<li><?php _e('You can still delete this staging site but deleting this site will not delete any table or database. You will have to delete them manually if they exist.', 'wp-staging') ?></li>
|
35 |
+
</ul>
|
|
|
|
|
36 |
</div>
|
37 |
+
<?php } ?>
|
38 |
|
39 |
<div class="wpstg-tabs-wrapper">
|
40 |
|
41 |
+
<?php if ($isDatabaseConnected) { ?>
|
42 |
<a href="#" class="wpstg-tab-header active" data-id="#wpstg-scanning-db">
|
43 |
<span class="wpstg-tab-triangle">►</span>
|
44 |
<?php echo __("Database tables to remove", "wp-staging")?>
|
51 |
</h4>
|
52 |
<div style="margin-bottom:6px;margin-top:6px;">
|
53 |
<a href="#" class="wpstg-button-unselect">
|
54 |
+
<?php _e("Unselect All", "wp-staging") ?>
|
55 |
</a>
|
56 |
</div>
|
57 |
|
68 |
<?php endforeach ?>
|
69 |
<div style="margin-bottom:6px;margin-top:6px;">
|
70 |
<a href="#" class="wpstg-button-unselect">
|
71 |
+
<?php _e("Unselect All", "wp-staging") ?>
|
72 |
</a>
|
73 |
</div>
|
74 |
</div>
|
75 |
+
<?php } ?>
|
76 |
<!-- /Database -->
|
77 |
|
78 |
<a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
|
Backend/views/clone/ajax/mail-setting.php
CHANGED
@@ -11,5 +11,5 @@
|
|
11 |
</div>
|
12 |
<p style="font-weight:bold;background-color:#e6e6e6;padding:15px;border-top: 1px solid white;margin-top: 20px;"><?php _e('That\'s a Pro Feature', 'wp-staging'); ?>
|
13 |
<br>
|
14 |
-
<a href="https://wp-staging.com/?utm_source=wp-admin&utm_medium=wp-admin&utm_campaign=db-external&utm_term=db-external" target="_blank" class="quads-button green wpstg-button" style="border-radius:3px;font-size: 14px;border: 1px solid white;"><?php _e("Get WP
|
15 |
</p>
|
11 |
</div>
|
12 |
<p style="font-weight:bold;background-color:#e6e6e6;padding:15px;border-top: 1px solid white;margin-top: 20px;"><?php _e('That\'s a Pro Feature', 'wp-staging'); ?>
|
13 |
<br>
|
14 |
+
<a href="https://wp-staging.com/?utm_source=wp-admin&utm_medium=wp-admin&utm_campaign=db-external&utm_term=db-external" target="_blank" class="quads-button green wpstg-button" style="border-radius:3px;font-size: 14px;border: 1px solid white;"><?php _e("Get WP STAGING Pro", "wp-staging"); ?></a>
|
15 |
</p>
|
Backend/views/clone/multi-site/index.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
<span class="wpstg-notice-alert" style="margin-top:20px;">
|
2 |
-
<?php echo sprintf(__('WordPress Multisite is not supported! Upgrade to <a href="%s" target="_blank">WP
|
3 |
</span>
|
1 |
<span class="wpstg-notice-alert" style="margin-top:20px;">
|
2 |
+
<?php echo sprintf(__('WordPress Multisite is not supported! Upgrade to <a href="%s" target="_blank">WP STAGING Pro</a>', 'wp-staging'), 'https://wp-staging.com/')?>
|
3 |
</span>
|
Backend/views/clone/staging-site/index.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<span class="wpstg-notice-alert" style="margin-top:20px;">
|
2 |
-
<?php echo __("This staging site can be pushed and modified with WP
|
3 |
<br/>
|
4 |
-
<?php echo sprintf(__("<a href='%s' target='_new'>Open WP
|
5 |
<br/>
|
6 |
<br/>
|
7 |
<?php echo sprintf(__("If you like to clone this staging site check out <a href='%s' target='_new'>this article</a>."), 'https://wp-staging.com/docs/cloning-a-staging-site-testing-push-method/'); ?>
|
1 |
<span class="wpstg-notice-alert" style="margin-top:20px;">
|
2 |
+
<?php echo __("This staging site can be pushed and modified with WP STAGING Pro plugin installed on your production site! Open WP Staging Pro on your production site and start the pushing process from there!", "wp-staging")?>
|
3 |
<br/>
|
4 |
+
<?php echo sprintf(__("<a href='%s' target='_new'>Open WP STAGING Pro on Live Site</a>"), wpstg_get_production_hostname() . '/wp-admin/admin.php?page=wpstg_clone'); ?>
|
5 |
<br/>
|
6 |
<br/>
|
7 |
<?php echo sprintf(__("If you like to clone this staging site check out <a href='%s' target='_new'>this article</a>."), 'https://wp-staging.com/docs/cloning-a-staging-site-testing-push-method/'); ?>
|
Backend/views/notices/cache-directory-permission-problem.php
CHANGED
@@ -1,7 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<div class="wpstg-error">
|
2 |
<p>
|
3 |
-
<strong>WP Staging Folder Permission error: </strong> <?php echo
|
4 |
<br>
|
5 |
-
Check if the folder <strong><?php echo
|
6 |
</p>
|
7 |
-
</div>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var string $cacheDir
|
4 |
+
* @see \WPStaging\Backend\Notices\Notices::messages
|
5 |
+
*/
|
6 |
+
?>
|
7 |
<div class="wpstg-error">
|
8 |
<p>
|
9 |
+
<strong>WP Staging Folder Permission error: </strong> <?php echo $cacheDir; ?> is not write and/or readable.
|
10 |
<br>
|
11 |
+
Check if the folder <strong><?php echo $cacheDir; ?></strong> exists! Folder permissions should be chmod 755 or higher.
|
12 |
</p>
|
13 |
+
</div>
|
Backend/views/notices/logs-directory-permission-problem.php
CHANGED
@@ -1,7 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<div class="wpstg-error">
|
2 |
<p>
|
3 |
-
<strong>WP Staging Folder Permission error: </strong> <?php echo
|
4 |
<br>
|
5 |
-
Check if the folder <strong><?php echo
|
6 |
</p>
|
7 |
-
</div>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var string $logsDir
|
4 |
+
* @see \WPStaging\Backend\Notices\Notices::messages
|
5 |
+
*/
|
6 |
+
?>
|
7 |
<div class="wpstg-error">
|
8 |
<p>
|
9 |
+
<strong>WP Staging Folder Permission error: </strong> <?php echo $logsDir; ?> is not write and/or readable.
|
10 |
<br>
|
11 |
+
Check if the folder <strong><?php echo $logsDir; ?></strong> exists! Folder permissions should be chmod 755 or higher.
|
12 |
</p>
|
13 |
+
</div>
|
Backend/views/notices/no-license-key.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
<p>
|
3 |
<?php
|
4 |
echo sprintf( __(
|
5 |
-
'You have no license key entered. WP
|
6 |
'<br/> <a href="%1$s" target="_blank">%1$s</a>', 'wp-staging'), 'https://wp-staging.com'
|
7 |
);
|
8 |
?>
|
2 |
<p>
|
3 |
<?php
|
4 |
echo sprintf( __(
|
5 |
+
'You have no license key entered. WP STAGING Pro needs a valid license key to be activated. You can purchase the license from here:' .
|
6 |
'<br/> <a href="%1$s" target="_blank">%1$s</a>', 'wp-staging'), 'https://wp-staging.com'
|
7 |
);
|
8 |
?>
|
Backend/views/notices/rating.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* @var $this \WPStaging\Backend\Notices\Notices
|
4 |
-
* @see \WPStaging\Backend\Notices\Notices::
|
5 |
*/
|
6 |
?>
|
7 |
<div class="wpstg_fivestar" style="display:none;box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); border-left:none; background-color:#59a7f7; color:white; padding: 10px; margin: 10px; margin-left: 0px;">
|
1 |
<?php
|
2 |
/**
|
3 |
* @var $this \WPStaging\Backend\Notices\Notices
|
4 |
+
* @see \WPStaging\Backend\Notices\Notices::showNotices
|
5 |
*/
|
6 |
?>
|
7 |
<div class="wpstg_fivestar" style="display:none;box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); border-left:none; background-color:#59a7f7; color:white; padding: 10px; margin: 10px; margin-left: 0px;">
|
Backend/views/notices/transient.php
CHANGED
@@ -3,8 +3,8 @@
|
|
3 |
<?php
|
4 |
echo esc_html(
|
5 |
('1' === $deactivatedNoticeID) ?
|
6 |
-
__("WP Staging and WP
|
7 |
-
__("WP Staging and WP
|
8 |
)
|
9 |
?>
|
10 |
</p>
|
3 |
<?php
|
4 |
echo esc_html(
|
5 |
('1' === $deactivatedNoticeID) ?
|
6 |
+
__("WP Staging and WP STAGING Pro cannot both be active. We've automatically deactivated WP STAGING.", "wp-staging"):
|
7 |
+
__("WP Staging and WP STAGING Pro cannot both be active. We've automatically deactivated WP STAGING Pro.", "wp-staging")
|
8 |
)
|
9 |
?>
|
10 |
</p>
|
Backend/views/notices/uploads-cache-directory-permission-problem.php
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
<div class="wpstg-error">
|
2 |
-
<p>
|
3 |
-
<strong>WP Staging Folder Permission error: </strong>
|
4 |
-
<?php echo \WPStaging\WPStaging::getContentDir()?>
|
5 |
-
is not write and/or readable.
|
6 |
-
<br>
|
7 |
-
Check if the folder <strong><?php echo \WPStaging\WPStaging::getContentDir()?></strong> exists!
|
8 |
-
Folder permissions should be chmod 755 or 777.
|
9 |
-
</p>
|
10 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Backend/views/notices/wp-version-compatible-message.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
<p>
|
3 |
<?php
|
4 |
echo sprintf( __(
|
5 |
-
'Your version of WP
|
6 |
'<br/><br/>WP STAGING has an enterprise-level quality control that performs a compatibility audit on every new WordPress release.' .
|
7 |
'<br/>We prioritize testing the Pro version of the plugin first, which receives the compatibility audit earlier than the Free version. If you are in a rush, upgrade to Pro today to get the latest version of WPSTAGING.' .
|
8 |
'<p><a href="%1$s" target="_blank"><strong>Get the latest version Now</strong></a>.', 'wp-staging'), 'https://wp-staging.com', get_bloginfo( 'version' )
|
2 |
<p>
|
3 |
<?php
|
4 |
echo sprintf( __(
|
5 |
+
'Your version of WP STAGING has not been tested with WordPress %2$s.' .
|
6 |
'<br/><br/>WP STAGING has an enterprise-level quality control that performs a compatibility audit on every new WordPress release.' .
|
7 |
'<br/>We prioritize testing the Pro version of the plugin first, which receives the compatibility audit earlier than the Free version. If you are in a rush, upgrade to Pro today to get the latest version of WPSTAGING.' .
|
8 |
'<p><a href="%1$s" target="_blank"><strong>Get the latest version Now</strong></a>.', 'wp-staging'), 'https://wp-staging.com', get_bloginfo( 'version' )
|
Backend/views/welcome/welcome.php
CHANGED
@@ -1,15 +1,15 @@
|
|
1 |
<div class="" id="wpstg-welcome">
|
2 |
<div style="border: 2px solid white;padding: 20px;margin-bottom:20px;">
|
3 |
<h2 class="wpstg-h2">
|
4 |
-
<span class="wpstg-heading-pro"><?php _e( 'WP
|
5 |
</h2>
|
6 |
<li><strong>Cloning</strong> - <?php _e( 'Create a clone of your website with a simple click', 'wp-staging' ); ?></li>
|
7 |
<li><strong>Push Changes</strong> - <?php _e( 'Copy plugin and theme files from staging to live site', 'wp-staging' ); ?></li>
|
8 |
<li><strong>Authentication</strong> - <?php _e( 'Staging Site is available to authenticated users only', 'wp-staging' ); ?></li>
|
9 |
<li><strong>High Performance</strong> - <?php _e( 'Cloning process is fast and does not slow down website loading', 'wp-staging' ); ?></li>
|
10 |
<li><strong>Secure</strong> - <?php _e( 'WP Staging is coded well for protection of your data', 'wp-staging' ); ?></li>
|
11 |
-
<li><strong>Multisites</strong> - <?php _e( 'WP
|
12 |
-
<a href="http://wp-staging.com/?utm_source=wpstg&utm_medium=addon_page&utm_term=click-wpstaging-pro&utm_campaign=wpstaging" target="_blank" class="wpstg-button green">Buy WP
|
13 |
<a href="<?php echo admin_url(); ?>admin.php?page=wpstg_clone" target="_self" style="margin-left:30px;">Skip - Start Cloning</a>
|
14 |
<div class="wpstg-footer"> <?php _e( 'Comes with our 30-day money back guarantee * You need to give us chance to resolve your issue first.', 'wp-staging' ); ?></div>
|
15 |
</div>
|
1 |
<div class="" id="wpstg-welcome">
|
2 |
<div style="border: 2px solid white;padding: 20px;margin-bottom:20px;">
|
3 |
<h2 class="wpstg-h2">
|
4 |
+
<span class="wpstg-heading-pro"><?php _e( 'WP STAGING Pro', 'wp-staging' ); ?></span><?php _e( ' - Copy Themes & Plugins from Staging to Live Site', 'wp-staging' ); ?>
|
5 |
</h2>
|
6 |
<li><strong>Cloning</strong> - <?php _e( 'Create a clone of your website with a simple click', 'wp-staging' ); ?></li>
|
7 |
<li><strong>Push Changes</strong> - <?php _e( 'Copy plugin and theme files from staging to live site', 'wp-staging' ); ?></li>
|
8 |
<li><strong>Authentication</strong> - <?php _e( 'Staging Site is available to authenticated users only', 'wp-staging' ); ?></li>
|
9 |
<li><strong>High Performance</strong> - <?php _e( 'Cloning process is fast and does not slow down website loading', 'wp-staging' ); ?></li>
|
10 |
<li><strong>Secure</strong> - <?php _e( 'WP Staging is coded well for protection of your data', 'wp-staging' ); ?></li>
|
11 |
+
<li><strong>Multisites</strong> - <?php _e( 'WP STAGING Pro allows to clone and push Multisites, (main site & sub sites)', 'wp-staging' ); ?></li>
|
12 |
+
<a href="http://wp-staging.com/?utm_source=wpstg&utm_medium=addon_page&utm_term=click-wpstaging-pro&utm_campaign=wpstaging" target="_blank" class="wpstg-button green">Buy WP STAGING Pro</a>
|
13 |
<a href="<?php echo admin_url(); ?>admin.php?page=wpstg_clone" target="_self" style="margin-left:30px;">Skip - Start Cloning</a>
|
14 |
<div class="wpstg-footer"> <?php _e( 'Comes with our 30-day money back guarantee * You need to give us chance to resolve your issue first.', 'wp-staging' ); ?></div>
|
15 |
</div>
|
Core/Utils/Cache.php
CHANGED
@@ -71,7 +71,13 @@ class Cache {
|
|
71 |
|
72 |
// If cache directory doesn't exists, create it
|
73 |
if( !is_dir( $this->cacheDir ) && !@mkdir( $this->cacheDir, 0775, true ) ) {
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
76 |
}
|
77 |
|
71 |
|
72 |
// If cache directory doesn't exists, create it
|
73 |
if( !is_dir( $this->cacheDir ) && !@mkdir( $this->cacheDir, 0775, true ) ) {
|
74 |
+
/**
|
75 |
+
* There's no need to throw this exception, which causes a fatal,
|
76 |
+
* as a warning is already displayed on:
|
77 |
+
*
|
78 |
+
* @see \WPStaging\Backend\Notices\Notices::messages
|
79 |
+
*/
|
80 |
+
//throw new \Exception( "Failed to create cache directory " . $this->cacheDir . '! Make sure folder permission is 755 and owner is correct. Should be www-data or similar.' );
|
81 |
}
|
82 |
}
|
83 |
|
Core/Utils/Logger.php
CHANGED
@@ -86,7 +86,13 @@ class Logger implements LoggerInterface
|
|
86 |
// If cache directory doesn't exists, create it
|
87 |
if (!is_dir($this->logDir) && !@mkdir($this->logDir, 0755, true))
|
88 |
{
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
}
|
91 |
}
|
92 |
|
86 |
// If cache directory doesn't exists, create it
|
87 |
if (!is_dir($this->logDir) && !@mkdir($this->logDir, 0755, true))
|
88 |
{
|
89 |
+
/**
|
90 |
+
* There's no need to throw this exception, which causes a fatal,
|
91 |
+
* as a warning is already displayed on:
|
92 |
+
*
|
93 |
+
* @see \WPStaging\Backend\Notices\Notices::messages
|
94 |
+
*/
|
95 |
+
// throw new \Exception("Failed to create log directory!");
|
96 |
}
|
97 |
}
|
98 |
|
Core/Utils/functions.php
CHANGED
@@ -126,9 +126,9 @@ function wpstg_replace_first_match($needle, $replace, $haystack)
|
|
126 |
|
127 |
/**
|
128 |
* Search & Replace last occurence of string in haystack
|
129 |
-
* @param
|
130 |
-
* @param
|
131 |
-
* @return
|
132 |
*/
|
133 |
function wpstg_replace_last_match($needle, $replace, $haystack)
|
134 |
{
|
@@ -142,8 +142,8 @@ function wpstg_replace_last_match($needle, $replace, $haystack)
|
|
142 |
|
143 |
/**
|
144 |
* Check if string is valid date
|
145 |
-
* @param
|
146 |
-
* @param
|
147 |
* @return bool
|
148 |
*/
|
149 |
function wpstg_is_valid_date($date, $format = 'Y-m-d')
|
126 |
|
127 |
/**
|
128 |
* Search & Replace last occurence of string in haystack
|
129 |
+
* @param string $haystack
|
130 |
+
* @param string $needle
|
131 |
+
* @return string
|
132 |
*/
|
133 |
function wpstg_replace_last_match($needle, $replace, $haystack)
|
134 |
{
|
142 |
|
143 |
/**
|
144 |
* Check if string is valid date
|
145 |
+
* @param string $date
|
146 |
+
* @param string $format
|
147 |
* @return bool
|
148 |
*/
|
149 |
function wpstg_is_valid_date($date, $format = 'Y-m-d')
|
Framework/CloningProcess/Data/UpdateWpConfigConstants.php
CHANGED
@@ -20,8 +20,6 @@ class UpdateWpConfigConstants extends FileCloningService
|
|
20 |
"UPLOADS" => sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getUploadFolder())),
|
21 |
"WP_PLUGIN_DIR" => '__DIR__ . "/wp-content/plugins"',
|
22 |
"WP_LANG_DIR" => '__DIR__ . "/wp-content/languages"',
|
23 |
-
// Below disabled. It can lead to deleting plugins after login to admin dashboard
|
24 |
-
//"WP_TEMP_DIR" => '__DIR__ . "/wp-content/temp"',
|
25 |
"WP_HOME" => sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getStagingSiteUrl())),
|
26 |
"WP_SITEURL" => sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getStagingSiteUrl())),
|
27 |
"WP_CACHE" => 'false',
|
@@ -98,11 +96,15 @@ class UpdateWpConfigConstants extends FileCloningService
|
|
98 |
|
99 |
$replace = sprintf("define('%s', %s);", $constant, $newDefinition);
|
100 |
|
101 |
-
|
|
|
|
|
|
|
102 |
|
103 |
if ($content === null) {
|
104 |
throw new \RuntimeException("Failed to change " . $constant);
|
105 |
}
|
|
|
106 |
$this->log("Updated: " . $constant);
|
107 |
return $content;
|
108 |
}
|
@@ -118,14 +120,21 @@ class UpdateWpConfigConstants extends FileCloningService
|
|
118 |
{
|
119 |
preg_match($this->abspathRegex, $content, $matches);
|
120 |
if (!empty($matches[0])) {
|
|
|
121 |
$replace = "define('" . $constant . "', " . $newDefinition . "); \n" .
|
122 |
"if ( ! defined( 'ABSPATH' ) )";
|
123 |
-
|
|
|
|
|
|
|
|
|
124 |
throw new \RuntimeException("Failed to change " . $constant);
|
125 |
}
|
|
|
126 |
} else {
|
127 |
throw new \RuntimeException("Can not add " . $constant . " constant to wp-config.php. Can not find free position to add it.");
|
128 |
}
|
|
|
129 |
$this->log("Added:" . $constant);
|
130 |
return $content;
|
131 |
}
|
20 |
"UPLOADS" => sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getUploadFolder())),
|
21 |
"WP_PLUGIN_DIR" => '__DIR__ . "/wp-content/plugins"',
|
22 |
"WP_LANG_DIR" => '__DIR__ . "/wp-content/languages"',
|
|
|
|
|
23 |
"WP_HOME" => sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getStagingSiteUrl())),
|
24 |
"WP_SITEURL" => sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getStagingSiteUrl())),
|
25 |
"WP_CACHE" => 'false',
|
96 |
|
97 |
$replace = sprintf("define('%s', %s);", $constant, $newDefinition);
|
98 |
|
99 |
+
// escaping dollar sign in the value
|
100 |
+
$replacementEscapedCharacter = addcslashes($replace, '\\$');
|
101 |
+
|
102 |
+
$content = preg_replace([$pattern], $replacementEscapedCharacter, $content);
|
103 |
|
104 |
if ($content === null) {
|
105 |
throw new \RuntimeException("Failed to change " . $constant);
|
106 |
}
|
107 |
+
|
108 |
$this->log("Updated: " . $constant);
|
109 |
return $content;
|
110 |
}
|
120 |
{
|
121 |
preg_match($this->abspathRegex, $content, $matches);
|
122 |
if (!empty($matches[0])) {
|
123 |
+
|
124 |
$replace = "define('" . $constant . "', " . $newDefinition . "); \n" .
|
125 |
"if ( ! defined( 'ABSPATH' ) )";
|
126 |
+
|
127 |
+
// escaping dollar sign in the value
|
128 |
+
$replaceEscaped = addcslashes($replace, '\\$');
|
129 |
+
|
130 |
+
if (null === ($content = preg_replace(array($this->abspathRegex), $replaceEscaped, $content))) {
|
131 |
throw new \RuntimeException("Failed to change " . $constant);
|
132 |
}
|
133 |
+
|
134 |
} else {
|
135 |
throw new \RuntimeException("Can not add " . $constant . " constant to wp-config.php. Can not find free position to add it.");
|
136 |
}
|
137 |
+
|
138 |
$this->log("Added:" . $constant);
|
139 |
return $content;
|
140 |
}
|
Requirements/WpstgFreeRequirements.php
CHANGED
@@ -5,6 +5,12 @@ if (!class_exists('WpstgFreeRequirements')) {
|
|
5 |
|
6 |
class WpstgFreeRequirements extends WpstgRequirements
|
7 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
public function checkRequirements()
|
9 |
{
|
10 |
$this->proVersionMustNotBeEnabled();
|
@@ -12,7 +18,7 @@ if (!class_exists('WpstgFreeRequirements')) {
|
|
12 |
}
|
13 |
|
14 |
/**
|
15 |
-
* Prevent conflicts when
|
16 |
*/
|
17 |
private function proVersionMustNotBeEnabled()
|
18 |
{
|
@@ -21,118 +27,24 @@ if (!class_exists('WpstgFreeRequirements')) {
|
|
21 |
return;
|
22 |
}
|
23 |
|
24 |
-
$proPlugin = plugin_basename(WPSTG_PRO_LOADED);
|
25 |
-
$freePlugin = plugin_basename($this->pluginFile);
|
26 |
|
27 |
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
28 |
|
29 |
-
if (
|
30 |
-
|
31 |
-
|
32 |
-
* Free active
|
33 |
-
*
|
34 |
-
* Result: Deactivate Free
|
35 |
-
*/
|
36 |
-
if (is_plugin_active($proPlugin)) {
|
37 |
-
if (current_user_can('deactivate_plugin', $freePlugin)) {
|
38 |
-
unset($_GET['activate']);
|
39 |
-
deactivate_plugins($freePlugin);
|
40 |
-
|
41 |
-
$this->notificationMessage = __('WP STAGING Pro is activated, therefore WP STAGING Basic was automatically disabled.', 'wp-staging');
|
42 |
-
add_action('admin_notices', [$this, '_displayWarning']);
|
43 |
-
|
44 |
-
throw new RuntimeException(sprintf("WP STAGING Pro is activated, therefore WP STAGING Basic was automatically disabled. Pro version that was active: %s, Basic version that was disabled: %s", $proPlugin, $freePlugin));
|
45 |
-
} else {
|
46 |
-
$this->notificationMessage = __('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Please ask the site administrator to leave only one instance of WP STAGING active.', 'wp-staging');
|
47 |
-
add_action('admin_notices', [$this, '_displayWarning']);
|
48 |
-
|
49 |
-
throw new RuntimeException(sprintf('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Plugin that was loaded: %s, Plugin that was prevented from loading: %s', $freePlugin, $proPlugin));
|
50 |
-
}
|
51 |
-
}
|
52 |
-
} else {
|
53 |
-
if (!is_network_admin()) {
|
54 |
-
/*
|
55 |
-
* Pro active site-level
|
56 |
-
* Free active site-level
|
57 |
-
* Free deactivated network-level
|
58 |
-
*
|
59 |
-
* Result: Deactivate Free site-level
|
60 |
-
*/
|
61 |
-
if (
|
62 |
-
is_plugin_active($proPlugin) &&
|
63 |
-
is_plugin_active($freePlugin) &&
|
64 |
-
!is_plugin_active_for_network($freePlugin)
|
65 |
-
) {
|
66 |
-
if (current_user_can('deactivate_plugin', $freePlugin)) {
|
67 |
-
unset($_GET['activate']);
|
68 |
-
deactivate_plugins($freePlugin);
|
69 |
-
|
70 |
-
$this->notificationMessage = __('WP STAGING Pro is activated, therefore WP STAGING Basic was automatically disabled.', 'wp-staging');
|
71 |
-
add_action('admin_notices', [$this, '_displayWarning']);
|
72 |
-
|
73 |
-
throw new RuntimeException(sprintf("WP STAGING Pro is activated, therefore WP STAGING Basic was automatically disabled. Pro version that was active: %s, Basic version that was disabled: %s", $proPlugin, $freePlugin));
|
74 |
-
} else {
|
75 |
-
$this->notificationMessage = __('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Please ask the site administrator to leave only one instance of WP STAGING active.', 'wp-staging');
|
76 |
-
add_action('admin_notices', [$this, '_displayWarning']);
|
77 |
-
|
78 |
-
throw new RuntimeException(sprintf('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Plugin that was loaded: %s, Plugin that was prevented from loading: %s', $freePlugin, $proPlugin));
|
79 |
-
}
|
80 |
-
}
|
81 |
-
|
82 |
-
/*
|
83 |
-
* Pro active site-level
|
84 |
-
* Free active network-level
|
85 |
-
*
|
86 |
-
* Result: Deactivate Pro site-level
|
87 |
-
*/
|
88 |
-
if (
|
89 |
-
is_plugin_active($proPlugin) &&
|
90 |
-
is_plugin_active_for_network($freePlugin)
|
91 |
-
) {
|
92 |
-
if (current_user_can('deactivate_plugin', $proPlugin)) {
|
93 |
-
unset($_GET['activate']);
|
94 |
-
deactivate_plugins($proPlugin);
|
95 |
-
|
96 |
-
$this->notificationMessage = __('WP STAGING Basic is activated network-wide, therefore WP STAGING Pro was automatically disabled. Please disable WP STAGING Basic network-wide to enable WP STAGING Pro.', 'wp-staging');
|
97 |
-
add_action('admin_notices', [$this, '_displayWarning']);
|
98 |
-
|
99 |
-
throw new RuntimeException(sprintf("WP STAGING Basic is activated networkwide, therefore WP STAGING Pro was automatically disabled. Basic version that was activate networkwide: %s, Pro version that was disabled: %s", $freePlugin, $proPlugin));
|
100 |
-
} else {
|
101 |
-
$this->notificationMessage = __('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Please ask the site administrator to leave only one instance of WP STAGING active.', 'wp-staging');
|
102 |
-
add_action('admin_notices', [$this, '_displayWarning']);
|
103 |
-
|
104 |
-
throw new RuntimeException(sprintf('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Plugin that was loaded: %s, Plugin that was prevented from loading: %s', $freePlugin, $proPlugin));
|
105 |
-
}
|
106 |
-
}
|
107 |
} else {
|
108 |
-
|
109 |
-
* Pro active network-level
|
110 |
-
* Free active network-level
|
111 |
-
*
|
112 |
-
* Result: Deactivate Free network-level
|
113 |
-
*/
|
114 |
-
if (is_plugin_active_for_network($proPlugin)) {
|
115 |
-
if (current_user_can('manage_network_plugins')) {
|
116 |
-
unset($_GET['activate']);
|
117 |
-
deactivate_plugins($freePlugin, null, true);
|
118 |
-
|
119 |
-
$this->notificationMessage = __('WP STAGING Pro is activated network-wide, therefore WP STAGING Basic was disabled network-wide.', 'wp-staging');
|
120 |
-
add_action('network_admin_notices', [$this, '_displayWarning']);
|
121 |
-
|
122 |
-
throw new RuntimeException(sprintf("WP STAGING Pro is activated networkwide, therefore WP STAGING Basic networkwide was automatically disabled. Pro version that was activate networkwide: %s, Basic version that was disabled networkwide: %s", $proPlugin, $freePlugin));
|
123 |
-
} else {
|
124 |
-
$this->notificationMessage = __('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Please ask the site administrator to leave only one instance of WP STAGING active.', 'wp-staging');
|
125 |
-
add_action('admin_notices', [$this, '_displayWarning']);
|
126 |
-
|
127 |
-
throw new RuntimeException(sprintf('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Plugin that was loaded: %s, Plugin that was prevented from loading: %s', $freePlugin, $proPlugin));
|
128 |
-
}
|
129 |
-
}
|
130 |
}
|
|
|
|
|
131 |
}
|
132 |
}
|
133 |
|
134 |
/**
|
135 |
-
* Catch-all to prevent conflicts when another instance of
|
136 |
*/
|
137 |
private function anotherInstanceOfWpstagingMustNotBeEnabled()
|
138 |
{
|
@@ -155,5 +67,114 @@ if (!class_exists('WpstgFreeRequirements')) {
|
|
155 |
throw new RuntimeException(sprintf("Another instance of WP STAGING is activated, therefore other instances of WP STAGING were automatically prevented from running to avoid errors. Please leave only one instance of the WP STAGING plugin active. Plugin that was prevented from loading: %s", $this->pluginFile));
|
156 |
}
|
157 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
}
|
159 |
}
|
5 |
|
6 |
class WpstgFreeRequirements extends WpstgRequirements
|
7 |
{
|
8 |
+
/** @var string */
|
9 |
+
private $proPlugin;
|
10 |
+
|
11 |
+
/** @var string */
|
12 |
+
private $freePlugin;
|
13 |
+
|
14 |
public function checkRequirements()
|
15 |
{
|
16 |
$this->proVersionMustNotBeEnabled();
|
18 |
}
|
19 |
|
20 |
/**
|
21 |
+
* Prevent conflicts when WP STAGING Pro is active.
|
22 |
*/
|
23 |
private function proVersionMustNotBeEnabled()
|
24 |
{
|
27 |
return;
|
28 |
}
|
29 |
|
30 |
+
$this->proPlugin = plugin_basename(WPSTG_PRO_LOADED);
|
31 |
+
$this->freePlugin = plugin_basename($this->pluginFile);
|
32 |
|
33 |
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
34 |
|
35 |
+
if (is_multisite()) {
|
36 |
+
if (is_network_admin()) {
|
37 |
+
$this->deactivateFreePluginOnMultisiteNetworkLevel();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
} else {
|
39 |
+
$this->deactivateFreeOrProPluginOnMultisite();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
+
} else {
|
42 |
+
$this->deactivateFreePluginIfProIsActiveOnSingleSite();
|
43 |
}
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
+
* Catch-all to prevent conflicts when another instance of WP STAGING is active.
|
48 |
*/
|
49 |
private function anotherInstanceOfWpstagingMustNotBeEnabled()
|
50 |
{
|
67 |
throw new RuntimeException(sprintf("Another instance of WP STAGING is activated, therefore other instances of WP STAGING were automatically prevented from running to avoid errors. Please leave only one instance of the WP STAGING plugin active. Plugin that was prevented from loading: %s", $this->pluginFile));
|
68 |
}
|
69 |
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Pro active
|
73 |
+
* Free active
|
74 |
+
*
|
75 |
+
* Result: Deactivate Free
|
76 |
+
*/
|
77 |
+
private function deactivateFreePluginIfProIsActiveOnSingleSite()
|
78 |
+
{
|
79 |
+
if (is_plugin_active($this->proPlugin)) {
|
80 |
+
if (current_user_can('deactivate_plugin', $this->freePlugin)) {
|
81 |
+
unset($_GET['activate']);
|
82 |
+
deactivate_plugins($this->freePlugin);
|
83 |
+
|
84 |
+
$this->notificationMessage = __('WP STAGING Pro is activated, therefore WP STAGING Basic was automatically disabled.', 'wp-staging');
|
85 |
+
add_action('admin_notices', [$this, '_displayWarning']);
|
86 |
+
|
87 |
+
throw new RuntimeException(sprintf("WP STAGING Pro is activated, therefore WP STAGING Basic was automatically disabled. Pro version that was active: %s, Basic version that was disabled: %s", $this->proPlugin, $this->freePlugin));
|
88 |
+
}
|
89 |
+
|
90 |
+
$this->notificationMessage = __('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Please ask the site administrator to leave only one instance of WP STAGING active.', 'wp-staging');
|
91 |
+
add_action('admin_notices', [$this, '_displayWarning']);
|
92 |
+
|
93 |
+
throw new RuntimeException(sprintf('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Plugin that was loaded: %s, Plugin that was prevented from loading: %s', $this->freePlugin, $this->proPlugin));
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
private function deactivateFreeOrProPluginOnMultisite()
|
98 |
+
{
|
99 |
+
/*
|
100 |
+
* Pro active site-level
|
101 |
+
* Free active site-level
|
102 |
+
* Free deactivated network-level
|
103 |
+
*
|
104 |
+
* Result: Deactivate Free site-level
|
105 |
+
*/
|
106 |
+
if (
|
107 |
+
is_plugin_active($this->proPlugin) &&
|
108 |
+
is_plugin_active($this->freePlugin) &&
|
109 |
+
!is_plugin_active_for_network($this->freePlugin)
|
110 |
+
) {
|
111 |
+
if (current_user_can('deactivate_plugin', $this->freePlugin)) {
|
112 |
+
unset($_GET['activate']);
|
113 |
+
deactivate_plugins($this->freePlugin);
|
114 |
+
|
115 |
+
$this->notificationMessage = __('WP STAGING Pro is activated, therefore WP STAGING Basic was automatically disabled.', 'wp-staging');
|
116 |
+
add_action('admin_notices', [$this, '_displayWarning']);
|
117 |
+
|
118 |
+
throw new RuntimeException(sprintf("WP STAGING Pro is activated, therefore WP STAGING Basic was automatically disabled. Pro version that was active: %s, Basic version that was disabled: %s", $this->proPlugin, $this->freePlugin));
|
119 |
+
}
|
120 |
+
|
121 |
+
$this->notificationMessage = __('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Please ask the site administrator to leave only one instance of WP STAGING active.', 'wp-staging');
|
122 |
+
add_action('admin_notices', [$this, '_displayWarning']);
|
123 |
+
|
124 |
+
throw new RuntimeException(sprintf('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Plugin that was loaded: %s, Plugin that was prevented from loading: %s', $this->freePlugin, $this->proPlugin));
|
125 |
+
}
|
126 |
+
|
127 |
+
/*
|
128 |
+
* Pro active site-level
|
129 |
+
* Free active network-level
|
130 |
+
*
|
131 |
+
* Result: Deactivate Pro site-level
|
132 |
+
*/
|
133 |
+
if (
|
134 |
+
is_plugin_active($this->proPlugin) &&
|
135 |
+
is_plugin_active_for_network($this->freePlugin)
|
136 |
+
) {
|
137 |
+
if (current_user_can('deactivate_plugin', $this->proPlugin)) {
|
138 |
+
unset($_GET['activate']);
|
139 |
+
deactivate_plugins($this->proPlugin);
|
140 |
+
|
141 |
+
$this->notificationMessage = __('WP STAGING Basic is activated network-wide, therefore WP STAGING Pro was automatically disabled. Please disable WP STAGING Basic network-wide to enable WP STAGING Pro.', 'wp-staging');
|
142 |
+
add_action('admin_notices', [$this, '_displayWarning']);
|
143 |
+
|
144 |
+
throw new RuntimeException(sprintf("WP STAGING Basic is activated networkwide, therefore WP STAGING Pro was automatically disabled. Basic version that was activate networkwide: %s, Pro version that was disabled: %s", $this->freePlugin, $this->proPlugin));
|
145 |
+
}
|
146 |
+
|
147 |
+
$this->notificationMessage = __('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Please ask the site administrator to leave only one instance of WP STAGING active.', 'wp-staging');
|
148 |
+
add_action('admin_notices', [$this, '_displayWarning']);
|
149 |
+
|
150 |
+
throw new RuntimeException(sprintf('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Plugin that was loaded: %s, Plugin that was prevented from loading: %s', $this->freePlugin, $this->proPlugin));
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
/*
|
155 |
+
* Pro active network-level
|
156 |
+
* Free active network-level
|
157 |
+
*
|
158 |
+
* Result: Deactivate Free network-level
|
159 |
+
*/
|
160 |
+
private function deactivateFreePluginOnMultisiteNetworkLevel()
|
161 |
+
{
|
162 |
+
if (is_plugin_active_for_network($this->proPlugin)) {
|
163 |
+
if (current_user_can('manage_network_plugins')) {
|
164 |
+
unset($_GET['activate']);
|
165 |
+
deactivate_plugins($this->freePlugin, null, true);
|
166 |
+
|
167 |
+
$this->notificationMessage = __('WP STAGING Pro is activated network-wide, therefore WP STAGING Basic was disabled network-wide.', 'wp-staging');
|
168 |
+
add_action('network_admin_notices', [$this, '_displayWarning']);
|
169 |
+
|
170 |
+
throw new RuntimeException(sprintf("WP STAGING Pro is activated networkwide, therefore WP STAGING Basic networkwide was automatically disabled. Pro version that was activate networkwide: %s, Basic version that was disabled networkwide: %s", $this->proPlugin, $this->freePlugin));
|
171 |
+
}
|
172 |
+
|
173 |
+
$this->notificationMessage = __('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Please ask the site administrator to leave only one instance of WP STAGING active.', 'wp-staging');
|
174 |
+
add_action('admin_notices', [$this, '_displayWarning']);
|
175 |
+
|
176 |
+
throw new RuntimeException(sprintf('Another instance of WP STAGING was activated, therefore other instances of the WP STAGING plugin were prevented from loading. Plugin that was loaded: %s, Plugin that was prevented from loading: %s', $this->freePlugin, $this->proPlugin));
|
177 |
+
}
|
178 |
+
}
|
179 |
}
|
180 |
}
|
_init.php
CHANGED
@@ -2,40 +2,6 @@
|
|
2 |
|
3 |
use WPStaging\WPStaging;
|
4 |
|
5 |
-
// Compatible maximum WordPress Version
|
6 |
-
if (!defined('WPSTG_COMPATIBLE')) {
|
7 |
-
define('WPSTG_COMPATIBLE', '5.5.1');
|
8 |
-
}
|
9 |
-
|
10 |
-
// Compatible minimum WordPress version
|
11 |
-
if (!defined('WPSTG_MIN_WP_VERSION')) {
|
12 |
-
define('WPSTG_MIN_WP_VERSION', '4.0');
|
13 |
-
}
|
14 |
-
|
15 |
-
// Compatible up to PHP Version
|
16 |
-
if (!defined('WPSTG_PHP_COMPATIBLE')) {
|
17 |
-
define('WPSTG_PHP_COMPATIBLE', '5.5');
|
18 |
-
}
|
19 |
-
|
20 |
-
// Expected version number of the must-use plugin 'optimizer'. Used for automatic updates of the mu-plugin
|
21 |
-
if (!defined('WPSTG_OPTIMIZER_MUVERSION')) {
|
22 |
-
define('WPSTG_OPTIMIZER_MUVERSION', 1.3);
|
23 |
-
}
|
24 |
-
|
25 |
-
// URL of the base folder
|
26 |
-
if (!defined('WPSTG_PLUGIN_URL')) {
|
27 |
-
define('WPSTG_PLUGIN_URL', plugin_dir_url(WPSTG_PLUGIN_FILE));
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Load Basic/Pro related constants and due to that the rest of the basic or pro version
|
32 |
-
*/
|
33 |
-
if (file_exists(plugin_dir_path(__FILE__) . 'Pro/constants.php')) {
|
34 |
-
require_once plugin_dir_path(__FILE__) . 'Pro/constants.php';
|
35 |
-
} else {
|
36 |
-
require_once plugin_dir_path(__FILE__) . 'constants.php';
|
37 |
-
}
|
38 |
-
|
39 |
/**
|
40 |
* Do not show update notifications for WP STAGING Pro on the staging site
|
41 |
* @param object
|
@@ -69,8 +35,8 @@ if (!class_exists('Wpstg_Requirements_Check')) {
|
|
69 |
|
70 |
$pluginRequirements = new Wpstg_Requirements_Check(array(
|
71 |
'title' => 'WP STAGING',
|
72 |
-
'php' =>
|
73 |
-
'wp' =>
|
74 |
'file' => __FILE__,
|
75 |
));
|
76 |
|
@@ -81,11 +47,15 @@ if ($pluginRequirements->passes()) {
|
|
81 |
// Load composer autoloader
|
82 |
require_once __DIR__ . '/vendor/autoload.php';
|
83 |
|
|
|
|
|
84 |
$wpStaging = WPStaging::getInstance();
|
85 |
|
86 |
-
|
87 |
-
*
|
|
|
88 |
*/
|
|
|
89 |
|
90 |
// Wordpress DB Object
|
91 |
global $wpdb;
|
@@ -93,11 +63,4 @@ if ($pluginRequirements->passes()) {
|
|
93 |
if ($wpdb instanceof \wpdb) {
|
94 |
$wpStaging->set("wpdb", $wpdb);
|
95 |
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* Installation Hooks
|
99 |
-
*/
|
100 |
-
if (!class_exists('WPStaging\Install')) {
|
101 |
-
require_once WPSTG_PLUGIN_DIR . "install.php";
|
102 |
-
}
|
103 |
}
|
2 |
|
3 |
use WPStaging\WPStaging;
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
/**
|
6 |
* Do not show update notifications for WP STAGING Pro on the staging site
|
7 |
* @param object
|
35 |
|
36 |
$pluginRequirements = new Wpstg_Requirements_Check(array(
|
37 |
'title' => 'WP STAGING',
|
38 |
+
'php' => '5.5',
|
39 |
+
'wp' => '4.0',
|
40 |
'file' => __FILE__,
|
41 |
));
|
42 |
|
47 |
// Load composer autoloader
|
48 |
require_once __DIR__ . '/vendor/autoload.php';
|
49 |
|
50 |
+
require_once __DIR__ . '/constants.php';
|
51 |
+
|
52 |
$wpStaging = WPStaging::getInstance();
|
53 |
|
54 |
+
/*
|
55 |
+
* Set the WPSTG_COMPATIBLE constant in the container,
|
56 |
+
* so that we can change it for testing purposes.
|
57 |
*/
|
58 |
+
$wpStaging->set('WPSTG_COMPATIBLE', WPSTG_COMPATIBLE);
|
59 |
|
60 |
// Wordpress DB Object
|
61 |
global $wpdb;
|
63 |
if ($wpdb instanceof \wpdb) {
|
64 |
$wpStaging->set("wpdb", $wpdb);
|
65 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
}
|
constants.php
CHANGED
@@ -1,18 +1,42 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
3 |
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
if (!defined('WPSTG_VERSION')) {
|
8 |
-
define('WPSTG_VERSION', '2.7.7');
|
9 |
}
|
10 |
|
11 |
-
//
|
12 |
-
if (!defined('
|
13 |
-
define('
|
14 |
}
|
15 |
|
16 |
-
if (
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
|
3 |
+
// Absolute path to plugin dir /var/www/.../plugins/wp-staging(-pro)
|
4 |
+
if (!defined('WPSTG_PLUGIN_DIR')) {
|
5 |
+
define('WPSTG_PLUGIN_DIR', plugin_dir_path(WPSTG_PLUGIN_FILE));
|
6 |
+
}
|
7 |
|
8 |
+
// URL of the base folder
|
9 |
+
if (!defined('WPSTG_PLUGIN_URL')) {
|
10 |
+
define('WPSTG_PLUGIN_URL', plugin_dir_url(WPSTG_PLUGIN_FILE));
|
|
|
|
|
11 |
}
|
12 |
|
13 |
+
// Expected version number of the must-use plugin 'optimizer'. Used for automatic updates of the mu-plugin
|
14 |
+
if (!defined('WPSTG_OPTIMIZER_MUVERSION')) {
|
15 |
+
define('WPSTG_OPTIMIZER_MUVERSION', 1.3);
|
16 |
}
|
17 |
|
18 |
+
if (file_exists(__DIR__ . '/wp-staging-pro.php')) {
|
19 |
+
/** WPSTAGING Pro Constants */
|
20 |
+
|
21 |
+
// WP STAGING version number
|
22 |
+
if (!defined('WPSTGPRO_VERSION')) {
|
23 |
+
define('WPSTGPRO_VERSION', '3.1.3');
|
24 |
+
}
|
25 |
+
|
26 |
+
// Compatible up to WordPress Version
|
27 |
+
if (!defined('WPSTG_COMPATIBLE')) {
|
28 |
+
define('WPSTG_COMPATIBLE', '5.5.3');
|
29 |
+
}
|
30 |
+
} else {
|
31 |
+
/** WPSTAGING Free Constants */
|
32 |
+
|
33 |
+
// WP STAGING version number
|
34 |
+
if (!defined('WPSTG_VERSION')) {
|
35 |
+
define('WPSTG_VERSION', '2.7.8');
|
36 |
+
}
|
37 |
+
|
38 |
+
// Compatible up to WordPress Version
|
39 |
+
if (!defined('WPSTG_COMPATIBLE')) {
|
40 |
+
define('WPSTG_COMPATIBLE', '5.5.2');
|
41 |
+
}
|
42 |
+
}
|
install.php
CHANGED
@@ -7,35 +7,31 @@ use WPStaging\Utils\IISWebConfig;
|
|
7 |
use WPStaging\Utils\Htaccess;
|
8 |
use WPStaging\Utils\Filesystem;
|
9 |
|
10 |
-
// Exit if accessed directly
|
11 |
-
if (!defined('ABSPATH'))
|
12 |
-
exit;
|
13 |
-
|
14 |
-
// TODO; remove previous auto-loader, use composer based instead!
|
15 |
-
require_once __DIR__ . '/vendor/autoload.php';
|
16 |
-
|
17 |
/**
|
18 |
* Install Class
|
19 |
*
|
20 |
*/
|
21 |
class Install
|
22 |
{
|
|
|
23 |
|
24 |
-
public function __construct()
|
25 |
{
|
26 |
-
$
|
27 |
-
register_activation_hook($file, array($this, 'activation'));
|
28 |
}
|
29 |
|
30 |
-
public
|
31 |
{
|
32 |
-
$
|
33 |
-
|
34 |
-
|
35 |
-
$
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
39 |
}
|
40 |
|
41 |
private function initCron()
|
@@ -83,5 +79,3 @@ class Install
|
|
83 |
$webconfig->create(trailingslashit(\WPStaging\WPStaging::getContentDir()) . 'logs/web.config');
|
84 |
}
|
85 |
}
|
86 |
-
|
87 |
-
new Install();
|
7 |
use WPStaging\Utils\Htaccess;
|
8 |
use WPStaging\Utils\Filesystem;
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
/**
|
11 |
* Install Class
|
12 |
*
|
13 |
*/
|
14 |
class Install
|
15 |
{
|
16 |
+
private $bootstrap;
|
17 |
|
18 |
+
public function __construct(\WpstgBootstrapInterface $bootstrap)
|
19 |
{
|
20 |
+
$this->bootstrap = $bootstrap;
|
|
|
21 |
}
|
22 |
|
23 |
+
public function activation()
|
24 |
{
|
25 |
+
$this->bootstrap->checkRequirements();
|
26 |
+
$this->bootstrap->bootstrap();
|
27 |
+
|
28 |
+
if ($this->bootstrap->passedRequirements()) {
|
29 |
+
$this->initCron();
|
30 |
+
$this->installOptimizer();
|
31 |
+
$this->createHtaccess();
|
32 |
+
$this->createIndex();
|
33 |
+
$this->createWebConfig();
|
34 |
+
}
|
35 |
}
|
36 |
|
37 |
private function initCron()
|
79 |
$webconfig->create(trailingslashit(\WPStaging\WPStaging::getContentDir()) . 'logs/web.config');
|
80 |
}
|
81 |
}
|
|
|
|
readme.txt
CHANGED
@@ -9,7 +9,7 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
|
9 |
Tags: backup, staging, duplication, clone, migration
|
10 |
Requires at least: 3.6+
|
11 |
Tested up to: 5.5
|
12 |
-
Stable tag: 2.7.
|
13 |
Requires PHP: 5.5
|
14 |
|
15 |
A duplicator plugin - clone/move, duplicate & migrate websites to staging, backup and development sites that only authorized users can access.
|
@@ -157,8 +157,20 @@ https://wp-staging.com
|
|
157 |
|
158 |
== Changelog ==
|
159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
= 2.7.7 =
|
161 |
-
* Fix: Fatal error on activation
|
162 |
|
163 |
= 2.7.6 =
|
164 |
* New: Compatible up to WordPress 5.5.1
|
@@ -176,7 +188,6 @@ https://wp-staging.com
|
|
176 |
* Fix: Wrong german translations
|
177 |
* Fix: Cloning fails if there is no underscore in table prefix
|
178 |
|
179 |
-
|
180 |
= 2.7.5 =
|
181 |
* New: Compatible up to WordPress 5.4.2
|
182 |
* Fix: Remove beta notice
|
@@ -252,7 +263,6 @@ SKIP VERSION
|
|
252 |
* Fix: use an alternative method for file_put_contents as it is not supported on all systems due to file permission issues
|
253 |
* Fix: Redundant and duplicated update comments in wp-config.php in staging site
|
254 |
|
255 |
-
|
256 |
= 2.6.2 =
|
257 |
* Fix: Do not show warning "Preparing Data Step3: Failed to update rewrite_rules in wpstg0_options"
|
258 |
* Fix: Change error "Table wpstgtmp_options does not exist" to warning
|
@@ -260,7 +270,6 @@ SKIP VERSION
|
|
260 |
* New: Setup server environment variables per process and not globally (e.g. set_time_limit)
|
261 |
* New: Add support for custom uploads folder if user customized UPLOADS constant or upload_path in DB
|
262 |
|
263 |
-
|
264 |
= 2.6.1 =
|
265 |
* New: Improve styling of login form. Thanks to Andy Kennan (Screaming Frog)
|
266 |
* New: Add 'password lost' button to login form
|
@@ -269,8 +278,6 @@ SKIP VERSION
|
|
269 |
* Fix: PDO instances can not be serialized or unserialized
|
270 |
* Fix: Can not update staging site db table if there are constraints in it
|
271 |
|
272 |
-
|
273 |
-
|
274 |
= 2.6.0 =
|
275 |
* New: Compatible up to WordPress 5.2.2
|
276 |
* New: Performance improvement for directory iterator using less server ressources
|
@@ -278,34 +285,17 @@ SKIP VERSION
|
|
278 |
* Fix: Error conditions in class Data does not compare type strict (== vs. ==) resulting in interruption of clone process
|
279 |
* Fix: Excluded folders under wp-content level are not take into account on microsoft IIS servers
|
280 |
|
281 |
-
|
282 |
-
* New: Update for WP 5.2.1
|
283 |
-
* New: Better corporate identity and more friendly UI colors for staging sites listings and button
|
284 |
-
* New: Better warning notices before updating process is executed
|
285 |
-
* New: Add tooltips for explaining navigation buttons
|
286 |
-
* New: Check if UPLOAD constant is defined and use this value for uploads folder destination
|
287 |
-
* New: Show notice if user tries to clone a staging website.
|
288 |
-
* Fix: Staging sites listing entries appeared on the cloned website.
|
289 |
-
* Fix: Do not search & replace through "__PHP_Incomplete_Class_Name" definitions
|
290 |
-
* Fix: Prevent wordfence firewall rule interrupting the clone deletion method
|
291 |
-
* Fix: Excluded wp staging directory from deleting process is ignored and will be deleted either way
|
292 |
-
* Fix: Strip whitespaces in cloning site internal names
|
293 |
-
|
294 |
-
Complete changelog: [https://wp-staging.com/wp-staging-changelog](https://wp-staging.com/wp-staging-changelog)
|
295 |
|
296 |
== Upgrade Notice ==
|
297 |
-
* New:
|
298 |
-
* New:
|
299 |
-
* New:
|
300 |
-
|
301 |
-
*
|
302 |
-
*
|
303 |
-
*
|
304 |
-
|
305 |
-
*
|
306 |
-
*
|
307 |
-
* Fix: Show access denied message if a non but existing user tries to access the staging site
|
308 |
-
* Fix: Remove wp_logout() in staging site login form to prevent multiple login log entries with plugin WP Activity Log
|
309 |
-
* Fix: Wrong german translations
|
310 |
-
* Fix: Cloning fails if there is no underscore in table prefix
|
311 |
|
9 |
Tags: backup, staging, duplication, clone, migration
|
10 |
Requires at least: 3.6+
|
11 |
Tested up to: 5.5
|
12 |
+
Stable tag: 2.7.8
|
13 |
Requires PHP: 5.5
|
14 |
|
15 |
A duplicator plugin - clone/move, duplicate & migrate websites to staging, backup and development sites that only authorized users can access.
|
157 |
|
158 |
== Changelog ==
|
159 |
|
160 |
+
= 2.7.8 =
|
161 |
+
* New: Add special admin notice if plugin is not tested with latest WordPress version
|
162 |
+
* New: Compatible up to WordPress 5.5.2
|
163 |
+
* New: Allow deleting of orphaned staging site entries if staging site was deleted manually before
|
164 |
+
|
165 |
+
* Fix: Activation hook is not fired after first time installation and wpstg optimizer and cron tasks are not set up
|
166 |
+
* Fix: Staging site does not work if database password contains dollar sign in password
|
167 |
+
* Fix: Prevent fatal error when the plugin is activated, but there is no permission to create folder wp-content/uploads/wp-staging or wp-content/uploads/wp-staging/logs.
|
168 |
+
|
169 |
+
* Dev: Add new DI container implementation
|
170 |
+
* Dev: Add composer 2
|
171 |
+
|
172 |
= 2.7.7 =
|
173 |
+
* Fix: Fatal error on activation in pro version (Syntax error)
|
174 |
|
175 |
= 2.7.6 =
|
176 |
* New: Compatible up to WordPress 5.5.1
|
188 |
* Fix: Wrong german translations
|
189 |
* Fix: Cloning fails if there is no underscore in table prefix
|
190 |
|
|
|
191 |
= 2.7.5 =
|
192 |
* New: Compatible up to WordPress 5.4.2
|
193 |
* Fix: Remove beta notice
|
263 |
* Fix: use an alternative method for file_put_contents as it is not supported on all systems due to file permission issues
|
264 |
* Fix: Redundant and duplicated update comments in wp-config.php in staging site
|
265 |
|
|
|
266 |
= 2.6.2 =
|
267 |
* Fix: Do not show warning "Preparing Data Step3: Failed to update rewrite_rules in wpstg0_options"
|
268 |
* Fix: Change error "Table wpstgtmp_options does not exist" to warning
|
270 |
* New: Setup server environment variables per process and not globally (e.g. set_time_limit)
|
271 |
* New: Add support for custom uploads folder if user customized UPLOADS constant or upload_path in DB
|
272 |
|
|
|
273 |
= 2.6.1 =
|
274 |
* New: Improve styling of login form. Thanks to Andy Kennan (Screaming Frog)
|
275 |
* New: Add 'password lost' button to login form
|
278 |
* Fix: PDO instances can not be serialized or unserialized
|
279 |
* Fix: Can not update staging site db table if there are constraints in it
|
280 |
|
|
|
|
|
281 |
= 2.6.0 =
|
282 |
* New: Compatible up to WordPress 5.2.2
|
283 |
* New: Performance improvement for directory iterator using less server ressources
|
285 |
* Fix: Error conditions in class Data does not compare type strict (== vs. ==) resulting in interruption of clone process
|
286 |
* Fix: Excluded folders under wp-content level are not take into account on microsoft IIS servers
|
287 |
|
288 |
+
Full changelog: [https://wp-staging.com/wp-staging-changelog](https://wp-staging.com/wp-staging-changelog)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
289 |
|
290 |
== Upgrade Notice ==
|
291 |
+
* New: Add special admin notice if plugin is not tested with latest WordPress version
|
292 |
+
* New: Compatible up to WordPress 5.5.2
|
293 |
+
* New: Allow deleting of orphaned staging site entries if staging site was deleted manually before
|
294 |
+
|
295 |
+
* Fix: Activation hook is not fired after first time installation and wpstg optimizer and cron tasks are not set up
|
296 |
+
* Fix: Staging site does not work if database password contains dollar sign in password
|
297 |
+
* Fix: Prevent fatal error when the plugin is activated, but there is no permission to create folder wp-content/uploads/wp-staging or wp-content/uploads/wp-staging/logs.
|
298 |
+
|
299 |
+
* Dev: Add new DI container implementation
|
300 |
+
* Dev: Add composer 2
|
|
|
|
|
|
|
|
|
301 |
|
vendor/composer/autoload_classmap.php
CHANGED
@@ -282,4 +282,11 @@ return array(
|
|
282 |
'WPStaging\\Utils\\Strings' => $baseDir . '/Core/Utils/Strings.php',
|
283 |
'WPStaging\\WPStaging' => $baseDir . '/Core/WPStaging.php',
|
284 |
'WPStaging\\thirdParty\\thirdPartyCompatibility' => $baseDir . '/Core/thirdParty/thirdPartyCompatibility.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
);
|
282 |
'WPStaging\\Utils\\Strings' => $baseDir . '/Core/Utils/Strings.php',
|
283 |
'WPStaging\\WPStaging' => $baseDir . '/Core/WPStaging.php',
|
284 |
'WPStaging\\thirdParty\\thirdPartyCompatibility' => $baseDir . '/Core/thirdParty/thirdPartyCompatibility.php',
|
285 |
+
'tad_DI52_Container' => $vendorDir . '/lucatume/di52/src/tad/DI52/Container.php',
|
286 |
+
'tad_DI52_ContainerInterface' => $vendorDir . '/lucatume/di52/src/tad/DI52/ContainerInterface.php',
|
287 |
+
'tad_DI52_ProtectedValue' => $vendorDir . '/lucatume/di52/src/tad/DI52/ProtectedValue.php',
|
288 |
+
'tad_DI52_ServiceProvider' => $vendorDir . '/lucatume/di52/src/tad/DI52/ServiceProvider.php',
|
289 |
+
'tad_DI52_ServiceProviderInterface' => $vendorDir . '/lucatume/di52/src/tad/DI52/ServiceProviderInterface.php',
|
290 |
+
'xrstf\\Composer52\\AutoloadGenerator' => $vendorDir . '/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php',
|
291 |
+
'xrstf\\Composer52\\Generator' => $vendorDir . '/xrstf/composer-php52/lib/xrstf/Composer52/Generator.php',
|
292 |
);
|
vendor/composer/autoload_namespaces.php
CHANGED
@@ -6,4 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
|
|
6 |
$baseDir = dirname($vendorDir);
|
7 |
|
8 |
return array(
|
|
|
|
|
9 |
);
|
6 |
$baseDir = dirname($vendorDir);
|
7 |
|
8 |
return array(
|
9 |
+
'xrstf\\Composer52' => array($vendorDir . '/xrstf/composer-php52/lib'),
|
10 |
+
'tad_DI52_' => array($vendorDir . '/lucatume/di52/src'),
|
11 |
);
|
vendor/composer/autoload_static.php
CHANGED
@@ -50,6 +50,23 @@ class ComposerStaticInitwpstgfree
|
|
50 |
),
|
51 |
);
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
public static $classMap = array (
|
54 |
'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php',
|
55 |
'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php',
|
@@ -327,6 +344,13 @@ class ComposerStaticInitwpstgfree
|
|
327 |
'WPStaging\\Utils\\Strings' => __DIR__ . '/../..' . '/Core/Utils/Strings.php',
|
328 |
'WPStaging\\WPStaging' => __DIR__ . '/../..' . '/Core/WPStaging.php',
|
329 |
'WPStaging\\thirdParty\\thirdPartyCompatibility' => __DIR__ . '/../..' . '/Core/thirdParty/thirdPartyCompatibility.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
);
|
331 |
|
332 |
public static function getInitializer(ClassLoader $loader)
|
@@ -334,6 +358,7 @@ class ComposerStaticInitwpstgfree
|
|
334 |
return \Closure::bind(function () use ($loader) {
|
335 |
$loader->prefixLengthsPsr4 = ComposerStaticInitwpstgfree::$prefixLengthsPsr4;
|
336 |
$loader->prefixDirsPsr4 = ComposerStaticInitwpstgfree::$prefixDirsPsr4;
|
|
|
337 |
$loader->classMap = ComposerStaticInitwpstgfree::$classMap;
|
338 |
|
339 |
}, null, ClassLoader::class);
|
50 |
),
|
51 |
);
|
52 |
|
53 |
+
public static $prefixesPsr0 = array (
|
54 |
+
'x' =>
|
55 |
+
array (
|
56 |
+
'xrstf\\Composer52' =>
|
57 |
+
array (
|
58 |
+
0 => __DIR__ . '/..' . '/xrstf/composer-php52/lib',
|
59 |
+
),
|
60 |
+
),
|
61 |
+
't' =>
|
62 |
+
array (
|
63 |
+
'tad_DI52_' =>
|
64 |
+
array (
|
65 |
+
0 => __DIR__ . '/..' . '/lucatume/di52/src',
|
66 |
+
),
|
67 |
+
),
|
68 |
+
);
|
69 |
+
|
70 |
public static $classMap = array (
|
71 |
'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php',
|
72 |
'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php',
|
344 |
'WPStaging\\Utils\\Strings' => __DIR__ . '/../..' . '/Core/Utils/Strings.php',
|
345 |
'WPStaging\\WPStaging' => __DIR__ . '/../..' . '/Core/WPStaging.php',
|
346 |
'WPStaging\\thirdParty\\thirdPartyCompatibility' => __DIR__ . '/../..' . '/Core/thirdParty/thirdPartyCompatibility.php',
|
347 |
+
'tad_DI52_Container' => __DIR__ . '/..' . '/lucatume/di52/src/tad/DI52/Container.php',
|
348 |
+
'tad_DI52_ContainerInterface' => __DIR__ . '/..' . '/lucatume/di52/src/tad/DI52/ContainerInterface.php',
|
349 |
+
'tad_DI52_ProtectedValue' => __DIR__ . '/..' . '/lucatume/di52/src/tad/DI52/ProtectedValue.php',
|
350 |
+
'tad_DI52_ServiceProvider' => __DIR__ . '/..' . '/lucatume/di52/src/tad/DI52/ServiceProvider.php',
|
351 |
+
'tad_DI52_ServiceProviderInterface' => __DIR__ . '/..' . '/lucatume/di52/src/tad/DI52/ServiceProviderInterface.php',
|
352 |
+
'xrstf\\Composer52\\AutoloadGenerator' => __DIR__ . '/..' . '/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php',
|
353 |
+
'xrstf\\Composer52\\Generator' => __DIR__ . '/..' . '/xrstf/composer-php52/lib/xrstf/Composer52/Generator.php',
|
354 |
);
|
355 |
|
356 |
public static function getInitializer(ClassLoader $loader)
|
358 |
return \Closure::bind(function () use ($loader) {
|
359 |
$loader->prefixLengthsPsr4 = ComposerStaticInitwpstgfree::$prefixLengthsPsr4;
|
360 |
$loader->prefixDirsPsr4 = ComposerStaticInitwpstgfree::$prefixDirsPsr4;
|
361 |
+
$loader->prefixesPsr0 = ComposerStaticInitwpstgfree::$prefixesPsr0;
|
362 |
$loader->classMap = ComposerStaticInitwpstgfree::$classMap;
|
363 |
|
364 |
}, null, ClassLoader::class);
|
vendor/composer/installed.json
CHANGED
@@ -1,4 +1,53 @@
|
|
1 |
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
{
|
3 |
"name": "psr/log",
|
4 |
"version": "1.1.3",
|
@@ -46,7 +95,10 @@
|
|
46 |
"log",
|
47 |
"psr",
|
48 |
"psr-3"
|
49 |
-
]
|
|
|
|
|
|
|
50 |
},
|
51 |
{
|
52 |
"name": "symfony/filesystem",
|
@@ -98,7 +150,10 @@
|
|
98 |
}
|
99 |
],
|
100 |
"description": "Symfony Filesystem Component",
|
101 |
-
"homepage": "https://symfony.com"
|
|
|
|
|
|
|
102 |
},
|
103 |
{
|
104 |
"name": "symfony/finder",
|
@@ -149,21 +204,24 @@
|
|
149 |
}
|
150 |
],
|
151 |
"description": "Symfony Finder Component",
|
152 |
-
"homepage": "https://symfony.com"
|
|
|
|
|
|
|
153 |
},
|
154 |
{
|
155 |
"name": "symfony/polyfill-ctype",
|
156 |
-
"version": "v1.
|
157 |
-
"version_normalized": "1.
|
158 |
"source": {
|
159 |
"type": "git",
|
160 |
"url": "https://github.com/symfony/polyfill-ctype.git",
|
161 |
-
"reference": "
|
162 |
},
|
163 |
"dist": {
|
164 |
"type": "zip",
|
165 |
-
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/
|
166 |
-
"reference": "
|
167 |
"shasum": ""
|
168 |
},
|
169 |
"require": {
|
@@ -172,11 +230,11 @@
|
|
172 |
"suggest": {
|
173 |
"ext-ctype": "For best performance"
|
174 |
},
|
175 |
-
"time": "2020-
|
176 |
"type": "library",
|
177 |
"extra": {
|
178 |
"branch-alias": {
|
179 |
-
"dev-
|
180 |
},
|
181 |
"thanks": {
|
182 |
"name": "symfony/polyfill",
|
@@ -213,6 +271,46 @@
|
|
213 |
"ctype",
|
214 |
"polyfill",
|
215 |
"portable"
|
216 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
}
|
218 |
]
|
1 |
[
|
2 |
+
{
|
3 |
+
"name": "lucatume/di52",
|
4 |
+
"version": "2.1.2",
|
5 |
+
"version_normalized": "2.1.2.0",
|
6 |
+
"source": {
|
7 |
+
"type": "git",
|
8 |
+
"url": "https://github.com/lucatume/di52.git",
|
9 |
+
"reference": "d0f9afbc609a1fed67a9396db5e99badf2e4f23a"
|
10 |
+
},
|
11 |
+
"dist": {
|
12 |
+
"type": "zip",
|
13 |
+
"url": "https://api.github.com/repos/lucatume/di52/zipball/d0f9afbc609a1fed67a9396db5e99badf2e4f23a",
|
14 |
+
"reference": "d0f9afbc609a1fed67a9396db5e99badf2e4f23a",
|
15 |
+
"shasum": ""
|
16 |
+
},
|
17 |
+
"require": {
|
18 |
+
"php": ">=5.2",
|
19 |
+
"xrstf/composer-php52": "1.*"
|
20 |
+
},
|
21 |
+
"require-dev": {
|
22 |
+
"phpunit/phpunit-mock-objects-php52": "dev-1.1.0-php52",
|
23 |
+
"phpunit/phpunit-php52": "dev-3.6.12-php52"
|
24 |
+
},
|
25 |
+
"time": "2020-10-27T15:26:20+00:00",
|
26 |
+
"type": "library",
|
27 |
+
"installation-source": "dist",
|
28 |
+
"autoload": {
|
29 |
+
"psr-0": {
|
30 |
+
"tad_DI52_": [
|
31 |
+
"src/"
|
32 |
+
]
|
33 |
+
}
|
34 |
+
},
|
35 |
+
"notification-url": "https://packagist.org/downloads/",
|
36 |
+
"license": [
|
37 |
+
"GPL-3.0"
|
38 |
+
],
|
39 |
+
"authors": [
|
40 |
+
{
|
41 |
+
"name": "Luca Tumedei",
|
42 |
+
"email": "luca@theaveragedev.com"
|
43 |
+
}
|
44 |
+
],
|
45 |
+
"description": "A PHP 5.2 compatible dependency injection container.",
|
46 |
+
"support": {
|
47 |
+
"issues": "https://github.com/lucatume/di52/issues",
|
48 |
+
"source": "https://github.com/lucatume/di52/tree/2.1.2"
|
49 |
+
}
|
50 |
+
},
|
51 |
{
|
52 |
"name": "psr/log",
|
53 |
"version": "1.1.3",
|
95 |
"log",
|
96 |
"psr",
|
97 |
"psr-3"
|
98 |
+
],
|
99 |
+
"support": {
|
100 |
+
"source": "https://github.com/php-fig/log/tree/1.1.3"
|
101 |
+
}
|
102 |
},
|
103 |
{
|
104 |
"name": "symfony/filesystem",
|
150 |
}
|
151 |
],
|
152 |
"description": "Symfony Filesystem Component",
|
153 |
+
"homepage": "https://symfony.com",
|
154 |
+
"support": {
|
155 |
+
"source": "https://github.com/symfony/filesystem/tree/v2.8.52"
|
156 |
+
}
|
157 |
},
|
158 |
{
|
159 |
"name": "symfony/finder",
|
204 |
}
|
205 |
],
|
206 |
"description": "Symfony Finder Component",
|
207 |
+
"homepage": "https://symfony.com",
|
208 |
+
"support": {
|
209 |
+
"source": "https://github.com/symfony/finder/tree/v2.8.50"
|
210 |
+
}
|
211 |
},
|
212 |
{
|
213 |
"name": "symfony/polyfill-ctype",
|
214 |
+
"version": "v1.19.0",
|
215 |
+
"version_normalized": "1.19.0.0",
|
216 |
"source": {
|
217 |
"type": "git",
|
218 |
"url": "https://github.com/symfony/polyfill-ctype.git",
|
219 |
+
"reference": "aed596913b70fae57be53d86faa2e9ef85a2297b"
|
220 |
},
|
221 |
"dist": {
|
222 |
"type": "zip",
|
223 |
+
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b",
|
224 |
+
"reference": "aed596913b70fae57be53d86faa2e9ef85a2297b",
|
225 |
"shasum": ""
|
226 |
},
|
227 |
"require": {
|
230 |
"suggest": {
|
231 |
"ext-ctype": "For best performance"
|
232 |
},
|
233 |
+
"time": "2020-10-23T09:01:57+00:00",
|
234 |
"type": "library",
|
235 |
"extra": {
|
236 |
"branch-alias": {
|
237 |
+
"dev-main": "1.19-dev"
|
238 |
},
|
239 |
"thanks": {
|
240 |
"name": "symfony/polyfill",
|
271 |
"ctype",
|
272 |
"polyfill",
|
273 |
"portable"
|
274 |
+
],
|
275 |
+
"support": {
|
276 |
+
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0"
|
277 |
+
}
|
278 |
+
},
|
279 |
+
{
|
280 |
+
"name": "xrstf/composer-php52",
|
281 |
+
"version": "v1.0.20",
|
282 |
+
"version_normalized": "1.0.20.0",
|
283 |
+
"source": {
|
284 |
+
"type": "git",
|
285 |
+
"url": "https://github.com/composer-php52/composer-php52.git",
|
286 |
+
"reference": "bd41459d5e27df8d33057842b32377c39e97a5a8"
|
287 |
+
},
|
288 |
+
"dist": {
|
289 |
+
"type": "zip",
|
290 |
+
"url": "https://api.github.com/repos/composer-php52/composer-php52/zipball/bd41459d5e27df8d33057842b32377c39e97a5a8",
|
291 |
+
"reference": "bd41459d5e27df8d33057842b32377c39e97a5a8",
|
292 |
+
"shasum": ""
|
293 |
+
},
|
294 |
+
"time": "2016-04-16T21:52:24+00:00",
|
295 |
+
"type": "library",
|
296 |
+
"extra": {
|
297 |
+
"branch-alias": {
|
298 |
+
"dev-default": "1.x-dev"
|
299 |
+
}
|
300 |
+
},
|
301 |
+
"installation-source": "dist",
|
302 |
+
"autoload": {
|
303 |
+
"psr-0": {
|
304 |
+
"xrstf\\Composer52": "lib/"
|
305 |
+
}
|
306 |
+
},
|
307 |
+
"notification-url": "https://packagist.org/downloads/",
|
308 |
+
"license": [
|
309 |
+
"MIT"
|
310 |
+
],
|
311 |
+
"support": {
|
312 |
+
"issues": "https://github.com/composer-php52/composer-php52/issues",
|
313 |
+
"source": "https://github.com/composer-php52/composer-php52"
|
314 |
+
}
|
315 |
}
|
316 |
]
|
vendor/lucatume/di52/.github/workflows/test-php-52.yml
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: PHP 5.2
|
2 |
+
on: push
|
3 |
+
jobs:
|
4 |
+
test:
|
5 |
+
name: PHPUnit tests
|
6 |
+
runs-on: ubuntu-latest
|
7 |
+
steps:
|
8 |
+
- name: Checkout code
|
9 |
+
uses: actions/checkout@v2
|
10 |
+
- name: Install Composer dependencies
|
11 |
+
run: composer install
|
12 |
+
- name: Pull tommylau/php-5.2
|
13 |
+
run: docker pull tommylau/php-5.2
|
14 |
+
- name: Build custom PHP 5.2 image
|
15 |
+
run: docker build ./_build/containers/php-52 --tag di52/php-52:latest
|
16 |
+
- name: Run PHPUnit tests
|
17 |
+
run: docker run --rm -v ${GITHUB_WORKSPACE}:/project di52/php-52
|
vendor/lucatume/di52/.github/workflows/test.yml
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: PHP 5.2+
|
2 |
+
on: push
|
3 |
+
jobs:
|
4 |
+
test:
|
5 |
+
name: PHPUnit tests
|
6 |
+
runs-on: ubuntu-latest
|
7 |
+
strategy:
|
8 |
+
matrix:
|
9 |
+
php: ["5.3","5.4","5.5","5.6","7.0","7.1","7.2","7.3","7.4"]
|
10 |
+
steps:
|
11 |
+
- name: Checkout code
|
12 |
+
uses: actions/checkout@v2
|
13 |
+
- name: Setup PHP
|
14 |
+
uses: shivammathur/setup-php@v2
|
15 |
+
with:
|
16 |
+
php-version: ${{matrix.php}}
|
17 |
+
- name: Swap composer.json file
|
18 |
+
run: rm composer.json; mv composer-5-3-plus.json composer.json
|
19 |
+
- name: Get Composer cache directory
|
20 |
+
id: composercache
|
21 |
+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
22 |
+
- name: Cache Composer dependencies
|
23 |
+
uses: actions/cache@v2
|
24 |
+
with:
|
25 |
+
path: ${{ steps.composercache.outputs.dir }}
|
26 |
+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
27 |
+
restore-keys: ${{ runner.os }}-composer-
|
28 |
+
- name: Install dependencies
|
29 |
+
run: composer update
|
30 |
+
- name: Swap the autoload file
|
31 |
+
run: rm -f vendor/autoload_52.php; cp vendor/autoload.php vendor/autoload_52.php
|
32 |
+
- name: Run PHPUnit tests
|
33 |
+
run: vendor/bin/phpunit-php52
|
vendor/lucatume/di52/.gitignore
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.idea
|
2 |
+
# Created by .ignore support plugin (hsz.mobi)
|
3 |
+
### Composer template
|
4 |
+
vendor/
|
5 |
+
|
6 |
+
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
|
7 |
+
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
|
8 |
+
# composer.lock
|
9 |
+
|
10 |
+
tests/coverage
|
11 |
+
|
vendor/lucatume/di52/.phpstorm.meta.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace PHPSTORM_META {
|
4 |
+
$STATIC_METHOD_TYPES = [
|
5 |
+
\tad_DI52_Container::make( '' ) => [
|
6 |
+
"" == "@",
|
7 |
+
],
|
8 |
+
];
|
9 |
+
}
|
vendor/lucatume/di52/CHANGELOG.md
ADDED
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Change Log
|
2 |
+
All notable changes to this project will be documented in this file.
|
3 |
+
This project adheres to [Semantic Versioning](http://semver.org/).
|
4 |
+
|
5 |
+
## [unreleased] Unreleased
|
6 |
+
|
7 |
+
## [2.1.2] 2020-10-27;
|
8 |
+
|
9 |
+
### Fixed
|
10 |
+
- PHP 5.3 and 7.4 incompatibility issues
|
11 |
+
### Changed
|
12 |
+
- moved the builds to GitHub Actions
|
13 |
+
|
14 |
+
## [2.1.1] 2020-10-23;
|
15 |
+
|
16 |
+
### Added
|
17 |
+
- new build tools to the repository
|
18 |
+
### Changed
|
19 |
+
- refactor `Container::callback` code to re-use callbacks when available (thanks @sc0ttkclark)
|
20 |
+
### Fixed
|
21 |
+
- fix an issue where the Closure produced by the `callback` method would build the object for static method calls
|
22 |
+
|
23 |
+
## [2.1.0] - 2020-07-14
|
24 |
+
### Added
|
25 |
+
- support for one parameter singletong binding of concrete, instantiatable, classes, thanks @Luc45
|
26 |
+
|
27 |
+
## [2.0.12] - 2019-10-14
|
28 |
+
### Added
|
29 |
+
- add PHPStorm make method auto-completion (thanks @Luc45)
|
30 |
+
|
31 |
+
## [2.0.11] - 2019-09-26
|
32 |
+
### Changed
|
33 |
+
- improve exception throwing to show original exceptions when the building of a bound class, interface or slug fails
|
34 |
+
|
35 |
+
## [2.0.10] - 2018-10-29
|
36 |
+
### Fixed
|
37 |
+
- an issue with array variable handling
|
38 |
+
- made error message more clear for non-string offsets
|
39 |
+
|
40 |
+
## [2.0.9] - 2017-09-26
|
41 |
+
### Fixed
|
42 |
+
- issue with `setVar` method where, in some instances, variable values could not be overridden
|
43 |
+
|
44 |
+
## [2.0.8] - 2017-07-18
|
45 |
+
### Fixed
|
46 |
+
- check for file existence in autoload script (thanks @truongwp)
|
47 |
+
|
48 |
+
## [2.0.7] - 2017-06-15
|
49 |
+
### Fixed
|
50 |
+
- issue where non registered classes object dependencies would be built just the first time (issue #2)
|
51 |
+
|
52 |
+
## [2.0.6] - 2017-05-09
|
53 |
+
### Fixed
|
54 |
+
- fix handling of unbound interface arguments
|
55 |
+
|
56 |
+
## [2.0.5] - 2017-02-22
|
57 |
+
### Changed
|
58 |
+
- change internal method visibility to improve compatibility with monkey patching libraries
|
59 |
+
|
60 |
+
## [2.0.4] - 2017-02-22
|
61 |
+
### Fixed
|
62 |
+
- allow unbound classes with `__construct` method requirements to be used in `instance` callbacks
|
63 |
+
|
64 |
+
## [2.0.3] - 2017-02-07
|
65 |
+
### Fixed
|
66 |
+
- support for use of `callback` to feed `instance` and viceversa
|
67 |
+
|
68 |
+
## [2.0.2] - 2017-02-02
|
69 |
+
### Fixed
|
70 |
+
- support for built objects in `instance` and `callback` methods
|
71 |
+
|
72 |
+
## [2.0.1] - 2017-01-23
|
73 |
+
### Fixed
|
74 |
+
- an issue where re-binding implementations could lead to built objects still using previous bindings
|
75 |
+
|
76 |
+
#### Changed
|
77 |
+
- removed some dead code left over from previous iterations
|
78 |
+
|
79 |
+
## [2.0.0] - 2017-01-21
|
80 |
+
### Added
|
81 |
+
- `instance` and `callback` methods
|
82 |
+
|
83 |
+
### Changed
|
84 |
+
- refactored the code completely
|
85 |
+
- the README file to update it to the new code
|
86 |
+
|
87 |
+
### Removed
|
88 |
+
- support for array based construction instructions (see `instance` methods)
|
89 |
+
|
90 |
+
## [1.4.5] - 2017-01-19
|
91 |
+
### Fixed
|
92 |
+
- an issue where singleton resolution would result in circular reference on some Windows versions (thanks @bordoni)
|
93 |
+
|
94 |
+
## [1.4.4] - 2017-01-09
|
95 |
+
### Added
|
96 |
+
- support for binding replacement
|
97 |
+
|
98 |
+
## [1.4.3] - 2016-10-18
|
99 |
+
### Changed
|
100 |
+
- snake_case method names are now set to camelCase
|
101 |
+
|
102 |
+
### Fixed
|
103 |
+
- an inheritance issue on PHP 5.2
|
104 |
+
- non PHP 5.2 compatible tests
|
105 |
+
|
106 |
+
### Added
|
107 |
+
- Travis CI support and build
|
108 |
+
|
109 |
+
## [1.4.2] - 2016-10-14
|
110 |
+
### Fixed
|
111 |
+
- nested dependency resolution issue with interfaces and default values
|
112 |
+
|
113 |
+
## [1.4.1b] - 2016-10-14
|
114 |
+
### Fixed
|
115 |
+
- pass the `afterBuildMethods` argument along...
|
116 |
+
|
117 |
+
## [1.4.1] - 2016-10-14
|
118 |
+
### Fixed
|
119 |
+
- updated `tad_di512_Container` `bind` and `singleton` methods signatures
|
120 |
+
|
121 |
+
## [1.4.0] - 2016-10-14
|
122 |
+
### Added
|
123 |
+
- more informative exception message when trying to resolve unbound slug or non existing class
|
124 |
+
- support for after build methods
|
125 |
+
|
126 |
+
### Fixed
|
127 |
+
- another nested dependency resolving issue
|
128 |
+
|
129 |
+
## [1.3.2] - 2016-07-28
|
130 |
+
### Fixed
|
131 |
+
- nested dependency resolving issue
|
132 |
+
|
133 |
+
## [1.3.1] - 2016-04-19
|
134 |
+
### Added
|
135 |
+
- more informative exception message when default primitive value is missing
|
136 |
+
|
137 |
+
## [1.3.0] - 2016-04-19
|
138 |
+
### Added
|
139 |
+
- support for the custom bindings
|
140 |
+
- support for same class singleton binding
|
141 |
+
|
142 |
+
### Changed
|
143 |
+
- performance optimization
|
144 |
+
|
145 |
+
## [1.2.6] - 2016-04-11
|
146 |
+
### Changed
|
147 |
+
- internal workings to improve performance (using [@TomBZombie benchmarks](https://github.com/TomBZombie/php-dependency-injection-benchmarks)
|
148 |
+
|
149 |
+
## [1.2.5] - 2016-03-06
|
150 |
+
### Added
|
151 |
+
- support for decorator pattern in PHP 5.2 compatible syntax
|
152 |
+
- code highlighting for code examples in doc (thanks @omarreiss)
|
153 |
+
|
154 |
+
## [1.2.4] - 2016-03-05
|
155 |
+
### Added
|
156 |
+
- tests for uncovered code
|
157 |
+
|
158 |
+
## [1.2.3] - 2016-03-04
|
159 |
+
### Fixed
|
160 |
+
- singleton resolution for same implementations
|
161 |
+
|
162 |
+
## [1.2.2] - 2016-02-13
|
163 |
+
- doc updates
|
164 |
+
|
165 |
+
## [1.2.1] - 2016-02-13
|
166 |
+
### Added
|
167 |
+
- `hasTag($tag)` method to the container
|
168 |
+
- `isBound($classOrInterface)` method to the container
|
169 |
+
- support for deferred service providers
|
170 |
+
|
171 |
+
## [1.2.1] - 2016-01-23
|
172 |
+
### Added
|
173 |
+
- tagging support
|
174 |
+
- service providers support
|
175 |
+
|
176 |
+
## [1.2.0] - 2016-01-22
|
177 |
+
### Added
|
178 |
+
- the binding and automatic resolution API ([code inspiration](https://www.ltconsulting.co.uk/automatic-dependency-injection-with-phps-reflection-api/))
|
179 |
+
|
180 |
+
## [1.1.2] - 2016-01-19
|
181 |
+
### Fixed
|
182 |
+
- resolution for objects in arrays
|
183 |
+
|
184 |
+
## [1.1.1] - 2016-01-19
|
185 |
+
### Added
|
186 |
+
- support for the `%varName%` variable notation.
|
187 |
+
|
188 |
+
## [1.1.0] - 2016-01-18
|
189 |
+
### Added
|
190 |
+
- array resolution support for the Array Access API.
|
191 |
+
- the changelog.
|
192 |
+
|
193 |
+
[1.0.2]: https://github.com/lucatume/di52/compare/1.0.1...1.0.2
|
194 |
+
[1.0.3]: https://github.com/lucatume/di52/compare/1.0.2...1.0.3
|
195 |
+
[1.1.0]: https://github.com/lucatume/di52/compare/1.0.3...1.1.0
|
196 |
+
[1.1.1]: https://github.com/lucatume/di52/compare/1.0.3...1.1.2
|
197 |
+
[1.1.2]: https://github.com/lucatume/di52/compare/1.0.3...1.1.2
|
198 |
+
[1.2.0]: https://github.com/lucatume/di52/compare/1.1.2...1.2.0
|
199 |
+
[1.2.0]: https://github.com/lucatume/di52/compare/1.1.2...1.2.0
|
200 |
+
[1.2.1]: https://github.com/lucatume/di52/compare/1.2.0...1.2.1
|
201 |
+
[1.2.2]: https://github.com/lucatume/di52/compare/1.2.1...1.2.2
|
202 |
+
[1.2.3]: https://github.com/lucatume/di52/compare/1.2.2...1.2.3
|
203 |
+
[1.2.4]: https://github.com/lucatume/di52/compare/1.2.3...1.2.4
|
204 |
+
[1.2.5]: https://github.com/lucatume/di52/compare/1.2.4...1.2.5
|
205 |
+
[1.2.6]: https://github.com/lucatume/di52/compare/1.2.5...1.2.6
|
206 |
+
[1.3.0]: https://github.com/lucatume/di52/compare/1.2.6...1.3.0
|
207 |
+
[1.3.1]: https://github.com/lucatume/di52/compare/1.3.0...1.3.1
|
208 |
+
[1.3.2]: https://github.com/lucatume/di52/compare/1.3.1...1.3.2
|
209 |
+
[1.4.0]: https://github.com/lucatume/di52/compare/1.3.1...1.4.0
|
210 |
+
[1.4.1]: https://github.com/lucatume/di52/compare/1.4.0...1.4.1
|
211 |
+
[1.4.1b]: https://github.com/lucatume/di52/compare/1.4.1...1.4.1b
|
212 |
+
[1.4.2]: https://github.com/lucatume/di52/compare/1.4.1b...1.4.2
|
213 |
+
[1.4.3]: https://github.com/lucatume/di52/compare/1.4.2...1.4.3
|
214 |
+
[1.4.4]: https://github.com/lucatume/di52/compare/1.4.3...1.4.4
|
215 |
+
[1.4.5]: https://github.com/lucatume/di52/compare/1.4.4...1.4.5
|
216 |
+
[2.0.0]: https://github.com/lucatume/di52/compare/1.4.5...2.0.0
|
217 |
+
[2.0.1]: https://github.com/lucatume/di52/compare/2.0.0...2.0.1
|
218 |
+
[2.0.2]: https://github.com/lucatume/di52/compare/2.0.1...2.0.2
|
219 |
+
[2.0.3]: https://github.com/lucatume/di52/compare/2.0.2...2.0.3
|
220 |
+
[2.0.4]: https://github.com/lucatume/di52/compare/2.0.3...2.0.4
|
221 |
+
[2.0.5]: https://github.com/lucatume/di52/compare/2.0.4...2.0.5
|
222 |
+
[2.0.6]: https://github.com/lucatume/di52/compare/2.0.5...2.0.6
|
223 |
+
[2.0.7]: https://github.com/lucatume/di52/compare/2.0.6...2.0.7
|
224 |
+
[2.0.8]: https://github.com/lucatume/di52/compare/2.0.7...2.0.8
|
225 |
+
[2.0.9]: https://github.com/lucatume/di52/compare/2.0.8...2.0.9
|
226 |
+
[2.0.10]: https://github.com/lucatume/di52/compare/2.0.9...2.0.10
|
227 |
+
[2.0.11]: https://github.com/lucatume/di52/compare/2.0.10...2.0.11
|
228 |
+
[2.0.12]: https://github.com/lucatume/di52/compare/2.0.11...2.0.12
|
229 |
+
[2.1.0]: https://github.com/lucatume/di52/compare/2.0.12...2.1.0
|
230 |
+
[2.1.1]: https://github.com/lucatume/di52/compare/2.1.0...2.1.1
|
231 |
+
[2.1.2]: https://github.com/lucatume/di52/compare/2.1.1...2.1.2
|
232 |
+
[Unreleased]: https://github.com/lucatume/di52/compare/2.1.2...HEAD
|
vendor/lucatume/di52/README.md
ADDED
@@ -0,0 +1,688 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
A PHP 5.2 compatible dependency injection container heavily inspired by [Laravel IOC](https://laravel.com/docs/5.0/container "Service Container - Laravel - The PHP Framework For Web Artisans") and [Pimple](http://pimple.sensiolabs.org/ "Pimple - A simple PHP Dependency Injection Container") that works even better on newer version of PHP.
|
2 |
+
|
3 |
+
[![Build Status](https://travis-ci.org/lucatume/di52.svg?branch=master)](https://travis-ci.org/lucatume/di52)
|
4 |
+
|
5 |
+
## Installation
|
6 |
+
Use [Composer](https://getcomposer.org/) to require the library:
|
7 |
+
|
8 |
+
```bash
|
9 |
+
composer require lucatume/di52
|
10 |
+
```
|
11 |
+
|
12 |
+
Include the [Composer](https://getcomposer.org/) autoload file in your project entry point and create a new instance of the container to start using it:
|
13 |
+
|
14 |
+
```php
|
15 |
+
require_once 'vendor/autoload.php'
|
16 |
+
|
17 |
+
$container = new tad_DI52_Container();
|
18 |
+
```
|
19 |
+
|
20 |
+
If that's not an option then clone or download the package and require the `di52/autoload.php` file in your code:
|
21 |
+
|
22 |
+
```php
|
23 |
+
require_once 'path/to/di52/autoload.php'
|
24 |
+
|
25 |
+
$container = new tad_DI52_Container();
|
26 |
+
```
|
27 |
+
|
28 |
+
Where `path/to/di52/autoload.php` is the absolute path to the `autoload.php` file found in di52 root folder.
|
29 |
+
|
30 |
+
### PHP 5.2 Installation
|
31 |
+
While the container will work on newer versions of php it was born to support PHP 5.2 out of the box; if the application requires it I suggest [requiring the `xrstf/composer-php52` package](https://packagist.org/packages/xrstf/composer-php52 "xrstf/composer-php52 - Packagist") to handle autoloading on PHP 5.2 compatible code.
|
32 |
+
|
33 |
+
## PHP 5.2 examples, PHP 7 ready code
|
34 |
+
While the examples in the code are, for the most part, PHP 5.2 compatible di52 will work even better with newer versions of PHP.
|
35 |
+
|
36 |
+
## Code example
|
37 |
+
```php
|
38 |
+
// ClassOne.php
|
39 |
+
class ClassOne implements InterfaceOne {}
|
40 |
+
|
41 |
+
// MysqlConnection.php
|
42 |
+
class MysqlConnection implements DbConnectionInterface {}
|
43 |
+
|
44 |
+
// ClassThree.php
|
45 |
+
class ClassThree {
|
46 |
+
public function __construct(InterfaceOne $one, DbConnectionInterface $db){
|
47 |
+
// ...
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
// in the application bootstrap file
|
52 |
+
$container = new tad_DI52_Container();
|
53 |
+
|
54 |
+
$container->bind('InterfaceOne', 'ClassOne');
|
55 |
+
$container->singleton('DbConnectionInterface', 'MysqlConnection');
|
56 |
+
|
57 |
+
$three = $container->make('ClassThree');
|
58 |
+
```
|
59 |
+
|
60 |
+
## Quick and dirty introduction to dependency injection and DI containers
|
61 |
+
|
62 |
+
### What is dependency injection?
|
63 |
+
|
64 |
+
A [Dependency Injection (DI) Container](https://en.wikipedia.org/wiki/Dependency_injection "Dependency injection - Wikipedia") is a tool meant to make dependency injection possible and easy to manage.
|
65 |
+
Dependencies are specified by a class constructor method via [**type-hinting**](http://php.net/manual/en/language.oop5.typehinting.php "PHP: Type Hinting - Manual"):
|
66 |
+
|
67 |
+
```php
|
68 |
+
class A {
|
69 |
+
private $b;
|
70 |
+
private $c;
|
71 |
+
|
72 |
+
public function __construct(B $b, C $c){
|
73 |
+
$this->b = $b;
|
74 |
+
$this->c = $c;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
```
|
78 |
+
|
79 |
+
Any instance of class `A` **depends** on implementations of the `B` and `C` classes.
|
80 |
+
The "injection" happens when class `A` dependencies are passed to it, "injected" in its constructor method, in place of being created inside the class itself.
|
81 |
+
|
82 |
+
|
83 |
+
```php
|
84 |
+
$a = new A(new B(), new C());
|
85 |
+
```
|
86 |
+
|
87 |
+
The flexibility of type hinting allows injecting into `A` not just instances of `B` and `C` but instances of any class extending the two:
|
88 |
+
|
89 |
+
```php
|
90 |
+
class ExtendedB extends B {}
|
91 |
+
|
92 |
+
class ExtendedC extends C {}
|
93 |
+
|
94 |
+
$a = new a(new ExtendedB(), new ExtendedC());
|
95 |
+
```
|
96 |
+
|
97 |
+
PHP allows type hinting not just **concrete implementations** (classes) but **interfaces** too:
|
98 |
+
|
99 |
+
```php
|
100 |
+
class A {
|
101 |
+
private $b;
|
102 |
+
private $c;
|
103 |
+
|
104 |
+
public function __construct(BInterface $b, CInterface $c){
|
105 |
+
$this->b = $b;
|
106 |
+
$this->c = $c;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
```
|
110 |
+
|
111 |
+
This extends the possibilities of dependency injection even further and avoids strict coupling of the code:
|
112 |
+
|
113 |
+
```php
|
114 |
+
class B implements BInterface {}
|
115 |
+
|
116 |
+
class C implements CInterface {}
|
117 |
+
|
118 |
+
$a = new a(new B(), new C());
|
119 |
+
```
|
120 |
+
|
121 |
+
### What is a DI container?
|
122 |
+
The `B` and `C` classes are concrete (as in "you can instance them") implementations of interfaces and while the interfaces might never change the implementations might and should change in the lifecycle of code: that's the [Dependency Inversion principle](https://en.wikipedia.org/wiki/Dependency_inversion_principle) or "depend upon abstraction, non concretions".
|
123 |
+
If the implementation of `BInterface` changes from `B` to `BetterB` then I'd have to update all the code where I'm building instances of `A` to use `BetterB` in place of `B`:
|
124 |
+
|
125 |
+
```php
|
126 |
+
|
127 |
+
// before
|
128 |
+
$a = new A(new B(), new C());
|
129 |
+
|
130 |
+
//after
|
131 |
+
$a = new A(new BetterB(), new C());
|
132 |
+
```
|
133 |
+
|
134 |
+
On smaller code-bases this might prove to be a quick solution but, as the code grows, it will become less and less an applicable solution.
|
135 |
+
Adding classes to the mix proves the point when dependencies start to stack:
|
136 |
+
|
137 |
+
```php
|
138 |
+
class D implements DInterface{
|
139 |
+
public function __construct(AInterface $a, CInterface $c){}
|
140 |
+
}
|
141 |
+
|
142 |
+
class E {
|
143 |
+
public function __construct(DInterface $d){}
|
144 |
+
}
|
145 |
+
|
146 |
+
$a = new A (new BetterB(), new C());
|
147 |
+
$d = new D($a, $c);
|
148 |
+
$e = new E($d);
|
149 |
+
```
|
150 |
+
|
151 |
+
Another issue with this approach is that classes have to be built immediately to be injected, see `$a` and `$d` above to feed `$e`, with the immediate cost of "eager" instantiation, if `$e` is never used than the effort put into building it, in terms of time and resources spent by PHP to build `$a`, `$b`, `$c`, `$d` and finally `$e`, are wasted.
|
152 |
+
A **dependency injection container** is an object that, provided construction templates of objects, will take care of building only objects that are really needed taking care of **resolving** nested dependencies.
|
153 |
+
|
154 |
+
>Need an instance of `E`? I will build instances of `B` and `C` to build an instance of `A` to build an instance of `D` to finally build and return an instance of `E`.
|
155 |
+
|
156 |
+
### Construction templates
|
157 |
+
The container will need to be told, just once, how objects should be built.
|
158 |
+
For the container it's easy to understand that a class type-hinting an instance of the concrete class `A` will require a new instance of `A` but loosely coupled code leveraging the use of a DI container will probably type-hint an `interface` in place of concrete `class`es.
|
159 |
+
Telling the container what concrete `class` to instance when a certain `interface` is requested by an object `__construct` method is called "binding and implementation to an interface".
|
160 |
+
While dependency injection can be made in other methods too beyond the `__construct` one that's what di52 supports at the moment; if you want to read more the web is full of good reference material, [this article by Fabien Potencier](http://fabien.potencier.org/what-is-dependency-injection.html) is a very good start.
|
161 |
+
|
162 |
+
## The power of make
|
163 |
+
At its base the container is a dependency resolution and injection machine: given a class to its `make` method it will read the class type-hinted dependencies, build them and inject them in the class.
|
164 |
+
|
165 |
+
```php
|
166 |
+
// file ClassThree.php
|
167 |
+
class ClassThree {
|
168 |
+
private $one;
|
169 |
+
private $two;
|
170 |
+
|
171 |
+
public function __construct(ClassOne $one, ClassTwo $two){
|
172 |
+
$this->one = $one;
|
173 |
+
$this->two = $two;
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
// application bootstrap file
|
178 |
+
$container = new tad_DI52_Container();
|
179 |
+
|
180 |
+
$three = $container->make('ClassThree');
|
181 |
+
```
|
182 |
+
|
183 |
+
Keep that in mind while reading the following paragraphs.
|
184 |
+
|
185 |
+
## Storing variables
|
186 |
+
In its most basic use case the container can store variables:
|
187 |
+
|
188 |
+
```php
|
189 |
+
$container = new tad_DI52_Container();
|
190 |
+
|
191 |
+
$container->setVar('foo', 23);
|
192 |
+
|
193 |
+
$foo = $container->getVar('foo');
|
194 |
+
```
|
195 |
+
|
196 |
+
Since di52 will treat any callable object as a factory (see below) callables have to be protected using the container `protect` method:
|
197 |
+
|
198 |
+
```php
|
199 |
+
$container = new tad_DI52_Container();
|
200 |
+
|
201 |
+
$container->setVar('foo.factory', $container->protect(function($val){
|
202 |
+
return $val + 23;
|
203 |
+
}));
|
204 |
+
|
205 |
+
$foo = $container->getVar('foo');
|
206 |
+
```
|
207 |
+
|
208 |
+
## Binding implementations
|
209 |
+
Once an instance of di52 is available telling it what should be built and when is quite easy; di52 proposes the same API exposed by [Laravel Service container](https://laravel.com/docs/5.3/container "Service Container - Laravel - The PHP Framework For Web ...") and while the inner workings are different the good idea (Laravel's) is reused.
|
210 |
+
Reusing the example above:
|
211 |
+
|
212 |
+
```php
|
213 |
+
$container = new tad_DI52_Container();
|
214 |
+
|
215 |
+
// binding
|
216 |
+
$container->bind('AInterface', 'A');
|
217 |
+
$container->bind('BInterface', 'BetterB');
|
218 |
+
$container->bind('CInterface', 'C');
|
219 |
+
$container->bind('DInterface', 'D');
|
220 |
+
|
221 |
+
// constructing
|
222 |
+
$e = $container->make('E');
|
223 |
+
```
|
224 |
+
|
225 |
+
The `make` method will build the `E` object resolving its requirements to the bound implementations when requested.
|
226 |
+
When using the `bind` method a new instance of the bound implementations will be returned on each request; this might not be the wanted behaviour especially for object costly to build (like a database driver that needs to connect): in that case the `singleton` method should be used:
|
227 |
+
|
228 |
+
```php
|
229 |
+
$container = new tad_DI52_Container();
|
230 |
+
|
231 |
+
$container->singleton('DBDriverInterface', 'MYSqlDriver');
|
232 |
+
$container->singleton('RepositoryInterface', 'MYSQLRepository');
|
233 |
+
|
234 |
+
$container->make('RepositoryInterface');
|
235 |
+
```
|
236 |
+
|
237 |
+
Binding an implementation to an interface using the `singleton` methods tells the container the implementations should be built just the first time: any later call for that same interface should return the same instance.
|
238 |
+
Implementations can be redefined in any moment simple calling the `bind` or `singleton` methods again specifying a different implementation.
|
239 |
+
|
240 |
+
## Binding objects
|
241 |
+
The container allows binding (using the `bind` or the `singleton` method) more than just implementations in the form of class names to take into account various scenarios where objects might be pre-existing in previous code or built in an other way; when binding an object that same object will be returned each time making the use of `bind` and `singleton` equivalent:
|
242 |
+
|
243 |
+
```php
|
244 |
+
$container = new tad_DI52_Container();
|
245 |
+
|
246 |
+
// a globally stored instance of the database handling class
|
247 |
+
global $db;
|
248 |
+
|
249 |
+
$container->bind('DBInterface', $db);
|
250 |
+
|
251 |
+
// binding an object that's built using a factory
|
252 |
+
$container->bind('RepositoryInterface', RepositoryFactory::make('post'));
|
253 |
+
|
254 |
+
if($condition) {
|
255 |
+
$handler = new HandlerOne();
|
256 |
+
} else {
|
257 |
+
$handler = new HandlerTwo();
|
258 |
+
}
|
259 |
+
|
260 |
+
// binding an object that's built in some other way
|
261 |
+
$container->bind('HandlerInterface', $handler);
|
262 |
+
```
|
263 |
+
|
264 |
+
## Binding closures on PHP 5.3+
|
265 |
+
All of the cases above suffers from an "eager instantiation" that's far from being ideal; if that's the case and the code runs on PHP 5.3+ then closures can be bound as factories using `bind` and as singletons using `singleton`:
|
266 |
+
|
267 |
+
```php
|
268 |
+
$container = new tad_DI52_Container();
|
269 |
+
|
270 |
+
// binding an object that's built using a factory using a closure
|
271 |
+
$container->bind('RepositoryInterface', function(){
|
272 |
+
return RepositoryFactory::make('post');
|
273 |
+
});
|
274 |
+
|
275 |
+
// binding an object that's built in some other way
|
276 |
+
$container->singleton('HandlerInterface', function(){
|
277 |
+
if($condition) {
|
278 |
+
$handler = new HandlerOne();
|
279 |
+
} else {
|
280 |
+
$handler = new HandlerTwo();
|
281 |
+
}
|
282 |
+
});
|
283 |
+
```
|
284 |
+
|
285 |
+
Closures will receive the container itself as an argument and will be able to leverage its resolution power:
|
286 |
+
|
287 |
+
```php
|
288 |
+
$container = new tad_DI52_Container();
|
289 |
+
|
290 |
+
$container->make('DBDriverInterface', 'MYSQLDriver');
|
291 |
+
|
292 |
+
$container->bind('DBInterface', function(tad_DI52_Container $container){
|
293 |
+
$dbDriver = $container->make('DBDriverInterface');
|
294 |
+
|
295 |
+
return new DBConnection($dbDriver);
|
296 |
+
});
|
297 |
+
```
|
298 |
+
|
299 |
+
## Binding implementations to classes
|
300 |
+
Binding implementations to interfaces works when the object constructor methods type hint interfaces but that might not always be the case; the container will handle that case allowing implementations to be bound to classes supporting both the `bind` and the `singleton` methods:
|
301 |
+
|
302 |
+
```php
|
303 |
+
// file LegacyClass.php
|
304 |
+
class LegacyClass {
|
305 |
+
public function __construct(ClassOne $one, ClassTwo $two){}
|
306 |
+
}
|
307 |
+
|
308 |
+
// app bootstrap file
|
309 |
+
$container = new tad_DI52_Container();
|
310 |
+
|
311 |
+
$container->bind('ClassOne', 'ModernClassOne');
|
312 |
+
$container->bind('ClassTwo', 'ModernClassTwo');
|
313 |
+
|
314 |
+
// the container will inject instances of the `ModernClassOne` and `ModernClassTwo` classes
|
315 |
+
$container->make('LegacyClass');
|
316 |
+
```
|
317 |
+
|
318 |
+
### Registering concrete instantiable classes as singleton
|
319 |
+
The container knows how to `make` instances of a concrete, instantiatable class, and there might be situations where
|
320 |
+
the requirement is to have `make` return the same singleton instance of a class on each call.
|
321 |
+
|
322 |
+
In those situations the binding syntax can be shortened to one parameter in place of two:
|
323 |
+
|
324 |
+
```php
|
325 |
+
// I want the `ClassOne` instance returned by the container to be the same every time.
|
326 |
+
|
327 |
+
// app bootstrap file
|
328 |
+
$container = new tad_DI52_Container();
|
329 |
+
|
330 |
+
// This is the short syntax to instruct the container to bind `ClassOne` as a singleton.
|
331 |
+
// This is the short form of this: $container->singleton(ClassOne::class, ClassOne::class);
|
332 |
+
$container->singleton(ClassOne::class);
|
333 |
+
|
334 |
+
assert($container->make(ClassOne::class) === $container->make(ClassOne::class));
|
335 |
+
```
|
336 |
+
|
337 |
+
## Binding implementations to slugs
|
338 |
+
The container was heavily inspired by [Pimple](http://pimple.sensiolabs.org/ "Pimple - A simple PHP Dependency Injection Container") and offers some features of the PHP 5.3+ DI container as well:
|
339 |
+
|
340 |
+
```php
|
341 |
+
$container = new tad_DI52_Container();
|
342 |
+
|
343 |
+
$container['db.driver'] = 'MYSQLDriver';
|
344 |
+
|
345 |
+
// storing a closure as a singleton constructor
|
346 |
+
$container['db.connection'] = function($container){
|
347 |
+
$dbDriver = $container->make('db.driver');
|
348 |
+
|
349 |
+
return new DBConnection($dbDriver);
|
350 |
+
};
|
351 |
+
|
352 |
+
$dbConnection = $container['db.connection'];
|
353 |
+
|
354 |
+
// storing a closure as a var
|
355 |
+
$container['uniqid'] = $container->protect(function(){
|
356 |
+
return uniqid('id', true);
|
357 |
+
});
|
358 |
+
|
359 |
+
// storing vars
|
360 |
+
$container['db.name'] = 'appDb';
|
361 |
+
$container['db.user'] = 'root';
|
362 |
+
$container['db.pass'] = '';
|
363 |
+
$container['db.host'] = 'localhost';
|
364 |
+
|
365 |
+
// getting vars
|
366 |
+
$dbName = $container['db.name'];
|
367 |
+
$dbUser = $container['db.user'];
|
368 |
+
$dbPass = $container['db.pass'];
|
369 |
+
$dbHost = $container['db.host'];
|
370 |
+
```
|
371 |
+
|
372 |
+
There is no replacement for the `factory` method offered by Pimple: the `bind` method should be used instead.
|
373 |
+
|
374 |
+
## Contextual binding
|
375 |
+
Borrowing an excellent idea from Laravel's container the possibility of contextual binding exists (supporting all the binding possibilities above).
|
376 |
+
Contextual binding solves the problem of different objects requiring different implementations of the same interface (or class, see above):
|
377 |
+
|
378 |
+
```php
|
379 |
+
$container = new tad_DI52_Container();
|
380 |
+
|
381 |
+
// by default any object requiring an implementation of the `CacheInterface`
|
382 |
+
// should be given the same instance of `Array Cache`
|
383 |
+
$container->singleton('CacheInterface', 'ArrayCache');
|
384 |
+
|
385 |
+
$container->bind('DbCache', function($container){
|
386 |
+
$cache = $container->make('CacheInterface');
|
387 |
+
$dbCache = new DbCache($cache);
|
388 |
+
$dbCache->prime();
|
389 |
+
$dbCache->dump();
|
390 |
+
|
391 |
+
return $dbCache;
|
392 |
+
});
|
393 |
+
|
394 |
+
// but when an implementation of the `CacheInterface` is requested by `TransactionManager`
|
395 |
+
// give it an instance of `DbCache` instead
|
396 |
+
$container->when('TransactionManager')
|
397 |
+
->needs('CacheInterface')
|
398 |
+
->give('DbCache');
|
399 |
+
```
|
400 |
+
|
401 |
+
## After-build methods
|
402 |
+
When working on PHP 5.2 compatible code closures will not be available and while that does impose limits di52 tries to "limit the damage".
|
403 |
+
The last code example could be rewritten in PHP 5.2 compatible code leveraging the container support for after-build methods: methods that will be called **with no arguments** on the built objects after it has been built:
|
404 |
+
|
405 |
+
```php
|
406 |
+
$container = new tad_DI52_Container();
|
407 |
+
|
408 |
+
$container->singleton('CacheInterface', 'ArrayCache');
|
409 |
+
|
410 |
+
$container->singleton('DbCache', 'DbCache', array('prime', 'dump'));
|
411 |
+
|
412 |
+
$container->when('TransactionManager')
|
413 |
+
->needs('CacheInterface')
|
414 |
+
->give('DbCache');
|
415 |
+
```
|
416 |
+
|
417 |
+
After-build methods can be specified as the third argument of the `bind` an `singleton` methods.
|
418 |
+
If the implementation is bound using `singleton` then the after-build methods will be called only the first time when the object is built.
|
419 |
+
|
420 |
+
## Binding decorator chains
|
421 |
+
The [Decorator pattern](https://en.wikipedia.org/wiki/Decorator_pattern "Decorator pattern - Wikipedia") allows extending the functionalities of an implementation without creating an extension and leveraging interfaces.
|
422 |
+
In very simple terms:
|
423 |
+
|
424 |
+
```php
|
425 |
+
|
426 |
+
interface EndpointInterface {
|
427 |
+
public function get();
|
428 |
+
}
|
429 |
+
|
430 |
+
class BaseEndpoint implements EndpointInterface {
|
431 |
+
private $repository;
|
432 |
+
|
433 |
+
public function __construct(ReposistoryInterface $repository) {
|
434 |
+
$this->repository = $repository;
|
435 |
+
}
|
436 |
+
|
437 |
+
public function get() {
|
438 |
+
return $this->repository->getAll();
|
439 |
+
}
|
440 |
+
}
|
441 |
+
|
442 |
+
class CachingEndpoint implements EndpointInterface {
|
443 |
+
private $decorated;
|
444 |
+
private $cache;
|
445 |
+
|
446 |
+
public function __construct(EndpointInterface $decorated, CacheInterface $cache ) {
|
447 |
+
$this->decorated = $decorated;
|
448 |
+
$this->cache = $cache;
|
449 |
+
}
|
450 |
+
|
451 |
+
public function get() {
|
452 |
+
$data = $this->cache->get('data')
|
453 |
+
|
454 |
+
if(false === $data) {
|
455 |
+
$data = $this->decorated->get();
|
456 |
+
$this->cache->set('data', $data);
|
457 |
+
}
|
458 |
+
|
459 |
+
return $data;
|
460 |
+
}
|
461 |
+
}
|
462 |
+
|
463 |
+
class LoggingEndpoint implements EndpointInterface {
|
464 |
+
private $decorated;
|
465 |
+
private $logger;
|
466 |
+
|
467 |
+
public function __construct(EndpointInterface $decorated, LoggerInterface $logger ) {
|
468 |
+
$this->decorated = $decorated;
|
469 |
+
$this->logger = logger$;
|
470 |
+
}
|
471 |
+
|
472 |
+
public function get() {
|
473 |
+
$this->logger->logRequest('get');
|
474 |
+
$data = $this->decorated->get();
|
475 |
+
|
476 |
+
return $data;
|
477 |
+
}
|
478 |
+
}
|
479 |
+
```
|
480 |
+
|
481 |
+
The container allows binding "chain of decorators" to an interface (or slug a la Pimple, or class) using the `bindDecorators` and `singletonDecorators`.
|
482 |
+
The two methods are the `bind` and `singleton` equivalents for decorators.
|
483 |
+
The two methods can be skipped on PHP 5.3+ code:
|
484 |
+
|
485 |
+
```php
|
486 |
+
$container = new tad_DI52_Container();
|
487 |
+
|
488 |
+
$container->bind('RepositoryInterface', 'PostRepository');
|
489 |
+
$container->bind('CacheInterface', 'ArrayCache');
|
490 |
+
$container->bind('LoggerInterface', 'FileLogger');
|
491 |
+
|
492 |
+
$container->bind('PostEndpoint', function($container){
|
493 |
+
$base = $container->make('BaseEndpoint');
|
494 |
+
$caching = new CachingEndpoint($base, $container->make('CacheInterface'));
|
495 |
+
$logging = new LoggingEndpoint($caching, $container->make('LoggerInterface'));
|
496 |
+
|
497 |
+
return $logging;
|
498 |
+
});
|
499 |
+
```
|
500 |
+
|
501 |
+
But becomes necessary on PHP 5.2 compatible code:
|
502 |
+
|
503 |
+
```php
|
504 |
+
$container = new tad_DI52_Container();
|
505 |
+
|
506 |
+
$container->bind('CacheInterface', 'ArrayCache');
|
507 |
+
$container->bind('LoggerInterface', 'FileLogger');
|
508 |
+
|
509 |
+
// decorate right to left, last is built first!
|
510 |
+
$container->bindDecorators('EndpointInterface', array('LoggingEndpoint', 'CachingEndpoint', 'BaseEndpoint'));
|
511 |
+
|
512 |
+
$postEndpoint = $container->make('EndpointInterface');
|
513 |
+
```
|
514 |
+
|
515 |
+
## Tagging
|
516 |
+
Tagging allows grouping similar implementations for the purpose of referencing them by group.
|
517 |
+
Grouping implementations makes sense when, as an example, the same method has to be called on each implementation:
|
518 |
+
|
519 |
+
```php
|
520 |
+
$container = new tad_DI52_Container();
|
521 |
+
|
522 |
+
$container->bind('UnsupportedEndpoint', function($container){
|
523 |
+
$template = '404';
|
524 |
+
$message = 'Nope';
|
525 |
+
$redirectAfter = 3;
|
526 |
+
$redirectTo = $container->make('HomeEndpoint');
|
527 |
+
|
528 |
+
return new UnsupportedEndpoint($template, $message, $redirectAfter, $redirectTo);
|
529 |
+
});
|
530 |
+
|
531 |
+
$container->tag(array('HomeEndpoint', 'PostEndpoint', 'UnsupportedEndpoint'), 'endpoints');
|
532 |
+
|
533 |
+
foreach($container->tagged('enpoints') as $endpoint) {
|
534 |
+
$endpoint->register();
|
535 |
+
}
|
536 |
+
```
|
537 |
+
|
538 |
+
The `tag` method supports any possibility offered by the container in terms of binding of objects, closures, decorator chains and after-build methods.
|
539 |
+
|
540 |
+
## The instance method
|
541 |
+
In the example above the `UnsupportedEndpoint` requires three primitive parameters and an endpoint to be built and the method used above relies on closures only available in PHP 5.3+.
|
542 |
+
To offer a degree of support the container offers the `instance` method that allows rewriting the code above to this:
|
543 |
+
|
544 |
+
```php
|
545 |
+
$container = new tad_DI52_Container();
|
546 |
+
|
547 |
+
$container->bind('UnsupportedEndpoint', $container->instance('404', 'Nope', 3, 'HomeEndpoint'));
|
548 |
+
|
549 |
+
$container->tag(array('HomeEndpoint', 'PostEndpoint', 'UnsupportedEndpoint'), 'enpoints');
|
550 |
+
|
551 |
+
foreach($container->tagged('enpoints') as $endpoint) {
|
552 |
+
$endpoint->register();
|
553 |
+
}
|
554 |
+
```
|
555 |
+
|
556 |
+
The instance methods does not offer the same amount of flexibility closures offer (and that's why closures were implemented) but mitigates the problem avoiding other work-arounds (singletons, factories or an eager instantiation) and granting a **lazy instantiation**.
|
557 |
+
|
558 |
+
## The callback method
|
559 |
+
Some applications require callbacks (or some form of callable) to be returned in specific pieces of code.
|
560 |
+
This is especially the case with WordPress and its [event-based architecture](https://codex.wordpress.org/Plugin_API/Filter_Reference "Plugin API/Filter Reference « WordPress Codex").
|
561 |
+
Using the container does not removes that possibility:
|
562 |
+
|
563 |
+
```php
|
564 |
+
$container = new tad_DI52_Container();
|
565 |
+
|
566 |
+
$container->bind('FilterInterface', 'ConcreteFilter');
|
567 |
+
|
568 |
+
add_filter('some_filter', array($container->make('FilterInterface'), 'filter'));
|
569 |
+
```
|
570 |
+
|
571 |
+
This code suffers, but, from an eager instantiation problem: `ConcreteFilter` is built for the purpose of binding it but might never be used.
|
572 |
+
The problem is easy to solve on PHP 5.3+:
|
573 |
+
|
574 |
+
|
575 |
+
```php
|
576 |
+
$container = new tad_DI52_Container();
|
577 |
+
|
578 |
+
$container->bind('FilterInterface', 'ConcreteFilter');
|
579 |
+
|
580 |
+
$filterFunction = function($dataToFilter) use($container){
|
581 |
+
$filter = $container->make('FilterInterface');
|
582 |
+
|
583 |
+
return $filter->filter($data);
|
584 |
+
};
|
585 |
+
|
586 |
+
add_filter('some_filter', $filterFunction);
|
587 |
+
```
|
588 |
+
|
589 |
+
But this is not an option on PHP 5.2 compatible code.
|
590 |
+
In that case the container offers the `callback` method to return a callable function that will **lazily build** the object, call the method on it passing the call arguments and return its return value:
|
591 |
+
|
592 |
+
```php
|
593 |
+
$container = new tad_DI52_Container();
|
594 |
+
|
595 |
+
$container->bind('FilterInterface', 'ConcreteFilter');
|
596 |
+
|
597 |
+
add_filter('some_filter', $container->callback('FilterInterface', 'filter'));
|
598 |
+
```
|
599 |
+
|
600 |
+
## Service providers
|
601 |
+
To avoid passing the container instance around (see [Service Locator pattern](https://en.wikipedia.org/wiki/Service_locator_pattern "Service locator pattern - Wikipedia")) or globalising it all the binding should happen in the same PHP file: this could lead, as the application grows, to a thousand lines monster.
|
602 |
+
To avoid that the container supports service providers: those are classes implmenting the `tad_DI52_ServiceProviderInterface` interface, or extend the ready to use `tad_DI52_ServiceProvider` class, that allow organizing the binding registrations into logical, self-contained and manageable units:
|
603 |
+
|
604 |
+
```php
|
605 |
+
// file ProviderOne.php
|
606 |
+
class ProviderOne extends tad_DI52_ServiceProvider {
|
607 |
+
public function register() {
|
608 |
+
$this->container->bind('InterfaceOne', 'ClassOne');
|
609 |
+
$this->container->bind('InterfaceTwo', 'ClassTwo');
|
610 |
+
$this->container->singleton('InterfaceThree', 'ClassThree');
|
611 |
+
}
|
612 |
+
}
|
613 |
+
|
614 |
+
// application bootstrap file
|
615 |
+
$container = new tad_DI52_Container();
|
616 |
+
|
617 |
+
$container->register('ProviderOne');
|
618 |
+
```
|
619 |
+
|
620 |
+
### Booting service providers
|
621 |
+
The container implements a `boot` method that will, in turn, call the `boot` method on any service provider that overloads it.
|
622 |
+
Some applications might define constants and environment variables at "boot" time (e.g. WordPress `plugins_loaded` action) that might make an immediate registration futile.
|
623 |
+
In that case service providers can overload the `boot` method:
|
624 |
+
|
625 |
+
|
626 |
+
```php
|
627 |
+
// file ProviderOne.php
|
628 |
+
class ProviderOne extends tad_DI52_ServiceProvider {
|
629 |
+
public function register() {
|
630 |
+
$this->container->bind('InterfaceOne', 'ClassOne');
|
631 |
+
$this->container->bind('InterfaceTwo', 'ClassTwo');
|
632 |
+
$this->container->singleton('InterfaceThree', 'ClassThree');
|
633 |
+
}
|
634 |
+
|
635 |
+
public function boot() {
|
636 |
+
if(defined('SOME_CONSTANT')) {
|
637 |
+
$this->container->bind('InterfaceFour', 'ClassFour');
|
638 |
+
} else {
|
639 |
+
$this->container->bind('InterfaceFour', 'AnotherClassFour');
|
640 |
+
}
|
641 |
+
}
|
642 |
+
}
|
643 |
+
|
644 |
+
// application bootstrap file
|
645 |
+
$container = new tad_DI52_Container();
|
646 |
+
|
647 |
+
$container->register('ProviderOne');
|
648 |
+
```
|
649 |
+
|
650 |
+
### Deferred service providers
|
651 |
+
Sometimes even just setting up the implementations might require such an up-front cost to make it undesireable unless it's needed.
|
652 |
+
This might happen with non autoloading code that will require a tangle of files to load (and side load) to grab a simple class instance.
|
653 |
+
To "defer" that cost service providers can overload the `deferred` property and the `provides` method:
|
654 |
+
|
655 |
+
```php
|
656 |
+
// file ProviderOne.php
|
657 |
+
class ProviderOne extends tad_DI52_ServiceProvider {
|
658 |
+
public $deferred = true;
|
659 |
+
|
660 |
+
public function provides() {
|
661 |
+
return array('LegacyClassOne', 'LegacyInterfaceTwo');
|
662 |
+
}
|
663 |
+
|
664 |
+
public function register() {
|
665 |
+
include_once('legacy-file-one.php')
|
666 |
+
include_once('legacy-file-two.php')
|
667 |
+
|
668 |
+
$db = new Db();
|
669 |
+
|
670 |
+
$details = $db->getDetails();
|
671 |
+
|
672 |
+
$this->container->singleton('LegacyClassOne', new LegacyClassOne($details));
|
673 |
+
$this->container->bind('LegacyInterfaceTwo', new LegacyClassTwo($details));
|
674 |
+
}
|
675 |
+
}
|
676 |
+
|
677 |
+
// application bootstrap file
|
678 |
+
$container = new tad_DI52_Container();
|
679 |
+
|
680 |
+
// the provider `register` method will not be called immediately...
|
681 |
+
$container->register('ProviderOne');
|
682 |
+
|
683 |
+
// ...it will be called here as it provides the binding of `LegacyClassOne`
|
684 |
+
$legacyOne = $container->make('LegacyClassOne');
|
685 |
+
|
686 |
+
// will not be called again here, done already
|
687 |
+
$legacyTwo = $container->make('LegacyInterfaceTwo');
|
688 |
+
```
|
vendor/lucatume/di52/_build/check_exports.sh
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
PWD=${1:-$(pwd)}
|
4 |
+
|
5 |
+
ignored_files=$(git status --ignored --porcelain \
|
6 |
+
| grep -E '^!!' \
|
7 |
+
| awk -F' ' '{ print $2 }' \
|
8 |
+
| sed -E 's#\/$$##g'); \
|
9 |
+
|
10 |
+
echo -e "\033[1mIgnored files (local and global .gitignore file)\033[0m"; \
|
11 |
+
echo -e "\033[1m================================================\033[0m"; \
|
12 |
+
echo "${ignored_files}"; \
|
13 |
+
|
14 |
+
excluded_files=$(echo "${ignored_files}" | tr '\n' ',' | sed -e 's/,[^,]*$//g'); \
|
15 |
+
ignore_pattern="(\.$|$(echo "${excluded_files}" | sed -e 's/,/|/g' ))"; \
|
16 |
+
vcs_files=$(ls -a -1 "${PWD}" | grep -Ev "${ignore_pattern}" | sort); \
|
17 |
+
|
18 |
+
echo ""; \
|
19 |
+
echo -e "\033[1mVCS files (these will be pushed to the repository)\033[0m"; \
|
20 |
+
echo -e "\033[1m==================================================\033[0m"; \
|
21 |
+
echo "${vcs_files}"; \
|
22 |
+
|
23 |
+
export_ignored_files=$(grep -E '\s+export-ignore' ${PWD}/.gitattributes | awk -F' ' '{ print $1 }' | sort); \
|
24 |
+
|
25 |
+
echo ""; \
|
26 |
+
echo -e "\033[1mExport ignored files (export-ignore)\033[0m"; \
|
27 |
+
echo -e "\033[1m====================================\033[0m"; \
|
28 |
+
echo "${export_ignored_files}"; \
|
29 |
+
|
30 |
+
exported_vcs_files=$(comm -23 <(echo "${vcs_files}") <(echo "${export_ignored_files}")); \
|
31 |
+
|
32 |
+
echo ""; \
|
33 |
+
echo -e "\033[1mThe following files will be exported\033[0m"; \
|
34 |
+
echo -e "\033[1m====================================\033[0m"; \
|
35 |
+
echo "${exported_vcs_files}"
|
vendor/lucatume/di52/_build/composer-hash.sh
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env sh
|
2 |
+
|
3 |
+
# Replaces the `extra._hash` string in the composer.json file.
|
4 |
+
|
5 |
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
6 |
+
COMPOSER_FILE="${SCRIPT_DIR}/../composer.json"
|
7 |
+
|
8 |
+
test -f "${COMPOSER_FILE}" || {
|
9 |
+
echo "composer.json file (${COMPOSER_FILE}) does not exist."
|
10 |
+
exit 1
|
11 |
+
}
|
12 |
+
|
13 |
+
ORIGINAL_HASH=$(cat "${COMPOSER_FILE}" | grep -e '"_hash"' | cut -d':' -f2 | cut -d'"' -f2)
|
14 |
+
NEW_HASH=$(date | md5sum | cut -d' ' -f1)
|
15 |
+
sed -i'.bak' -e "s/${ORIGINAL_HASH}/${NEW_HASH}/g" "${COMPOSER_FILE}"
|
vendor/lucatume/di52/_build/containers/php-52/Dockerfile
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
FROM tommylau/php-5.2
|
2 |
+
WORKDIR /project
|
3 |
+
CMD ["/project/vendor/bin/phpunit-php52"]
|
vendor/lucatume/di52/_build/dir_hash.sh
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
if [ "$#" -lt 1 ]; then
|
4 |
+
echo -e "\033[1mReturns a directory hash.\033[0m"
|
5 |
+
echo ""
|
6 |
+
echo -e "\033[32mUsage:\033[0m"
|
7 |
+
echo " dir_hash.sh <dir>"
|
8 |
+
echo ""
|
9 |
+
echo -e "\033[32mExamples:\033[0m"
|
10 |
+
echo ""
|
11 |
+
echo " Return the hash of the src directory"
|
12 |
+
echo -e " \033[36mdir_hash.sh src \033[0m"
|
13 |
+
exit 0
|
14 |
+
fi
|
15 |
+
|
16 |
+
echo "$(find "$1" -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum | cut -d' ' -f1)"
|
vendor/lucatume/di52/_build/release.php
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env php
|
2 |
+
<?php
|
3 |
+
/**
|
4 |
+
* Release a major, minor or patch update w/ release notes from the CHANGELOG.md file.
|
5 |
+
*
|
6 |
+
* Usage:
|
7 |
+
*
|
8 |
+
* _build/release.php patch
|
9 |
+
* _build/release.php minor
|
10 |
+
* _build/release.php major
|
11 |
+
*
|
12 |
+
* Release w/o prompt confirmation:
|
13 |
+
*
|
14 |
+
* _build/release.php -q patch
|
15 |
+
* _build/release.php --no-interactive minor
|
16 |
+
*
|
17 |
+
* Release w/o checking for dirty or unpushed changes:
|
18 |
+
*
|
19 |
+
* _build/release.php --no-dirty-check minor
|
20 |
+
* _build/release.php --no-unpushed-check patch
|
21 |
+
*
|
22 |
+
* Run a dry-run test:
|
23 |
+
*
|
24 |
+
* _build/release.php --dry-run patch
|
25 |
+
*
|
26 |
+
* Update the changelog:
|
27 |
+
*
|
28 |
+
* _build/release.php --changelog-update patch
|
29 |
+
*/
|
30 |
+
|
31 |
+
namespace lucatume\tools;
|
32 |
+
|
33 |
+
$root = dirname(__DIR__);
|
34 |
+
|
35 |
+
require_once $root . '/vendor/autoload.php';
|
36 |
+
|
37 |
+
$changelogFile = $root . '/CHANGELOG.md';
|
38 |
+
|
39 |
+
if ( ! file_exists( $changelogFile ) ) {
|
40 |
+
echo "\e[31mChangelog file (CHANGELOG.md, changelog.md) does not exist.\e[0m\n";
|
41 |
+
exit( 1 );
|
42 |
+
}
|
43 |
+
|
44 |
+
function args()
|
45 |
+
{
|
46 |
+
global $argv;
|
47 |
+
|
48 |
+
$options = getopt('q', ['not-interactive', 'no-diff-check', 'no-unpushed-check', 'dry-run', 'no-changelog-update'],
|
49 |
+
$optind);
|
50 |
+
|
51 |
+
$map = [
|
52 |
+
'releaseType' => isset($argv[$optind]) ? $argv[$optind] : 'patch',
|
53 |
+
'notInteractive' => isset($options['q']) || isset($options['not-interactive']),
|
54 |
+
'noChangelogUpdate' => isset($options['no-changelog-update']),
|
55 |
+
'checkDiff' => empty($options['no-diff-check']),
|
56 |
+
'checkUnpushed' => empty($options['no-unpushed-check']),
|
57 |
+
'dryRun' => isset($options['dry-run']),
|
58 |
+
];
|
59 |
+
|
60 |
+
return static function ($key, $default = null) use ($map) {
|
61 |
+
return isset($map[$key]) ? $map[$key] : $default;
|
62 |
+
};
|
63 |
+
}
|
64 |
+
|
65 |
+
$args = args();
|
66 |
+
|
67 |
+
if (!in_array($args('releaseType'), ['major', 'minor', 'patch'], true)) {
|
68 |
+
echo "\e[31mThe release type has to be one of major, minor or patch.\e[0m\n";
|
69 |
+
exit(1);
|
70 |
+
}
|
71 |
+
|
72 |
+
$dryRun = $args('dryRun', false);
|
73 |
+
|
74 |
+
if (!$dryRun) {
|
75 |
+
$currentGitBranch = trim(shell_exec('git rev-parse --abbrev-ref HEAD'));
|
76 |
+
if ($currentGitBranch !== 'master') {
|
77 |
+
echo "\e[31mCan release only from master branch.\e[0m\n";
|
78 |
+
exit(1);
|
79 |
+
}
|
80 |
+
echo "Current git branch: \e[32m" . $currentGitBranch . "\e[0m\n";
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Parses the changelog to get the latest notes and the latest, released, version.
|
85 |
+
*
|
86 |
+
* @param string $changelog The absolute path to the changelog file.
|
87 |
+
*
|
88 |
+
* @return array<string,mixed> The map of parsed values.
|
89 |
+
*/
|
90 |
+
function changelog($changelog)
|
91 |
+
{
|
92 |
+
$notes = '';
|
93 |
+
$latestVersion = '';
|
94 |
+
|
95 |
+
$f = fopen($changelog, 'rb');
|
96 |
+
$read = false;
|
97 |
+
while ($line = fgets($f)) {
|
98 |
+
if (preg_match('/^## \\[unreleased]/', $line)) {
|
99 |
+
$read = true;
|
100 |
+
continue;
|
101 |
+
}
|
102 |
+
|
103 |
+
if (preg_match('/^## \\[(?<version>\\d+\\.\\d\.\\d+)]/', $line, $m)) {
|
104 |
+
$latestVersion = $m['version'];
|
105 |
+
break;
|
106 |
+
}
|
107 |
+
|
108 |
+
if ($read === true) {
|
109 |
+
$notes .= $line;
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
fclose($f);
|
114 |
+
|
115 |
+
return [ 'notes' => trim( $notes ), 'latestVersion' => $latestVersion ];
|
116 |
+
}
|
117 |
+
|
118 |
+
function updateChangelog($changelogFile, $version, callable $args, $date = null)
|
119 |
+
{
|
120 |
+
$date = $date === null ? date('Y-m-d') : $date;
|
121 |
+
$changelogVersionLine = sprintf("\n\n## [%s] %s;", $version, $date);
|
122 |
+
$changelogFileName = basename($changelogFile);
|
123 |
+
$currentContents = file_get_contents($changelogFile);
|
124 |
+
$entryLine = '## [unreleased] Unreleased';
|
125 |
+
if ( strpos( $currentContents, $entryLine ) === false ) {
|
126 |
+
$message = 'Unreleased entry line not found; does the changelog file contain an entry like "' . $entryLine . '"?';
|
127 |
+
echo "\e[31m{$message}\e[0m\n";
|
128 |
+
exit( 1 );
|
129 |
+
}
|
130 |
+
$changelogContents = str_replace($entryLine, $entryLine . $changelogVersionLine, $currentContents);
|
131 |
+
$changelogContents = preg_replace_callback(
|
132 |
+
'/^\\[unreleased]:\\s+(?<repo>.*)(?<previous_version>\\d\\.\\d\\.\\d)\\.{3}HEAD$/um',
|
133 |
+
static function (array $matches) use ($version) {
|
134 |
+
return sprintf('[%1$s]: %2$s%3$s...%1$s' . PHP_EOL . '[unreleased]: %2$s%1$s...HEAD'
|
135 |
+
, $version, $matches['repo'], $matches['previous_version']);
|
136 |
+
},
|
137 |
+
$changelogContents
|
138 |
+
);
|
139 |
+
echo "Changelog updates:\n\n---\n";
|
140 |
+
echo substr($changelogContents, 0, 1024);
|
141 |
+
echo "\n\n[...]\n\n";
|
142 |
+
echo substr($changelogContents, strlen($changelogContents) - 512);
|
143 |
+
echo "---\n\n";
|
144 |
+
if (!$args('dryRun', false)
|
145 |
+
&& (
|
146 |
+
$args('notInteractive', false)
|
147 |
+
|| confirm("Would you like to proceed?")
|
148 |
+
)
|
149 |
+
) {
|
150 |
+
file_put_contents($changelogFile, $changelogContents);
|
151 |
+
passthru('git commit -m "doc(' . $changelogFileName . '.md) update to version ' . $version . '" -- ' . $changelogFile);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
$changelog = changelog($changelogFile);
|
156 |
+
|
157 |
+
$releaseType = $args('releaseType', 'patch');
|
158 |
+
switch ($releaseType) {
|
159 |
+
case 'major':
|
160 |
+
$releaseVersion = preg_replace_callback('/(?<target>\\d+)\\.\\d\.\\d+/', static function ($m) {
|
161 |
+
return (++$m['target']) . '.0.0';
|
162 |
+
}, $changelog['latestVersion']);
|
163 |
+
break;
|
164 |
+
case 'minor':
|
165 |
+
$releaseVersion = preg_replace_callback('/(?<major>\\d+)\\.(?<target>\\d)\.\\d+/', static function ($m) {
|
166 |
+
return $m['major'] . '.' . (++$m['target']) . '.0';
|
167 |
+
}, $changelog['latestVersion']);
|
168 |
+
break;
|
169 |
+
case 'patch':
|
170 |
+
$releaseVersion = preg_replace_callback('/(?<major>\\d+)\\.(?<minor>\\d)\.(?<target>\\d+)/',
|
171 |
+
static function ($m) {
|
172 |
+
return $m['major'] . '.' . ($m['minor']) . '.' . (++$m['target']);
|
173 |
+
}, $changelog['latestVersion']);
|
174 |
+
break;
|
175 |
+
}
|
176 |
+
|
177 |
+
$releaseNotesHeader = "{$releaseVersion}\n\n";
|
178 |
+
$fullReleaseNotes = $releaseNotesHeader . $changelog['notes'];
|
179 |
+
|
180 |
+
echo "Latest release: \e[32m" . $changelog['latestVersion'] . "\e[0m\n";
|
181 |
+
echo "Release type: \e[32m" . $releaseType . "\e[0m\n";
|
182 |
+
echo "Next release: \e[32m" . $releaseVersion . "\e[0m\n";
|
183 |
+
echo "Release notes:\n\n---\n" . $fullReleaseNotes . "\n---\n";
|
184 |
+
echo "\n\n";
|
185 |
+
|
186 |
+
if (!$args('noChangelogUpdate', false)) {
|
187 |
+
updateChangelog($changelogFile, $releaseVersion, $args);
|
188 |
+
}
|
189 |
+
|
190 |
+
if ($args('checkDiff', true) && !$dryRun) {
|
191 |
+
$gitDirty = trim(shell_exec('git diff HEAD'));
|
192 |
+
if (!empty($gitDirty)) {
|
193 |
+
echo "\e[31mYou have uncommited work.\e[0m\n";
|
194 |
+
exit(1);
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
function confirm($question)
|
199 |
+
{
|
200 |
+
$question = "\n{$question} ";
|
201 |
+
return preg_match('/y/i', readline($question));
|
202 |
+
}
|
203 |
+
|
204 |
+
if ($args('checkUnpushed', true) && !$dryRun) {
|
205 |
+
$gitDiff = trim(shell_exec('git log origin/master..HEAD'));
|
206 |
+
if (!empty($gitDiff)) {
|
207 |
+
echo "\e[31mYou have unpushed changes.\e[0m\n";
|
208 |
+
if (confirm('Would you like to push them now?')) {
|
209 |
+
passthru('git push');
|
210 |
+
} else {
|
211 |
+
exit(1);
|
212 |
+
}
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
file_put_contents($root . '/.rel', $fullReleaseNotes);
|
217 |
+
|
218 |
+
$releaseCommand = 'hub release create -F .rel ' . $releaseVersion;
|
219 |
+
|
220 |
+
echo "Releasing with command: \e[32m" . $releaseCommand . "\e[0m\n\n";
|
221 |
+
|
222 |
+
if ($dryRun || $args('notInteractive', false) || confirm('Do you want to proceed?')) {
|
223 |
+
if (!$dryRun) {
|
224 |
+
passthru($releaseCommand);
|
225 |
+
}
|
226 |
+
} else {
|
227 |
+
echo "Canceling\n";
|
228 |
+
}
|
229 |
+
|
230 |
+
unlink($root . '/.rel');
|
vendor/lucatume/di52/autoload.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if (!function_exists('di52_findFile')) {
|
3 |
+
function di52_findFile($class)
|
4 |
+
{
|
5 |
+
if (0 !== strpos($class, 'tad_DI52_')) {
|
6 |
+
return false;
|
7 |
+
}
|
8 |
+
|
9 |
+
return dirname(__FILE__) . '/src/' . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
|
10 |
+
}
|
11 |
+
}
|
12 |
+
|
13 |
+
if (!function_exists('di52_autoload')) {
|
14 |
+
function di52_autoload($class)
|
15 |
+
{
|
16 |
+
$file = di52_findFile($class);
|
17 |
+
if ($file) {
|
18 |
+
include $file;
|
19 |
+
|
20 |
+
return true;
|
21 |
+
}
|
22 |
+
|
23 |
+
return false;
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
spl_autoload_register('di52_autoload');
|
vendor/lucatume/di52/composer-5-3-plus.json
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "lucatume/di52",
|
3 |
+
"description": "A PHP 5.2 compatible dependency injection container.",
|
4 |
+
"license": "GPL-3.0",
|
5 |
+
"authors": [
|
6 |
+
{
|
7 |
+
"name": "Luca Tumedei",
|
8 |
+
"email": "luca@theaveragedev.com"
|
9 |
+
}
|
10 |
+
],
|
11 |
+
"autoload": {
|
12 |
+
"psr-0": {
|
13 |
+
"tad_DI52_": [
|
14 |
+
"src/"
|
15 |
+
]
|
16 |
+
}
|
17 |
+
},
|
18 |
+
"minimum-stability": "dev",
|
19 |
+
"require": {
|
20 |
+
"php": ">=5.3"
|
21 |
+
},
|
22 |
+
"require-dev": {
|
23 |
+
"phpunit/phpunit-php52": "dev-3.6.12-php52",
|
24 |
+
"phpunit/phpunit-mock-objects-php52": "dev-1.1.0-php52"
|
25 |
+
},
|
26 |
+
"repositories": [
|
27 |
+
{
|
28 |
+
"type": "git",
|
29 |
+
"url": "https://github.com/garex/phpunit"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"type": "git",
|
33 |
+
"url": "https://github.com/garex/phpunit-mock-objects"
|
34 |
+
}
|
35 |
+
]
|
36 |
+
}
|
vendor/lucatume/di52/composer.json
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "lucatume/di52",
|
3 |
+
"description": "A PHP 5.2 compatible dependency injection container.",
|
4 |
+
"license": "GPL-3.0",
|
5 |
+
"authors": [
|
6 |
+
{
|
7 |
+
"name": "Luca Tumedei",
|
8 |
+
"email": "luca@theaveragedev.com"
|
9 |
+
}
|
10 |
+
],
|
11 |
+
"autoload": {
|
12 |
+
"psr-0": {
|
13 |
+
"tad_DI52_": [
|
14 |
+
"src/"
|
15 |
+
]
|
16 |
+
}
|
17 |
+
},
|
18 |
+
"minimum-stability": "dev",
|
19 |
+
"config": {
|
20 |
+
"platform": {
|
21 |
+
"php": "5.2.17"
|
22 |
+
}
|
23 |
+
},
|
24 |
+
"require": {
|
25 |
+
"php": ">=5.2",
|
26 |
+
"xrstf/composer-php52": "1.*"
|
27 |
+
},
|
28 |
+
"require-dev": {
|
29 |
+
"phpunit/phpunit-php52": "dev-3.6.12-php52",
|
30 |
+
"phpunit/phpunit-mock-objects-php52": "dev-1.1.0-php52"
|
31 |
+
},
|
32 |
+
"repositories": [
|
33 |
+
{
|
34 |
+
"type": "git",
|
35 |
+
"url": "https://github.com/garex/phpunit"
|
36 |
+
},
|
37 |
+
{
|
38 |
+
"type": "git",
|
39 |
+
"url": "https://github.com/garex/phpunit-mock-objects"
|
40 |
+
}
|
41 |
+
],
|
42 |
+
"scripts": {
|
43 |
+
"post-install-cmd": [
|
44 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
45 |
+
],
|
46 |
+
"post-update-cmd": [
|
47 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
48 |
+
],
|
49 |
+
"post-autoload-dump": [
|
50 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
51 |
+
]
|
52 |
+
}
|
53 |
+
}
|
vendor/lucatume/di52/composer.lock
ADDED
@@ -0,0 +1,535 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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": "21d2d1cfe07d9e4e835907431fc9c87e",
|
8 |
+
"packages": [
|
9 |
+
{
|
10 |
+
"name": "xrstf/composer-php52",
|
11 |
+
"version": "v1.0.20",
|
12 |
+
"source": {
|
13 |
+
"type": "git",
|
14 |
+
"url": "https://github.com/composer-php52/composer-php52.git",
|
15 |
+
"reference": "bd41459d5e27df8d33057842b32377c39e97a5a8"
|
16 |
+
},
|
17 |
+
"dist": {
|
18 |
+
"type": "zip",
|
19 |
+
"url": "https://api.github.com/repos/composer-php52/composer-php52/zipball/bd41459d5e27df8d33057842b32377c39e97a5a8",
|
20 |
+
"reference": "bd41459d5e27df8d33057842b32377c39e97a5a8",
|
21 |
+
"shasum": ""
|
22 |
+
},
|
23 |
+
"type": "library",
|
24 |
+
"extra": {
|
25 |
+
"branch-alias": {
|
26 |
+
"dev-default": "1.x-dev"
|
27 |
+
}
|
28 |
+
},
|
29 |
+
"autoload": {
|
30 |
+
"psr-0": {
|
31 |
+
"xrstf\\Composer52": "lib/"
|
32 |
+
}
|
33 |
+
},
|
34 |
+
"notification-url": "https://packagist.org/downloads/",
|
35 |
+
"license": [
|
36 |
+
"MIT"
|
37 |
+
],
|
38 |
+
"time": "2016-04-16T21:52:24+00:00"
|
39 |
+
}
|
40 |
+
],
|
41 |
+
"packages-dev": [
|
42 |
+
{
|
43 |
+
"name": "phpunit/php-code-coverage",
|
44 |
+
"version": "1.2.0",
|
45 |
+
"source": {
|
46 |
+
"type": "git",
|
47 |
+
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
48 |
+
"reference": "21d0f05b8127057159eec4be79f8f8a92bc90957"
|
49 |
+
},
|
50 |
+
"dist": {
|
51 |
+
"type": "zip",
|
52 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/21d0f05b8127057159eec4be79f8f8a92bc90957",
|
53 |
+
"reference": "21d0f05b8127057159eec4be79f8f8a92bc90957",
|
54 |
+
"shasum": ""
|
55 |
+
},
|
56 |
+
"require": {
|
57 |
+
"php": ">=5.3.3",
|
58 |
+
"phpunit/php-file-iterator": ">=1.3.0@stable",
|
59 |
+
"phpunit/php-text-template": ">=1.1.1@stable",
|
60 |
+
"phpunit/php-token-stream": ">=1.1.3@stable"
|
61 |
+
},
|
62 |
+
"suggest": {
|
63 |
+
"ext-dom": "*",
|
64 |
+
"ext-reflection": "*",
|
65 |
+
"ext-spl": "*",
|
66 |
+
"ext-xdebug": ">=2.0.5"
|
67 |
+
},
|
68 |
+
"type": "library",
|
69 |
+
"autoload": {
|
70 |
+
"files": [
|
71 |
+
"PHP/CodeCoverage/Autoload.php"
|
72 |
+
]
|
73 |
+
},
|
74 |
+
"notification-url": "https://packagist.org/downloads/",
|
75 |
+
"include-path": [
|
76 |
+
""
|
77 |
+
],
|
78 |
+
"license": [
|
79 |
+
"BSD-3-Clause"
|
80 |
+
],
|
81 |
+
"authors": [
|
82 |
+
{
|
83 |
+
"name": "Sebastian Bergmann",
|
84 |
+
"email": "sb@sebastian-bergmann.de",
|
85 |
+
"role": "lead"
|
86 |
+
}
|
87 |
+
],
|
88 |
+
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
|
89 |
+
"homepage": "http://www.phpunit.de/",
|
90 |
+
"keywords": [
|
91 |
+
"coverage",
|
92 |
+
"testing",
|
93 |
+
"xunit"
|
94 |
+
],
|
95 |
+
"time": "2012-09-19T00:00:00+00:00"
|
96 |
+
},
|
97 |
+
{
|
98 |
+
"name": "phpunit/php-file-iterator",
|
99 |
+
"version": "1.3.2",
|
100 |
+
"source": {
|
101 |
+
"type": "git",
|
102 |
+
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
103 |
+
"reference": "46b0610951db3a918ee7842bc0d471e72c1d0d46"
|
104 |
+
},
|
105 |
+
"dist": {
|
106 |
+
"type": "zip",
|
107 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/46b0610951db3a918ee7842bc0d471e72c1d0d46",
|
108 |
+
"reference": "46b0610951db3a918ee7842bc0d471e72c1d0d46",
|
109 |
+
"shasum": ""
|
110 |
+
},
|
111 |
+
"require": {
|
112 |
+
"php": ">=5.2.7"
|
113 |
+
},
|
114 |
+
"type": "library",
|
115 |
+
"autoload": {
|
116 |
+
"files": [
|
117 |
+
"File/Iterator/Autoload.php"
|
118 |
+
]
|
119 |
+
},
|
120 |
+
"notification-url": "https://packagist.org/downloads/",
|
121 |
+
"include-path": [
|
122 |
+
""
|
123 |
+
],
|
124 |
+
"license": [
|
125 |
+
"BSD-3-Clause"
|
126 |
+
],
|
127 |
+
"authors": [
|
128 |
+
{
|
129 |
+
"name": "Sebastian Bergmann",
|
130 |
+
"email": "sb@sebastian-bergmann.de",
|
131 |
+
"role": "lead"
|
132 |
+
}
|
133 |
+
],
|
134 |
+
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
|
135 |
+
"homepage": "http://www.phpunit.de/",
|
136 |
+
"keywords": [
|
137 |
+
"filesystem",
|
138 |
+
"iterator"
|
139 |
+
],
|
140 |
+
"time": "2012-09-22T00:00:00+00:00"
|
141 |
+
},
|
142 |
+
{
|
143 |
+
"name": "phpunit/php-text-template",
|
144 |
+
"version": "1.1.2",
|
145 |
+
"source": {
|
146 |
+
"type": "git",
|
147 |
+
"url": "https://github.com/sebastianbergmann/php-text-template.git",
|
148 |
+
"reference": "1da672430d58dcbb21139a018febe038d8500fd8"
|
149 |
+
},
|
150 |
+
"dist": {
|
151 |
+
"type": "zip",
|
152 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/1da672430d58dcbb21139a018febe038d8500fd8",
|
153 |
+
"reference": "1da672430d58dcbb21139a018febe038d8500fd8",
|
154 |
+
"shasum": ""
|
155 |
+
},
|
156 |
+
"require": {
|
157 |
+
"php": ">=5.2.7"
|
158 |
+
},
|
159 |
+
"type": "library",
|
160 |
+
"autoload": {
|
161 |
+
"files": [
|
162 |
+
"Text/Template/Autoload.php"
|
163 |
+
]
|
164 |
+
},
|
165 |
+
"notification-url": "https://packagist.org/downloads/",
|
166 |
+
"include-path": [
|
167 |
+
""
|
168 |
+
],
|
169 |
+
"license": [
|
170 |
+
"BSD-3-Clause"
|
171 |
+
],
|
172 |
+
"authors": [
|
173 |
+
{
|
174 |
+
"name": "Sebastian Bergmann",
|
175 |
+
"email": "sb@sebastian-bergmann.de",
|
176 |
+
"role": "lead"
|
177 |
+
}
|
178 |
+
],
|
179 |
+
"description": "Simple template engine.",
|
180 |
+
"homepage": "http://www.phpunit.de/",
|
181 |
+
"keywords": [
|
182 |
+
"template"
|
183 |
+
],
|
184 |
+
"time": "2012-09-23T00:00:00+00:00"
|
185 |
+
},
|
186 |
+
{
|
187 |
+
"name": "phpunit/php-timer",
|
188 |
+
"version": "1.0.3",
|
189 |
+
"source": {
|
190 |
+
"type": "git",
|
191 |
+
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
192 |
+
"reference": "5175e9bb35fc9cc430973ed83a3d62531c3c8698"
|
193 |
+
},
|
194 |
+
"dist": {
|
195 |
+
"type": "zip",
|
196 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5175e9bb35fc9cc430973ed83a3d62531c3c8698",
|
197 |
+
"reference": "5175e9bb35fc9cc430973ed83a3d62531c3c8698",
|
198 |
+
"shasum": ""
|
199 |
+
},
|
200 |
+
"require": {
|
201 |
+
"php": ">=5.2.7"
|
202 |
+
},
|
203 |
+
"type": "library",
|
204 |
+
"autoload": {
|
205 |
+
"files": [
|
206 |
+
"PHP/Timer/Autoload.php"
|
207 |
+
]
|
208 |
+
},
|
209 |
+
"notification-url": "https://packagist.org/downloads/",
|
210 |
+
"include-path": [
|
211 |
+
""
|
212 |
+
],
|
213 |
+
"license": [
|
214 |
+
"BSD-3-Clause"
|
215 |
+
],
|
216 |
+
"authors": [
|
217 |
+
{
|
218 |
+
"name": "Sebastian Bergmann",
|
219 |
+
"email": "sb@sebastian-bergmann.de",
|
220 |
+
"role": "lead"
|
221 |
+
}
|
222 |
+
],
|
223 |
+
"description": "Utility class for timing",
|
224 |
+
"homepage": "http://www.phpunit.de/",
|
225 |
+
"keywords": [
|
226 |
+
"timer"
|
227 |
+
],
|
228 |
+
"time": "2012-09-23T00:00:00+00:00"
|
229 |
+
},
|
230 |
+
{
|
231 |
+
"name": "phpunit/php-token-stream",
|
232 |
+
"version": "1.1.4",
|
233 |
+
"source": {
|
234 |
+
"type": "git",
|
235 |
+
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
236 |
+
"reference": "dd11f1b0c071dc46fe711a7dd331db1b2179b9be"
|
237 |
+
},
|
238 |
+
"dist": {
|
239 |
+
"type": "zip",
|
240 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/dd11f1b0c071dc46fe711a7dd331db1b2179b9be",
|
241 |
+
"reference": "dd11f1b0c071dc46fe711a7dd331db1b2179b9be",
|
242 |
+
"shasum": ""
|
243 |
+
},
|
244 |
+
"require": {
|
245 |
+
"ext-tokenizer": "*",
|
246 |
+
"php": ">=5.2.7"
|
247 |
+
},
|
248 |
+
"type": "library",
|
249 |
+
"autoload": {
|
250 |
+
"files": [
|
251 |
+
"PHP/Token/Stream/Autoload.php"
|
252 |
+
]
|
253 |
+
},
|
254 |
+
"notification-url": "https://packagist.org/downloads/",
|
255 |
+
"include-path": [
|
256 |
+
""
|
257 |
+
],
|
258 |
+
"license": [
|
259 |
+
"BSD-3-Clause"
|
260 |
+
],
|
261 |
+
"authors": [
|
262 |
+
{
|
263 |
+
"name": "Sebastian Bergmann",
|
264 |
+
"email": "sb@sebastian-bergmann.de",
|
265 |
+
"role": "lead"
|
266 |
+
}
|
267 |
+
],
|
268 |
+
"description": "Wrapper around PHP's tokenizer extension.",
|
269 |
+
"homepage": "http://www.phpunit.de/",
|
270 |
+
"keywords": [
|
271 |
+
"tokenizer"
|
272 |
+
],
|
273 |
+
"time": "2012-09-23T00:00:00+00:00"
|
274 |
+
},
|
275 |
+
{
|
276 |
+
"name": "phpunit/phpunit-mock-objects-php52",
|
277 |
+
"version": "dev-1.1.0-php52",
|
278 |
+
"source": {
|
279 |
+
"type": "git",
|
280 |
+
"url": "https://github.com/garex/phpunit-mock-objects",
|
281 |
+
"reference": "625622b0678d53aa47c6dc7e232e0171e2623d75"
|
282 |
+
},
|
283 |
+
"require": {
|
284 |
+
"ext-reflection": "*",
|
285 |
+
"ext-spl": "*",
|
286 |
+
"php": ">=5.2.6",
|
287 |
+
"phpunit/php-text-template": ">=1.1.1@stable"
|
288 |
+
},
|
289 |
+
"type": "library",
|
290 |
+
"autoload": {
|
291 |
+
"classmap": [
|
292 |
+
"PHPUnit/"
|
293 |
+
]
|
294 |
+
},
|
295 |
+
"include-path": [
|
296 |
+
""
|
297 |
+
],
|
298 |
+
"time": "2014-10-02T18:21:59+00:00"
|
299 |
+
},
|
300 |
+
{
|
301 |
+
"name": "phpunit/phpunit-php52",
|
302 |
+
"version": "dev-3.6.12-php52",
|
303 |
+
"source": {
|
304 |
+
"type": "git",
|
305 |
+
"url": "https://github.com/garex/phpunit",
|
306 |
+
"reference": "96cd6cf307d82a4458f0c0bf8fb695d21b1a6072"
|
307 |
+
},
|
308 |
+
"require": {
|
309 |
+
"ext-dom": "*",
|
310 |
+
"ext-pcre": "*",
|
311 |
+
"ext-reflection": "*",
|
312 |
+
"ext-spl": "*",
|
313 |
+
"php": ">=5.2.7",
|
314 |
+
"phpunit/php-code-coverage": "=1.2.0",
|
315 |
+
"phpunit/php-file-iterator": "=1.3.2",
|
316 |
+
"phpunit/php-text-template": "=1.1.2",
|
317 |
+
"phpunit/php-timer": "=1.0.3",
|
318 |
+
"phpunit/php-token-stream": "=1.1.4",
|
319 |
+
"symfony/yaml": ">=2.1.0@stable",
|
320 |
+
"xrstf/composer-php52": "1.*"
|
321 |
+
},
|
322 |
+
"bin": [
|
323 |
+
"composer/bin/phpunit-php52"
|
324 |
+
],
|
325 |
+
"type": "library",
|
326 |
+
"autoload": {
|
327 |
+
"files": [
|
328 |
+
"PHPUnit/Autoload.php"
|
329 |
+
]
|
330 |
+
},
|
331 |
+
"include-path": [
|
332 |
+
"",
|
333 |
+
"../../symfony/yaml/"
|
334 |
+
],
|
335 |
+
"scripts": {
|
336 |
+
"post-install-cmd": [
|
337 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
338 |
+
],
|
339 |
+
"post-update-cmd": [
|
340 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
341 |
+
],
|
342 |
+
"post-autoload-dump": [
|
343 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
344 |
+
]
|
345 |
+
},
|
346 |
+
"time": "2019-06-23T16:06:23+00:00"
|
347 |
+
},
|
348 |
+
{
|
349 |
+
"name": "symfony/deprecation-contracts",
|
350 |
+
"version": "dev-main",
|
351 |
+
"source": {
|
352 |
+
"type": "git",
|
353 |
+
"url": "https://github.com/symfony/deprecation-contracts.git",
|
354 |
+
"reference": "be5a36670fd7ccb6f6e03d9c9bd7345e2a9a8515"
|
355 |
+
},
|
356 |
+
"dist": {
|
357 |
+
"type": "zip",
|
358 |
+
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/be5a36670fd7ccb6f6e03d9c9bd7345e2a9a8515",
|
359 |
+
"reference": "be5a36670fd7ccb6f6e03d9c9bd7345e2a9a8515",
|
360 |
+
"shasum": ""
|
361 |
+
},
|
362 |
+
"require": {
|
363 |
+
"php": ">=7.1"
|
364 |
+
},
|
365 |
+
"type": "library",
|
366 |
+
"extra": {
|
367 |
+
"branch-version": "2.3",
|
368 |
+
"branch-alias": {
|
369 |
+
"dev-main": "2.3-dev"
|
370 |
+
},
|
371 |
+
"thanks": {
|
372 |
+
"name": "symfony/contracts",
|
373 |
+
"url": "https://github.com/symfony/contracts"
|
374 |
+
}
|
375 |
+
},
|
376 |
+
"autoload": {
|
377 |
+
"files": [
|
378 |
+
"function.php"
|
379 |
+
]
|
380 |
+
},
|
381 |
+
"notification-url": "https://packagist.org/downloads/",
|
382 |
+
"license": [
|
383 |
+
"MIT"
|
384 |
+
],
|
385 |
+
"authors": [
|
386 |
+
{
|
387 |
+
"name": "Nicolas Grekas",
|
388 |
+
"email": "p@tchwork.com"
|
389 |
+
},
|
390 |
+
{
|
391 |
+
"name": "Symfony Community",
|
392 |
+
"homepage": "https://symfony.com/contributors"
|
393 |
+
}
|
394 |
+
],
|
395 |
+
"description": "A generic function and convention to trigger deprecation notices",
|
396 |
+
"homepage": "https://symfony.com",
|
397 |
+
"time": "2020-10-14T17:08:19+00:00"
|
398 |
+
},
|
399 |
+
{
|
400 |
+
"name": "symfony/polyfill-ctype",
|
401 |
+
"version": "dev-main",
|
402 |
+
"source": {
|
403 |
+
"type": "git",
|
404 |
+
"url": "https://github.com/symfony/polyfill-ctype.git",
|
405 |
+
"reference": "325e20642232b66e3f140a76f795b58b50a08787"
|
406 |
+
},
|
407 |
+
"dist": {
|
408 |
+
"type": "zip",
|
409 |
+
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/325e20642232b66e3f140a76f795b58b50a08787",
|
410 |
+
"reference": "325e20642232b66e3f140a76f795b58b50a08787",
|
411 |
+
"shasum": ""
|
412 |
+
},
|
413 |
+
"require": {
|
414 |
+
"php": ">=5.3.3"
|
415 |
+
},
|
416 |
+
"suggest": {
|
417 |
+
"ext-ctype": "For best performance"
|
418 |
+
},
|
419 |
+
"type": "library",
|
420 |
+
"extra": {
|
421 |
+
"branch-alias": {
|
422 |
+
"dev-main": "1.19-dev"
|
423 |
+
},
|
424 |
+
"thanks": {
|
425 |
+
"name": "symfony/polyfill",
|
426 |
+
"url": "https://github.com/symfony/polyfill"
|
427 |
+
}
|
428 |
+
},
|
429 |
+
"autoload": {
|
430 |
+
"psr-4": {
|
431 |
+
"Symfony\\Polyfill\\Ctype\\": ""
|
432 |
+
},
|
433 |
+
"files": [
|
434 |
+
"bootstrap.php"
|
435 |
+
]
|
436 |
+
},
|
437 |
+
"notification-url": "https://packagist.org/downloads/",
|
438 |
+
"license": [
|
439 |
+
"MIT"
|
440 |
+
],
|
441 |
+
"authors": [
|
442 |
+
{
|
443 |
+
"name": "Gert de Pagter",
|
444 |
+
"email": "BackEndTea@gmail.com"
|
445 |
+
},
|
446 |
+
{
|
447 |
+
"name": "Symfony Community",
|
448 |
+
"homepage": "https://symfony.com/contributors"
|
449 |
+
}
|
450 |
+
],
|
451 |
+
"description": "Symfony polyfill for ctype functions",
|
452 |
+
"homepage": "https://symfony.com",
|
453 |
+
"keywords": [
|
454 |
+
"compatibility",
|
455 |
+
"ctype",
|
456 |
+
"polyfill",
|
457 |
+
"portable"
|
458 |
+
],
|
459 |
+
"time": "2020-10-21T09:57:48+00:00"
|
460 |
+
},
|
461 |
+
{
|
462 |
+
"name": "symfony/yaml",
|
463 |
+
"version": "5.x-dev",
|
464 |
+
"source": {
|
465 |
+
"type": "git",
|
466 |
+
"url": "https://github.com/symfony/yaml.git",
|
467 |
+
"reference": "28ab1c87ffd653dc77e84581fed890c65dcafc19"
|
468 |
+
},
|
469 |
+
"dist": {
|
470 |
+
"type": "zip",
|
471 |
+
"url": "https://api.github.com/repos/symfony/yaml/zipball/28ab1c87ffd653dc77e84581fed890c65dcafc19",
|
472 |
+
"reference": "28ab1c87ffd653dc77e84581fed890c65dcafc19",
|
473 |
+
"shasum": ""
|
474 |
+
},
|
475 |
+
"require": {
|
476 |
+
"php": ">=7.2.5",
|
477 |
+
"symfony/deprecation-contracts": "^2.1",
|
478 |
+
"symfony/polyfill-ctype": "~1.8"
|
479 |
+
},
|
480 |
+
"conflict": {
|
481 |
+
"symfony/console": "<4.4"
|
482 |
+
},
|
483 |
+
"require-dev": {
|
484 |
+
"symfony/console": "^4.4|^5.0"
|
485 |
+
},
|
486 |
+
"suggest": {
|
487 |
+
"symfony/console": "For validating YAML files using the lint command"
|
488 |
+
},
|
489 |
+
"bin": [
|
490 |
+
"Resources/bin/yaml-lint"
|
491 |
+
],
|
492 |
+
"type": "library",
|
493 |
+
"extra": {
|
494 |
+
"branch-version": "5.2"
|
495 |
+
},
|
496 |
+
"autoload": {
|
497 |
+
"psr-4": {
|
498 |
+
"Symfony\\Component\\Yaml\\": ""
|
499 |
+
},
|
500 |
+
"exclude-from-classmap": [
|
501 |
+
"/Tests/"
|
502 |
+
]
|
503 |
+
},
|
504 |
+
"notification-url": "https://packagist.org/downloads/",
|
505 |
+
"license": [
|
506 |
+
"MIT"
|
507 |
+
],
|
508 |
+
"authors": [
|
509 |
+
{
|
510 |
+
"name": "Fabien Potencier",
|
511 |
+
"email": "fabien@symfony.com"
|
512 |
+
},
|
513 |
+
{
|
514 |
+
"name": "Symfony Community",
|
515 |
+
"homepage": "https://symfony.com/contributors"
|
516 |
+
}
|
517 |
+
],
|
518 |
+
"description": "Symfony Yaml Component",
|
519 |
+
"homepage": "https://symfony.com",
|
520 |
+
"time": "2020-10-14T17:08:19+00:00"
|
521 |
+
}
|
522 |
+
],
|
523 |
+
"aliases": [],
|
524 |
+
"minimum-stability": "dev",
|
525 |
+
"stability-flags": {
|
526 |
+
"phpunit/phpunit-php52": 20,
|
527 |
+
"phpunit/phpunit-mock-objects-php52": 20
|
528 |
+
},
|
529 |
+
"prefer-stable": false,
|
530 |
+
"prefer-lowest": false,
|
531 |
+
"platform": {
|
532 |
+
"php": ">=5.2"
|
533 |
+
},
|
534 |
+
"platform-dev": []
|
535 |
+
}
|
vendor/lucatume/di52/makefile
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
php52 = /Applications/Mamp/bin/php/php5.2.17/bin/php
|
2 |
+
benchmarksFolder = /Users/Luca/Repos/php-dependency-injection-benchmarks
|
3 |
+
|
4 |
+
test:
|
5 |
+
docker run --rm \
|
6 |
+
-v "${CURDIR}:/project" \
|
7 |
+
--entrypoint /project/vendor/bin/phpunit-php52 \
|
8 |
+
tommylau/php-5.2 \
|
9 |
+
--bootstrap /project/tests/bootstrap.php \
|
10 |
+
/project/tests/52-compat
|
11 |
+
vendor/bin/phpunit-php52 -v
|
12 |
+
|
13 |
+
benchmark:
|
14 |
+
cd $(benchmarksFolder); \
|
15 |
+
php test1-5_runner.php; \
|
16 |
+
ls -p -t ./results/test1-5_results-*.html | head -1 | xargs open;
|
17 |
+
|
18 |
+
benchmark6:
|
19 |
+
cd $(benchmarksFolder); \
|
20 |
+
php test6_runner.php; \
|
21 |
+
ls -p -t ./results/test6_results-*.html | head -1 | xargs open;
|
22 |
+
|
23 |
+
cover:
|
24 |
+
vendor/bin/phpunit-php52 --coverage-html ./tests/coverage tests
|
25 |
+
open ./tests/coverage/index.html
|
26 |
+
|
27 |
+
lint_52:
|
28 |
+
docker run --rm -v "${CURDIR}:/project" --entrypoint php tommylau/php-5.2 -l /project/src/tad/DI52/Container.php
|
29 |
+
docker run --rm -v "${CURDIR}:/project" --entrypoint php tommylau/php-5.2 -l /project/src/tad/DI52/ContainerInterface.php
|
30 |
+
docker run --rm -v "${CURDIR}:/project" --entrypoint php tommylau/php-5.2 -l /project/src/tad/DI52/ProtectedValue.php
|
31 |
+
docker run --rm -v "${CURDIR}:/project" --entrypoint php tommylau/php-5.2 -l /project/src/tad/DI52/ServiceProviderInterface.php
|
32 |
+
|
33 |
+
lint_53:
|
34 |
+
docker run --rm -v "${CURDIR}:/project" cespi/php-5.3 php -l /project/src/tad/DI52/closuresSupport.php
|
35 |
+
docker run --rm -v "${CURDIR}:/project" cespi/php-5.3 php -l /project/src/tad/DI52/Container.php
|
36 |
+
docker run --rm -v "${CURDIR}:/project" cespi/php-5.3 php -l /project/src/tad/DI52/ContainerInterface.php
|
37 |
+
docker run --rm -v "${CURDIR}:/project" cespi/php-5.3 php -l /project/src/tad/DI52/ProtectedValue.php
|
38 |
+
docker run --rm -v "${CURDIR}:/project" cespi/php-5.3 php -l /project/src/tad/DI52/ServiceProviderInterface.php
|
vendor/lucatume/di52/phpunit.xml
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<phpunit bootstrap='tests/bootstrap.php'
|
2 |
+
colors='true'>
|
3 |
+
<testsuites>
|
4 |
+
<testsuite name='All'>
|
5 |
+
<directory suffix="Test.php">tests/52-compat</directory>
|
6 |
+
<directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">tests/53-above</directory>
|
7 |
+
</testsuite>
|
8 |
+
</testsuites>
|
9 |
+
<filter>
|
10 |
+
<blacklist>
|
11 |
+
<directory suffix=".php">vendor</directory>
|
12 |
+
</blacklist>
|
13 |
+
<whitelist addUncoveredFilesFromWhitelist="true">
|
14 |
+
<directory suffix=".php">src</directory>
|
15 |
+
</whitelist>
|
16 |
+
</filter>
|
17 |
+
</phpunit>
|
vendor/lucatume/di52/src/tad/DI52/Container.php
ADDED
@@ -0,0 +1,906 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class tad_DI52_Container implements ArrayAccess {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var boolean
|
7 |
+
*/
|
8 |
+
protected $useClosures;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var array
|
12 |
+
*/
|
13 |
+
protected $callbacks = array();
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
protected $protected = array();
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var array
|
22 |
+
*/
|
23 |
+
protected $strings = array();
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var array
|
27 |
+
*/
|
28 |
+
protected $objects = array();
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var array
|
32 |
+
*/
|
33 |
+
protected $callables = array();
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var array
|
37 |
+
*/
|
38 |
+
protected $singletons = array();
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @var array
|
42 |
+
*/
|
43 |
+
protected $deferred = array();
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @var array
|
47 |
+
*/
|
48 |
+
protected $chains = array();
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @var array
|
52 |
+
*/
|
53 |
+
protected $reflections = array();
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @var array
|
57 |
+
*/
|
58 |
+
protected $afterbuild = array();
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @var string
|
62 |
+
*/
|
63 |
+
protected $resolving = '';
|
64 |
+
|
65 |
+
/**
|
66 |
+
* @var array
|
67 |
+
*/
|
68 |
+
protected $tags = array();
|
69 |
+
|
70 |
+
/**
|
71 |
+
* @var array
|
72 |
+
*/
|
73 |
+
protected $bootable = array();
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @var array
|
77 |
+
*/
|
78 |
+
protected $contexts = array();
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @var string
|
82 |
+
*/
|
83 |
+
protected $bindingFor;
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @var string
|
87 |
+
*/
|
88 |
+
protected $neededImplementation;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @var string
|
92 |
+
*/
|
93 |
+
protected $id;
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @var array
|
97 |
+
*/
|
98 |
+
protected $bindings = array();
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @var array
|
102 |
+
*/
|
103 |
+
protected $instanceCallbacks = array();
|
104 |
+
|
105 |
+
/**
|
106 |
+
* @var array
|
107 |
+
*/
|
108 |
+
public $__instanceCallbackArgs = array();
|
109 |
+
|
110 |
+
/**
|
111 |
+
* @var array
|
112 |
+
*/
|
113 |
+
protected $dependants = array();
|
114 |
+
|
115 |
+
/**
|
116 |
+
* tad_DI52_Container constructor.
|
117 |
+
*/
|
118 |
+
public function __construct() {
|
119 |
+
$this->id = uniqid(rand(1, 9999));
|
120 |
+
$GLOBALS['__container_' . $this->id] = $this;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Sets a variable on the container.
|
125 |
+
*
|
126 |
+
* Variables will be evaluated before storing, to protect a variable from the process, e.g. storing a closure, use
|
127 |
+
* the `protect` method:
|
128 |
+
*
|
129 |
+
* $container->setVar('foo', $container->protect($f));
|
130 |
+
*
|
131 |
+
* @see tad_DI52_Container::protect()
|
132 |
+
*
|
133 |
+
* @param string $key The alias the container will use to reference the variable.
|
134 |
+
* @param mixed $value The variable value.
|
135 |
+
*/
|
136 |
+
public function setVar($key, $value) {
|
137 |
+
$this->offsetSet($key, $value);
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Sets a variable on the container using the ArrayAccess API.
|
142 |
+
*
|
143 |
+
* When using the container as an array bindings will be bound as singletons; the two functions below are
|
144 |
+
* equivalent:
|
145 |
+
*
|
146 |
+
* $container->singleton('foo','ClassOne');
|
147 |
+
* $container['foo'] = 'ClassOne';
|
148 |
+
*
|
149 |
+
* Variables will be evaluated before storing, to protect a variable from the process, e.g. storing a closure, use
|
150 |
+
* the `protect` method:
|
151 |
+
*
|
152 |
+
* $container['foo'] = $container->protect($f));
|
153 |
+
*
|
154 |
+
* @see tad_DI52_Container::protect()
|
155 |
+
* @see tad_DI52_Container::singleton()
|
156 |
+
*
|
157 |
+
* @param string $key The alias the container will use to reference the variable.
|
158 |
+
* @param mixed $value The variable value.
|
159 |
+
*
|
160 |
+
* @return void
|
161 |
+
* @since 5.0.0
|
162 |
+
*/
|
163 |
+
public function offsetSet($offset, $value) {
|
164 |
+
if ($value instanceof tad_DI52_ProtectedValue) {
|
165 |
+
$this->protected[$offset] = true;
|
166 |
+
$value = $value->getValue();
|
167 |
+
}
|
168 |
+
|
169 |
+
$this->offsetUnset($offset);
|
170 |
+
|
171 |
+
$this->singletons[$offset] = $offset;
|
172 |
+
|
173 |
+
if (isset($this->protected[$offset])) {
|
174 |
+
$this->strings[$offset] = $value;
|
175 |
+
return;
|
176 |
+
}
|
177 |
+
|
178 |
+
if (is_callable($value)) {
|
179 |
+
$this->callables[$offset] = $value;
|
180 |
+
return;
|
181 |
+
}
|
182 |
+
|
183 |
+
if (is_object($value)) {
|
184 |
+
$this->objects[$offset] = $value;
|
185 |
+
return;
|
186 |
+
}
|
187 |
+
|
188 |
+
$this->strings[$offset] = $value;
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Returns a variable stored in the container.
|
193 |
+
*
|
194 |
+
* If the variable is a binding then the binding will be resolved before returning it.
|
195 |
+
*
|
196 |
+
* @see tad_DI52_Container::make
|
197 |
+
*
|
198 |
+
* @param string $key The alias of the variable or binding to fetch.
|
199 |
+
*
|
200 |
+
* @return mixed The variable value or the resolved binding.
|
201 |
+
*/
|
202 |
+
public function getVar($key) {
|
203 |
+
try {
|
204 |
+
return $this->offsetGet($key);
|
205 |
+
} catch (RuntimeException $e) {
|
206 |
+
return null;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Retrieves a variable or a binding from the database.
|
212 |
+
*
|
213 |
+
* If the offset is bound to an implementation then it will be resolved before returning it.
|
214 |
+
* * @param string $offset
|
215 |
+
*
|
216 |
+
* @return mixed
|
217 |
+
*/
|
218 |
+
public function offsetGet($offset) {
|
219 |
+
if (is_object($offset)) {
|
220 |
+
return is_callable($offset) ? call_user_func($offset, $this) : $offset;
|
221 |
+
}
|
222 |
+
|
223 |
+
if (isset($this->objects[$offset])) {
|
224 |
+
return $this->objects[$offset];
|
225 |
+
}
|
226 |
+
|
227 |
+
if (isset($this->strings[$offset])) {
|
228 |
+
if (isset($this->protected[$offset])) {
|
229 |
+
return $this->strings[$offset];
|
230 |
+
}
|
231 |
+
if (is_string($this->strings[$offset]) && class_exists($this->strings[$offset])) {
|
232 |
+
$instance = $this->make($this->strings[$offset]);
|
233 |
+
$this->objects[$offset] = $instance;
|
234 |
+
return $instance;
|
235 |
+
}
|
236 |
+
return $this->strings[$offset];
|
237 |
+
}
|
238 |
+
|
239 |
+
if (isset($this->callables[$offset])) {
|
240 |
+
return call_user_func($this->callables[$offset], $this);
|
241 |
+
}
|
242 |
+
|
243 |
+
if (is_string($offset) && class_exists($offset)) {
|
244 |
+
return $this->resolve($offset);
|
245 |
+
}
|
246 |
+
|
247 |
+
throw new RuntimeException("Nothing is bound to the key '{$offset}'");
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Returns an instance of the class or object bound to an interface, class or string slug if any, else it will try
|
252 |
+
* to automagically resolve the object to a usable instance.
|
253 |
+
*
|
254 |
+
* If the implementation has been bound as singleton using the `singleton` method
|
255 |
+
* or the ArrayAccess API then the implementation will be resolved just on the first request.
|
256 |
+
*
|
257 |
+
* @param string $classOrInterface A fully qualified class or interface name.
|
258 |
+
*
|
259 |
+
* @return mixed
|
260 |
+
*/
|
261 |
+
public function make($classOrInterface) {
|
262 |
+
if (is_object($classOrInterface)) {
|
263 |
+
return $classOrInterface;
|
264 |
+
}
|
265 |
+
|
266 |
+
if (!isset($this->bindings[$classOrInterface])) {
|
267 |
+
try {
|
268 |
+
return $this->build($classOrInterface, true);
|
269 |
+
} catch (Exception $e) {
|
270 |
+
// continue... we tried an early resolution
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
+
if (isset($this->objects[$classOrInterface])) {
|
275 |
+
return $this->objects[$classOrInterface];
|
276 |
+
}
|
277 |
+
|
278 |
+
if (isset($this->callables[$classOrInterface])) {
|
279 |
+
$resolved = call_user_func($this->callables[$classOrInterface], $this);
|
280 |
+
} else {
|
281 |
+
$resolved = $this->resolve($classOrInterface);
|
282 |
+
}
|
283 |
+
|
284 |
+
if (isset($this->singletons[$classOrInterface])) {
|
285 |
+
$this->objects[$classOrInterface] = $resolved;
|
286 |
+
}
|
287 |
+
|
288 |
+
return $resolved;
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Returns an instance of the class or object bound to an interface, class or string slug if any, else it will try
|
293 |
+
* to automagically resolve the object to a usable instance.
|
294 |
+
*
|
295 |
+
* Differently from the `make` method singleton implementations will be be ignored.
|
296 |
+
*
|
297 |
+
* @param string $classOrInterface
|
298 |
+
*
|
299 |
+
* @return array|mixed
|
300 |
+
*/
|
301 |
+
protected function resolve($classOrInterface) {
|
302 |
+
$original = $this->resolving;
|
303 |
+
$this->resolving = $classOrInterface;
|
304 |
+
|
305 |
+
try {
|
306 |
+
if (isset($this->deferred[$classOrInterface])) {
|
307 |
+
/** @var tad_DI52_ServiceProviderInterface $provider */
|
308 |
+
$provider = $this->deferred[$classOrInterface];
|
309 |
+
$provider->register();
|
310 |
+
}
|
311 |
+
|
312 |
+
if (!isset($this->strings[$classOrInterface])) {
|
313 |
+
try {
|
314 |
+
$instance = $this->build($classOrInterface);
|
315 |
+
} catch (Exception $e) {
|
316 |
+
if ( $e instanceof ReflectionException ) {
|
317 |
+
throw $e;
|
318 |
+
}
|
319 |
+
|
320 |
+
throw new RuntimeException("'{$classOrInterface}' is not a bound alias or an existing class.");
|
321 |
+
}
|
322 |
+
} else {
|
323 |
+
if (isset($this->chains[$classOrInterface])) {
|
324 |
+
$instance = $this->buildFromChain($classOrInterface);
|
325 |
+
} else {
|
326 |
+
$instance = $this->build($this->strings[$classOrInterface]);
|
327 |
+
}
|
328 |
+
}
|
329 |
+
|
330 |
+
if (isset($this->afterbuild[$classOrInterface])) {
|
331 |
+
foreach ($this->afterbuild[$classOrInterface] as $method) {
|
332 |
+
call_user_func(array($instance, $method));
|
333 |
+
}
|
334 |
+
}
|
335 |
+
|
336 |
+
$this->resolving = $original;
|
337 |
+
|
338 |
+
return $instance;
|
339 |
+
} catch (Exception $e) {
|
340 |
+
preg_match('/Error while making/', $e->getMessage(), $matches);
|
341 |
+
if (count($matches)) {
|
342 |
+
// @codeCoverageIgnoreStart
|
343 |
+
$divider = "\n\t => ";
|
344 |
+
$prefix = ' ';
|
345 |
+
// @codeCoverageIgnoreEnd
|
346 |
+
} else {
|
347 |
+
$divider = ':';
|
348 |
+
$prefix = 'Error while making ';
|
349 |
+
}
|
350 |
+
$message = "{$prefix} '{$classOrInterface}'{$divider} " . $e->getMessage();
|
351 |
+
|
352 |
+
throw new RuntimeException($message);
|
353 |
+
}
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* @param $implementation
|
358 |
+
* @param bool $resolving
|
359 |
+
*
|
360 |
+
* @return mixed
|
361 |
+
*/
|
362 |
+
protected function build($implementation, $resolving = false) {
|
363 |
+
$this->resolving = $resolving ? $implementation : $this->resolving;
|
364 |
+
if (!isset($this->reflections[$implementation])) {
|
365 |
+
$this->reflections[$implementation] = new ReflectionClass($implementation);
|
366 |
+
}
|
367 |
+
|
368 |
+
/** @var ReflectionClass $classReflection */
|
369 |
+
$classReflection = $this->reflections[$implementation];
|
370 |
+
$constructor = $classReflection->getConstructor();
|
371 |
+
$parameters = empty($constructor) ? array() : $constructor->getParameters();
|
372 |
+
$builtParams = array_map(array($this, '_getParameter'), $parameters);
|
373 |
+
|
374 |
+
$instance = !empty($builtParams) ?
|
375 |
+
$this->reflections[$implementation]->newInstanceArgs($builtParams)
|
376 |
+
: new $implementation;
|
377 |
+
|
378 |
+
return $instance;
|
379 |
+
}
|
380 |
+
|
381 |
+
/**
|
382 |
+
* @param string $classOrInterface
|
383 |
+
*
|
384 |
+
* @return mixed
|
385 |
+
*/
|
386 |
+
protected function buildFromChain($classOrInterface) {
|
387 |
+
$chainElements = $this->chains[$classOrInterface];
|
388 |
+
unset($this->chains[$classOrInterface]);
|
389 |
+
|
390 |
+
$instance = null;
|
391 |
+
foreach (array_reverse($chainElements) as $element) {
|
392 |
+
$instance = $this->resolve($element);
|
393 |
+
$this->objects[$classOrInterface] = $instance;
|
394 |
+
}
|
395 |
+
|
396 |
+
$this->chains[$classOrInterface] = $chainElements;
|
397 |
+
unset($this->objects[$classOrInterface]);
|
398 |
+
|
399 |
+
return $instance;
|
400 |
+
}
|
401 |
+
|
402 |
+
/**
|
403 |
+
* Tags an array of implementations bindings for later retrieval.
|
404 |
+
*
|
405 |
+
* The implementations can also reference interfaces, classes or string slugs.
|
406 |
+
* Example:
|
407 |
+
*
|
408 |
+
* $container->tag(['Posts', 'Users', 'Comments'], 'endpoints');
|
409 |
+
*
|
410 |
+
* @see tad_DI52_Container::tagged()
|
411 |
+
*
|
412 |
+
* @param array $implementationsArray
|
413 |
+
* @param string $tag
|
414 |
+
*/
|
415 |
+
public function tag(array $implementationsArray, $tag) {
|
416 |
+
$this->tags[$tag] = $implementationsArray;
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Retrieves an array of bound implementations resolving them.
|
421 |
+
*
|
422 |
+
* The array of implementations should be bound using the `tag` method:
|
423 |
+
*
|
424 |
+
* $container->tag(['Posts', 'Users', 'Comments'], 'endpoints');
|
425 |
+
* foreach($container->tagged('endpoints') as $endpoint){
|
426 |
+
* $endpoint->register();
|
427 |
+
* }
|
428 |
+
*
|
429 |
+
* @see tad_DI52_Container::tag()
|
430 |
+
*
|
431 |
+
* @param string $tag
|
432 |
+
*
|
433 |
+
* @return array An array of resolved bound implementations.
|
434 |
+
*/
|
435 |
+
public function tagged($tag) {
|
436 |
+
if ($this->hasTag($tag)) {
|
437 |
+
return array_map(array($this, 'offsetGet'), $this->tags[$tag]);
|
438 |
+
}
|
439 |
+
|
440 |
+
throw new RuntimeException("Nothing has been tagged {$tag}.");
|
441 |
+
}
|
442 |
+
|
443 |
+
/**
|
444 |
+
* Checks whether a tag group exists in the container.
|
445 |
+
*
|
446 |
+
* @see tad_DI52_Container::tag()
|
447 |
+
*
|
448 |
+
* @param string $tag
|
449 |
+
*
|
450 |
+
* @return bool
|
451 |
+
*/
|
452 |
+
public function hasTag($tag) {
|
453 |
+
return isset($this->tags[$tag]);
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Registers a service provider implementation.
|
458 |
+
*
|
459 |
+
* The `register` method will be called immediately on the service provider.
|
460 |
+
*
|
461 |
+
* If the provider overloads the `isDeferred` method returning a truthy value then the `register` method will be
|
462 |
+
* called only if one of the implementations provided by the provider is requested. The container defines which
|
463 |
+
* implementations is offering overloading the `provides` method; the method should return an array of provided
|
464 |
+
* implementations.
|
465 |
+
*
|
466 |
+
* If a provider overloads the `boot` method that method will be called when the `boot` method is called on the
|
467 |
+
* container itself.
|
468 |
+
*
|
469 |
+
* @see tad_DI52_ServiceProviderInterface::register()
|
470 |
+
* @see tad_DI52_ServiceProviderInterface::isDeferred()
|
471 |
+
* @see tad_DI52_ServiceProviderInterface::provides()
|
472 |
+
* @see tad_DI52_ServiceProviderInterface::boot()
|
473 |
+
*
|
474 |
+
* @param string $serviceProviderClass
|
475 |
+
*/
|
476 |
+
public function register($serviceProviderClass) {
|
477 |
+
/** @var tad_DI52_ServiceProviderInterface $provider */
|
478 |
+
$provider = new $serviceProviderClass($this);
|
479 |
+
if (!$provider->isDeferred()) {
|
480 |
+
$provider->register();
|
481 |
+
} else {
|
482 |
+
$provided = $provider->provides();
|
483 |
+
|
484 |
+
$count = count($provided);
|
485 |
+
if ($count === 0) {
|
486 |
+
throw new RuntimeException("Service provider '{$serviceProviderClass}' is marked as deferred but is not providing any implementation.");
|
487 |
+
}
|
488 |
+
|
489 |
+
$this->bindings = array_merge($this->bindings, array_combine($provided, $provided));
|
490 |
+
$this->deferred = array_merge($this->deferred,
|
491 |
+
array_combine($provided, array_fill(0, $count, $provider)));
|
492 |
+
}
|
493 |
+
$ref = new ReflectionMethod($provider, 'boot');
|
494 |
+
$requiresBoot = ($ref->getDeclaringClass()->getName() === get_class($provider));
|
495 |
+
if ($requiresBoot) {
|
496 |
+
$this->bootable[] = $provider;
|
497 |
+
}
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* Boots up the application calling the `boot` method of each registered service provider.
|
502 |
+
*
|
503 |
+
* If there are bootable providers (providers overloading the `boot` method) then the `boot` method will be
|
504 |
+
* called on each bootable provider.
|
505 |
+
*
|
506 |
+
* @see tad_DI52_ServiceProviderInterface::boot()
|
507 |
+
*/
|
508 |
+
public function boot() {
|
509 |
+
if (!empty($this->bootable)) {
|
510 |
+
foreach ($this->bootable as $provider) {
|
511 |
+
/** @var tad_DI52_ServiceProviderInterface $provider */
|
512 |
+
$provider->boot();
|
513 |
+
}
|
514 |
+
}
|
515 |
+
}
|
516 |
+
|
517 |
+
/**
|
518 |
+
* Checks whether an interface, class or string slug has been bound in the container.
|
519 |
+
*
|
520 |
+
* @param string $classOrInterface
|
521 |
+
*
|
522 |
+
* @return bool
|
523 |
+
*/
|
524 |
+
public function isBound($classOrInterface) {
|
525 |
+
return $this->offsetExists($classOrInterface);
|
526 |
+
}
|
527 |
+
|
528 |
+
/**
|
529 |
+
* Whether a offset exists
|
530 |
+
*
|
531 |
+
* @see isBound
|
532 |
+
*
|
533 |
+
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
534 |
+
*
|
535 |
+
* @param mixed $offset <p>
|
536 |
+
* An offset to check for.
|
537 |
+
* </p>
|
538 |
+
*
|
539 |
+
* @return boolean true on success or false on failure.
|
540 |
+
* </p>
|
541 |
+
* <p>
|
542 |
+
* The return value will be casted to boolean if non-boolean was returned.
|
543 |
+
* @since 5.0.0
|
544 |
+
*/
|
545 |
+
public function offsetExists($offset) {
|
546 |
+
return isset($this->bindings[$offset]);
|
547 |
+
}
|
548 |
+
|
549 |
+
/**
|
550 |
+
* Binds a class, interface or string slug to a chain of implementations decorating a base
|
551 |
+
* object; the chain will be lazily resolved only on the first call.
|
552 |
+
*
|
553 |
+
* The base decorated object must be the last element of the array.
|
554 |
+
*
|
555 |
+
* @param string $classOrInterface The class, interface or slug the decorator chain should be bound to.
|
556 |
+
* @param array $decorators An array of implementations that decorate an object.
|
557 |
+
* @param array $afterBuildMethods An array of methods that should be called on the instance after it has been
|
558 |
+
* built; the methods should not require any argument.
|
559 |
+
*/
|
560 |
+
public function singletonDecorators($classOrInterface, $decorators, array $afterBuildMethods = null) {
|
561 |
+
$this->bindDecorators($classOrInterface, $decorators, $afterBuildMethods);
|
562 |
+
$this->singletons[$classOrInterface] = $classOrInterface;
|
563 |
+
}
|
564 |
+
|
565 |
+
/**
|
566 |
+
* Binds a class, interface or string slug to to a chain of implementations decorating a
|
567 |
+
* base object.
|
568 |
+
*
|
569 |
+
* The base decorated object must be the last element of the array.
|
570 |
+
*
|
571 |
+
* @param string $classOrInterface The class, interface or slug the decorator chain should be bound to.
|
572 |
+
* @param array $decorators An array of implementations that decorate an object.
|
573 |
+
* @param array $afterBuildMethods An array of methods that should be called on the instance after it has been
|
574 |
+
* built; the methods should not require any argument.
|
575 |
+
*/
|
576 |
+
public function bindDecorators($classOrInterface, array $decorators, array $afterBuildMethods = null) {
|
577 |
+
$this->bindings[$classOrInterface] = $classOrInterface;
|
578 |
+
$this->strings[$classOrInterface] = $decorators;
|
579 |
+
$this->chains[$classOrInterface] = $decorators;
|
580 |
+
|
581 |
+
if (!empty($afterBuildMethods)) {
|
582 |
+
$base = end($decorators);
|
583 |
+
$this->afterbuild[$base] = $afterBuildMethods;
|
584 |
+
}
|
585 |
+
}
|
586 |
+
|
587 |
+
/**
|
588 |
+
* Offset to unset
|
589 |
+
*
|
590 |
+
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
591 |
+
*
|
592 |
+
* @param mixed $offset <p>
|
593 |
+
* The offset to unset.
|
594 |
+
* </p>
|
595 |
+
*
|
596 |
+
* @return void
|
597 |
+
* @since 5.0.0
|
598 |
+
*/
|
599 |
+
public function offsetUnset($offset) {
|
600 |
+
unset(
|
601 |
+
$this->strings[$offset],
|
602 |
+
$this->singletons[$offset],
|
603 |
+
$this->objects[$offset],
|
604 |
+
$this->bindings[$offset],
|
605 |
+
$this->afterbuild[$offset],
|
606 |
+
$this->callables[$offset],
|
607 |
+
$this->contexts[$offset],
|
608 |
+
$this->tags[$offset],
|
609 |
+
$this->chains[$offset]
|
610 |
+
);
|
611 |
+
}
|
612 |
+
|
613 |
+
/**
|
614 |
+
* Starts the `when->needs->give` chain for a contextual binding.
|
615 |
+
*
|
616 |
+
* @param string $class The fully qualified name of the requesting class.
|
617 |
+
*
|
618 |
+
* Example:
|
619 |
+
*
|
620 |
+
* // any class requesting an implementation of `LoggerInterface` will receive this implementation...
|
621 |
+
* $container->singleton('LoggerInterface', 'FilesystemLogger');
|
622 |
+
* // but if the requesting class is `Worker` return another implementation
|
623 |
+
* $container->when('Worker')
|
624 |
+
* ->needs('LoggerInterface)
|
625 |
+
* ->give('RemoteLogger);
|
626 |
+
*
|
627 |
+
* @return tad_DI52_Container
|
628 |
+
*/
|
629 |
+
public function when($class) {
|
630 |
+
$this->bindingFor = $class;
|
631 |
+
|
632 |
+
return $this;
|
633 |
+
}
|
634 |
+
|
635 |
+
/**
|
636 |
+
* Second step of the `when->needs->give` chain for a contextual binding.
|
637 |
+
*
|
638 |
+
* Example:
|
639 |
+
*
|
640 |
+
* // any class requesting an implementation of `LoggerInterface` will receive this implementation...
|
641 |
+
* $container->singleton('LoggerInterface', 'FilesystemLogger');
|
642 |
+
* // but if the requesting class is `Worker` return another implementation
|
643 |
+
* $container->when('Worker')
|
644 |
+
* ->needs('LoggerInterface)
|
645 |
+
* ->give('RemoteLogger);
|
646 |
+
*
|
647 |
+
* @param string $classOrInterface The class or interface needed by the class.
|
648 |
+
*
|
649 |
+
* @return tad_DI52_Container
|
650 |
+
*/
|
651 |
+
public function needs($classOrInterface) {
|
652 |
+
$this->neededImplementation = $classOrInterface;
|
653 |
+
return $this;
|
654 |
+
}
|
655 |
+
|
656 |
+
/**
|
657 |
+
* Third step of the `when->needs->give` chain for a contextual binding.
|
658 |
+
*
|
659 |
+
* Example:
|
660 |
+
*
|
661 |
+
* // any class requesting an implementation of `LoggerInterface` will receive this implementation...
|
662 |
+
* $container->singleton('LoggerInterface', 'FilesystemLogger');
|
663 |
+
* // but if the requesting class is `Worker` return another implementation
|
664 |
+
* $container->when('Worker')
|
665 |
+
* ->needs('LoggerInterface)
|
666 |
+
* ->give('RemoteLogger);
|
667 |
+
*
|
668 |
+
* @param mixed $implementation The implementation specified
|
669 |
+
*/
|
670 |
+
public function give($implementation) {
|
671 |
+
$this->bindings[$this->bindingFor] = $this->bindingFor;
|
672 |
+
|
673 |
+
$this->contexts[$this->neededImplementation] =
|
674 |
+
!empty($this->contexts[$this->neededImplementation]) ?
|
675 |
+
$this->contexts[$this->neededImplementation] : array();
|
676 |
+
$this->contexts[$this->neededImplementation][$this->bindingFor] = $implementation;
|
677 |
+
}
|
678 |
+
|
679 |
+
/**
|
680 |
+
* Protects a value from being resolved by the container.
|
681 |
+
*
|
682 |
+
* Example usage `$container['var'] = $container->protect(function(){return 'bar';});`
|
683 |
+
*
|
684 |
+
* @param mixed $value
|
685 |
+
*/
|
686 |
+
public function protect($value) {
|
687 |
+
return new tad_DI52_ProtectedValue($value);
|
688 |
+
}
|
689 |
+
|
690 |
+
/**
|
691 |
+
* Binds an interface, a class or a string slug to an implementation.
|
692 |
+
*
|
693 |
+
* Existing implementations are replaced.
|
694 |
+
*
|
695 |
+
* @param string $classOrInterface A class or interface fully qualified name or a string slug.
|
696 |
+
* @param mixed $implementation The implementation that should be bound to the alias(es); can be a class name,
|
697 |
+
* an object or a closure.
|
698 |
+
* @param array $afterBuildMethods An array of methods that should be called on the built implementation after
|
699 |
+
* resolving it.
|
700 |
+
*
|
701 |
+
* @throws ReflectionException When binding a class that does not exist without defining an implementation.
|
702 |
+
* @throws InvalidArgumentException When binding a class that cannot be instantiated without defining an implementation.
|
703 |
+
*/
|
704 |
+
public function bind($classOrInterface, $implementation = null, array $afterBuildMethods = null) {
|
705 |
+
if (is_null($implementation)) {
|
706 |
+
$reflection = new ReflectionClass($classOrInterface);
|
707 |
+
if (!$reflection->isInstantiable()) {
|
708 |
+
throw new InvalidArgumentException( sprintf('To bind a class in the Container without defining an implementation, the class must be instantiable. %s is not instantiable.', $classOrInterface) );
|
709 |
+
}
|
710 |
+
$implementation = $classOrInterface;
|
711 |
+
}
|
712 |
+
|
713 |
+
$this->offsetUnset($classOrInterface);
|
714 |
+
|
715 |
+
$this->bindings[$classOrInterface] = $classOrInterface;
|
716 |
+
|
717 |
+
if (is_callable($implementation)) {
|
718 |
+
$this->callables[$classOrInterface] = $implementation;
|
719 |
+
return;
|
720 |
+
}
|
721 |
+
|
722 |
+
if (is_object($implementation)) {
|
723 |
+
$this->objects[$classOrInterface] = $implementation;
|
724 |
+
return;
|
725 |
+
}
|
726 |
+
|
727 |
+
$this->strings[$classOrInterface] = $implementation;
|
728 |
+
|
729 |
+
if (!empty($afterBuildMethods)) {
|
730 |
+
$this->afterbuild[$classOrInterface] = $afterBuildMethods;
|
731 |
+
}
|
732 |
+
}
|
733 |
+
|
734 |
+
/**
|
735 |
+
* Binds an interface a class or a string slug to an implementation and will always return the same instance.
|
736 |
+
*
|
737 |
+
* @param string $classOrInterface A class or interface fully qualified name or a string slug.
|
738 |
+
* @param mixed $implementation The implementation that should be bound to the alias(es); can be a class name,
|
739 |
+
* an object or a closure.
|
740 |
+
* @param array $afterBuildMethods An array of methods that should be called on the built implementation after
|
741 |
+
* resolving it.
|
742 |
+
*/
|
743 |
+
public function singleton($classOrInterface, $implementation = null, array $afterBuildMethods = null) {
|
744 |
+
$this->bind($classOrInterface, $implementation, $afterBuildMethods);
|
745 |
+
|
746 |
+
$this->singletons[$classOrInterface] = $classOrInterface;
|
747 |
+
}
|
748 |
+
|
749 |
+
/**
|
750 |
+
* Returns a lambda function suitable to use as a callback; when called the function will build the implementation
|
751 |
+
* bound to `$classOrInterface` and return the value of a call to `$method` method with the call arguments.
|
752 |
+
*
|
753 |
+
* @param string|object $classOrInterface A class or interface fully qualified name or a string slug.
|
754 |
+
* @param string $method The method that should be called on the resolved implementation with the
|
755 |
+
* specified array arguments.
|
756 |
+
*
|
757 |
+
* @return mixed The called method return value.
|
758 |
+
*/
|
759 |
+
public function callback($classOrInterface, $method) {
|
760 |
+
$this->initClosuresSupport();
|
761 |
+
|
762 |
+
if (!is_string($method)) {
|
763 |
+
throw new RuntimeException('Callback method must be a string');
|
764 |
+
}
|
765 |
+
|
766 |
+
$classOrInterfaceName = is_object($classOrInterface) ? spl_object_hash($classOrInterface) : $classOrInterface;
|
767 |
+
$cacheKey = $classOrInterfaceName . '::' . $method;
|
768 |
+
|
769 |
+
if ( isset( $this->callbacks[ $cacheKey ] ) ) {
|
770 |
+
// Only return the existing callback if $classOrInterface was not an object (so it remains unique).
|
771 |
+
return $this->callbacks[ $cacheKey ];
|
772 |
+
}
|
773 |
+
|
774 |
+
if ($this->useClosures) {
|
775 |
+
$f = di52_callbackClosure($this, $classOrInterface, $method);
|
776 |
+
} else {
|
777 |
+
$classOrInterfaceName = is_object($classOrInterface) ? get_class($classOrInterface) : $classOrInterface;
|
778 |
+
// @codeCoverageIgnoreStart
|
779 |
+
if (is_object($classOrInterface) || is_callable($classOrInterface)) {
|
780 |
+
$objectId = uniqid(rand(1, 9999) . md5($classOrInterfaceName));
|
781 |
+
$this->bind($objectId, $classOrInterface);
|
782 |
+
$body = '$a = func_get_args();
|
783 |
+
global $__container_' . $this->id . ';
|
784 |
+
$c = $__container_' . $this->id . ';
|
785 |
+
$i = $c->make(\'' . $objectId . '\');
|
786 |
+
return call_user_func_array(array($i, \'' . $method . '\'),$a);';
|
787 |
+
} else {
|
788 |
+
$body = '$a = func_get_args();
|
789 |
+
global $__container_' . $this->id . ';
|
790 |
+
$c = $__container_' . $this->id . ';
|
791 |
+
$i = $c->make(\'' . $classOrInterfaceName . '\');
|
792 |
+
return call_user_func_array(array($i, \'' . $method . '\'),$a);';
|
793 |
+
}
|
794 |
+
$f = create_function('', $body);
|
795 |
+
// @codeCoverageIgnoreEnd
|
796 |
+
}
|
797 |
+
|
798 |
+
$this->callbacks[ $cacheKey ] = $f;
|
799 |
+
|
800 |
+
return $f;
|
801 |
+
}
|
802 |
+
|
803 |
+
public function _getParameter(ReflectionParameter $parameter) {
|
804 |
+
$class = $parameter->getClass();
|
805 |
+
|
806 |
+
if (null === $class) {
|
807 |
+
if (!$parameter->isDefaultValueAvailable()) {
|
808 |
+
throw new ReflectionException("parameter '{$parameter->name}' of '{$this->resolving}::__construct' does not have a default value.");
|
809 |
+
}
|
810 |
+
return $parameter->getDefaultValue();
|
811 |
+
}
|
812 |
+
|
813 |
+
$parameterClass = $parameter->getClass()->getName();
|
814 |
+
|
815 |
+
if (!$this->isBound($parameterClass) && !$parameter->getClass()->isInstantiable()) {
|
816 |
+
if (!$parameter->isDefaultValueAvailable()) {
|
817 |
+
throw new ReflectionException("parameter '{$parameter->name}' of '{$this->resolving}::__construct' does not have a default value.");
|
818 |
+
}
|
819 |
+
return $parameter->getDefaultValue();
|
820 |
+
}
|
821 |
+
|
822 |
+
if (!isset($this->dependants[$parameterClass])) {
|
823 |
+
$this->dependants[$parameterClass] = array($this->resolving);
|
824 |
+
} else {
|
825 |
+
$this->dependants[$parameterClass][] = $this->resolving;
|
826 |
+
}
|
827 |
+
|
828 |
+
return isset($this->contexts[$parameterClass][$this->resolving]) ?
|
829 |
+
$this->offsetGet($this->contexts[$parameterClass][$this->resolving])
|
830 |
+
: $this->offsetGet($parameterClass);
|
831 |
+
}
|
832 |
+
|
833 |
+
/**
|
834 |
+
* Returns a callable object that will build an instance of the specified class using the
|
835 |
+
* specified arguments when called.
|
836 |
+
*
|
837 |
+
* The callable will be a closure on PHP 5.3+ or a lambda function on PHP 5.2.
|
838 |
+
*
|
839 |
+
* @param string $classOrInterface The fully qualified name of a class or an interface.
|
840 |
+
* @param array $args An array of arguments that should be used to build the instancee;
|
841 |
+
* note that any argument will be resolved using the container itself and bindings
|
842 |
+
* will apply.
|
843 |
+
*
|
844 |
+
* @return callable A callable function that will return an instance of the specified class when
|
845 |
+
* called.
|
846 |
+
*/
|
847 |
+
public function instance($classOrInterface, array $args = array()) {
|
848 |
+
$this->initClosuresSupport();
|
849 |
+
|
850 |
+
$classOrInterfaceName = is_object($classOrInterface) ? get_class($classOrInterface) : $classOrInterface;
|
851 |
+
|
852 |
+
$instanceId = md5($classOrInterfaceName . '::' . serialize($args));
|
853 |
+
if (!isset($this->instanceCallbacks[$instanceId])) {
|
854 |
+
$this->__instanceCallbackArgs[$instanceId] = $args;
|
855 |
+
|
856 |
+
if ($this->useClosures) {
|
857 |
+
$f = di52_instanceClosure($this, $classOrInterface, $args);
|
858 |
+
} else {
|
859 |
+
// @codeCoverageIgnoreStart
|
860 |
+
if (is_object($classOrInterface) || is_callable($classOrInterface)) {
|
861 |
+
$objectId = uniqid(rand(1, 9999) . md5($classOrInterfaceName));
|
862 |
+
$this->bind($objectId, $classOrInterface);
|
863 |
+
$body = "global \$__container_{$this->id};
|
864 |
+
\$c = \$__container_{$this->id};
|
865 |
+
return \$c->make('{$objectId}'); ";
|
866 |
+
} else {
|
867 |
+
$body = "global \$__container_{$this->id};
|
868 |
+
\$c = \$__container_{$this->id};
|
869 |
+
\$r = new ReflectionClass('{$classOrInterface}');
|
870 |
+
\$vars = \$c->__instanceCallbackArgs['{$instanceId}'];
|
871 |
+
\$constructor = \$r->getConstructor();
|
872 |
+
if (null === \$constructor || empty(\$vars)) {
|
873 |
+
return \$c->make('{$classOrInterface}');
|
874 |
+
}
|
875 |
+
\$args = array();
|
876 |
+
foreach (\$vars as \$var) {
|
877 |
+
try {
|
878 |
+
\$args[] = \$c->make(\$var);
|
879 |
+
} catch (RuntimeException \$e) {
|
880 |
+
\$args[] = \$var;
|
881 |
+
}
|
882 |
+
}
|
883 |
+
return \$r->newInstanceArgs(\$args);";
|
884 |
+
}
|
885 |
+
$f = create_function('', $body);
|
886 |
+
// @codeCoverageIgnoreEnd
|
887 |
+
}
|
888 |
+
|
889 |
+
$this->instanceCallbacks[$instanceId] = $f;
|
890 |
+
}
|
891 |
+
|
892 |
+
return $this->instanceCallbacks[$instanceId];
|
893 |
+
}
|
894 |
+
|
895 |
+
/**
|
896 |
+
* Initializes the closure support on PHP 5.3+.
|
897 |
+
*/
|
898 |
+
protected function initClosuresSupport() {
|
899 |
+
if (null === $this->useClosures) {
|
900 |
+
$this->useClosures = version_compare(PHP_VERSION, '5.3.0', '>=');
|
901 |
+
if ($this->useClosures) {
|
902 |
+
require_once dirname(__FILE__) . '/closuresSupport.php';
|
903 |
+
}
|
904 |
+
}
|
905 |
+
}
|
906 |
+
}
|
vendor/lucatume/di52/src/tad/DI52/ContainerInterface.php
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface tad_DI52_ContainerInterface
|
5 |
+
*
|
6 |
+
* The API supported by the container.
|
7 |
+
*/
|
8 |
+
interface tad_DI52_ContainerInterface
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* @param string $key
|
12 |
+
* @param mixed $value
|
13 |
+
*/
|
14 |
+
public function setVar($key, $value);
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param string $key
|
18 |
+
*
|
19 |
+
* @return mixed
|
20 |
+
*/
|
21 |
+
public function getVar($key);
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Binds an interface or class to an implementation.
|
25 |
+
*
|
26 |
+
* @param string $classOrInterface An alias or an array of implementation aliases
|
27 |
+
* @param mixed $implementation
|
28 |
+
* @param array $afterBuildMethods
|
29 |
+
*/
|
30 |
+
public function bind($classOrInterface, $implementation, array $afterBuildMethods = null);
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Binds an interface or class to an implementation replacing an existing implementation.
|
34 |
+
*
|
35 |
+
* @param string $classOrInterface
|
36 |
+
* @param string $implementation
|
37 |
+
* @param array $afterBuildMethods
|
38 |
+
*/
|
39 |
+
public function replaceBind($classOrInterface, $implementation, array $afterBuildMethods = null);
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Returns an instance of the class or object bound to an interface.
|
43 |
+
*
|
44 |
+
* @param string $classOrInterface A fully qualified class or interface name.
|
45 |
+
* @return mixed
|
46 |
+
*/
|
47 |
+
public function make($classOrInterface);
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Binds an interface or class to an implementation and will always return the same instance.
|
51 |
+
*
|
52 |
+
* @param string $classOrInterface
|
53 |
+
* @param string $implementation
|
54 |
+
* @param array $afterBuildMethods
|
55 |
+
*/
|
56 |
+
public function singleton($classOrInterface, $implementation, array $afterBuildMethods = null);
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Binds an interface or class to an implementation and will always return the same instance replacing an
|
60 |
+
* existing singleton binding.
|
61 |
+
*
|
62 |
+
* @param string $classOrInterface
|
63 |
+
* @param string $implementation
|
64 |
+
* @param array $afterBuildMethods
|
65 |
+
*/
|
66 |
+
public function replaceSingleton($classOrInterface, $implementation, array $afterBuildMethods = null);
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Tags an array of implementation bindings.
|
70 |
+
*
|
71 |
+
* @param array $implementationsArray
|
72 |
+
* @param string $tag
|
73 |
+
*/
|
74 |
+
public function tag(array $implementationsArray, $tag);
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Retrieves an array of bound implementations resolving them.
|
78 |
+
*
|
79 |
+
* @param string $tag
|
80 |
+
* @return array An array of resolved bound implementations.
|
81 |
+
*/
|
82 |
+
public function tagged($tag);
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Registers a service provider implementation.
|
86 |
+
*
|
87 |
+
* @param string $serviceProviderClass
|
88 |
+
*/
|
89 |
+
public function register($serviceProviderClass);
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Boots up the application calling the `boot` method of each registered service provider.
|
93 |
+
*/
|
94 |
+
public function boot();
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Checks whether if an interface or class has been bound to a concrete implementation.
|
98 |
+
*
|
99 |
+
* @param string $classOrInterface
|
100 |
+
* @return bool
|
101 |
+
*/
|
102 |
+
public function isBound($classOrInterface);
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Checks whether a tag group exists in the container.
|
106 |
+
*
|
107 |
+
* @param string $tag
|
108 |
+
* @return bool
|
109 |
+
*/
|
110 |
+
public function hasTag($tag);
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Binds a chain of decorators to a class or interface.
|
114 |
+
*
|
115 |
+
* @param $classOrInterface
|
116 |
+
* @param array $decorators
|
117 |
+
*/
|
118 |
+
public function bindDecorators($classOrInterface, array $decorators);
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Binds a chain of decorators to a class or interface to be returned as a singleton.
|
122 |
+
*
|
123 |
+
* @param $classOrInterface
|
124 |
+
* @param array $decorators
|
125 |
+
*/
|
126 |
+
public function singletonDecorators($classOrInterface, $decorators);
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Starts the `when->needs->give` chain for a contextual binding.
|
130 |
+
*
|
131 |
+
* @param string $class The fully qualified name of the requesting class.
|
132 |
+
*
|
133 |
+
* Example:
|
134 |
+
*
|
135 |
+
* // any class requesting an implementation of `LoggerInterface` will receive this implementation...
|
136 |
+
* $container->singleton('LoggerInterface', 'FilesystemLogger');
|
137 |
+
* // but if the requesting class is `Worker` return another implementation
|
138 |
+
* $container->when('Worker')
|
139 |
+
* ->needs('LoggerInterface)
|
140 |
+
* ->give('RemoteLogger);
|
141 |
+
*
|
142 |
+
* @return tad_DI52_ContainerInterface
|
143 |
+
*/
|
144 |
+
public function when($class);
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Second step the `when->needs->give` chain for a contextual binding.
|
148 |
+
*
|
149 |
+
* @param string $classOrInterface The fully qualified name of the requested class.
|
150 |
+
*
|
151 |
+
* Example:
|
152 |
+
*
|
153 |
+
* // any class requesting an implementation of `LoggerInterface` will receive this implementation...
|
154 |
+
* $container->singleton('LoggerInterface', 'FilesystemLogger');
|
155 |
+
* // but if the requesting class is `Worker` return another implementation
|
156 |
+
* $container->when('Worker')
|
157 |
+
* ->needs('LoggerInterface)
|
158 |
+
* ->give('RemoteLogger);
|
159 |
+
*
|
160 |
+
* @return tad_DI52_ContainerInterface
|
161 |
+
*/
|
162 |
+
public function needs($classOrInterface);
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Last step the `when->needs->give` chain for a contextual binding.
|
166 |
+
*
|
167 |
+
* @param mixed $implementation An implementation of the requested class.
|
168 |
+
*
|
169 |
+
* Example:
|
170 |
+
*
|
171 |
+
* // any class requesting an implementation of `LoggerInterface` will receive this implementation...
|
172 |
+
* $container->singleton('LoggerInterface', 'FilesystemLogger');
|
173 |
+
* // but if the requesting class is `Worker` return another implementation
|
174 |
+
* $container->when('Worker')
|
175 |
+
* ->needs('LoggerInterface)
|
176 |
+
* ->give('RemoteLogger);
|
177 |
+
*
|
178 |
+
* @return tad_DI52_ContainerInterface
|
179 |
+
*/
|
180 |
+
public function give($implementation);
|
181 |
+
}
|
vendor/lucatume/di52/src/tad/DI52/ProtectedValue.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class tad_DI52_ProtectedValue
|
4 |
+
{
|
5 |
+
|
6 |
+
/**
|
7 |
+
* @var mixed
|
8 |
+
*/
|
9 |
+
protected $value;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* tad_DI52_ProtectedValue constructor.
|
13 |
+
* @param mixed $value
|
14 |
+
*/
|
15 |
+
public function __construct($value)
|
16 |
+
{
|
17 |
+
$this->value = $value;
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return mixed
|
22 |
+
*/
|
23 |
+
public function getValue()
|
24 |
+
{
|
25 |
+
return $this->value;
|
26 |
+
}
|
27 |
+
}
|
vendor/lucatume/di52/src/tad/DI52/ServiceProvider.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class tad_DI52_ServiceProvider
|
5 |
+
* @codeCoverageIgnore
|
6 |
+
*/
|
7 |
+
abstract class tad_DI52_ServiceProvider implements tad_DI52_ServiceProviderInterface
|
8 |
+
{
|
9 |
+
/**
|
10 |
+
* Whether the service provider will be a deferred one or not.
|
11 |
+
*
|
12 |
+
* @var bool
|
13 |
+
*/
|
14 |
+
protected $deferred = false;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var tad_DI52_Container
|
18 |
+
*/
|
19 |
+
protected $container;
|
20 |
+
|
21 |
+
|
22 |
+
/**
|
23 |
+
* tad_DI52_ServiceProvider constructor.
|
24 |
+
* @param tad_DI52_Container $container
|
25 |
+
*/
|
26 |
+
public function __construct(tad_DI52_Container $container)
|
27 |
+
{
|
28 |
+
$this->container = $container;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Whether the service provider will be a deferred one or not.
|
33 |
+
*
|
34 |
+
* @return bool
|
35 |
+
*/
|
36 |
+
public function isDeferred()
|
37 |
+
{
|
38 |
+
return $this->deferred;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Returns an array of the class or interfaces bound and provided by the service provider.
|
43 |
+
*
|
44 |
+
* @return array
|
45 |
+
*/
|
46 |
+
public function provides()
|
47 |
+
{
|
48 |
+
return array();
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Binds and sets up implementations at boot time.
|
53 |
+
*/
|
54 |
+
public function boot()
|
55 |
+
{
|
56 |
+
// no-op
|
57 |
+
}
|
58 |
+
}
|
vendor/lucatume/di52/src/tad/DI52/ServiceProviderInterface.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface tad_DI52_ServiceProviderInterface
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* Binds and sets up implementations.
|
7 |
+
*/
|
8 |
+
public function register();
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Binds and sets up implementations at boot time.
|
12 |
+
*/
|
13 |
+
public function boot();
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Returns an array of implementations provided by the service provider.
|
17 |
+
*
|
18 |
+
* @return array
|
19 |
+
*/
|
20 |
+
public function provides();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Whether the service provider will be a deferred one or not.
|
24 |
+
*
|
25 |
+
* @return bool
|
26 |
+
*/
|
27 |
+
public function isDeferred();
|
28 |
+
}
|
vendor/lucatume/di52/src/tad/DI52/closuresSupport.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Builds and returns a closure to be used to lazily make objects on PHP 5.3+, call a method on them and return the
|
4 |
+
* method value.
|
5 |
+
*
|
6 |
+
* @param tad_DI52_Container $container
|
7 |
+
* @param string|object $classOrInterface
|
8 |
+
* @param string $method
|
9 |
+
*
|
10 |
+
* @return Closure
|
11 |
+
*/
|
12 |
+
function di52_callbackClosure(tad_DI52_Container $container, $classOrInterface, $method) {
|
13 |
+
if ( is_object( $classOrInterface ) ) {
|
14 |
+
$objectId = uniqid( spl_object_hash( $classOrInterface ), true );
|
15 |
+
$container->bind( $objectId, $classOrInterface );
|
16 |
+
} else {
|
17 |
+
$objectId = $classOrInterface;
|
18 |
+
}
|
19 |
+
|
20 |
+
$isStatic = false;
|
21 |
+
try {
|
22 |
+
$reflectionMethod = new ReflectionMethod($classOrInterface, $method);
|
23 |
+
$isStatic = $reflectionMethod->isStatic();
|
24 |
+
} catch ( ReflectionException $e ) {
|
25 |
+
// no-op
|
26 |
+
}
|
27 |
+
|
28 |
+
return function () use ( $isStatic, $container, $objectId, $method ) {
|
29 |
+
return $isStatic ?
|
30 |
+
call_user_func_array( array( $objectId, $method ), func_get_args() )
|
31 |
+
: call_user_func_array( array( $container->make( $objectId ), $method ), func_get_args() );
|
32 |
+
};
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Builds and returns a closure to be used to lazily make objects on PHP 5.3+ and return them.
|
37 |
+
*
|
38 |
+
* @param tad_DI52_Container $container
|
39 |
+
* @param string $classOrInterface
|
40 |
+
* @param array $vars
|
41 |
+
*
|
42 |
+
* @return Closure
|
43 |
+
*/
|
44 |
+
function di52_instanceClosure(tad_DI52_Container $container, $classOrInterface, array $vars = array()) {
|
45 |
+
return function () use ($container, $classOrInterface, $vars) {
|
46 |
+
if (is_object($classOrInterface)) {
|
47 |
+
if (is_callable($classOrInterface)) {
|
48 |
+
return call_user_func_array($classOrInterface, $vars);
|
49 |
+
}
|
50 |
+
return $classOrInterface;
|
51 |
+
}
|
52 |
+
|
53 |
+
$r = new ReflectionClass($classOrInterface);
|
54 |
+
$constructor = $r->getConstructor();
|
55 |
+
if (null === $constructor || empty($vars)) {
|
56 |
+
return $container->make($classOrInterface);
|
57 |
+
}
|
58 |
+
$args = array();
|
59 |
+
foreach ($vars as $var) {
|
60 |
+
try {
|
61 |
+
$args[] = $container->make($var);
|
62 |
+
} catch (RuntimeException $e) {
|
63 |
+
$args[] = $var;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
return $r->newInstanceArgs($args);
|
67 |
+
};
|
68 |
+
}
|
vendor/lucatume/di52/tests/52-compat/Container52CompatTest.php
ADDED
@@ -0,0 +1,1448 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TestObject {
|
4 |
+
protected $num;
|
5 |
+
|
6 |
+
public function __construct( $num = 123 ) {
|
7 |
+
$this->num = $num;
|
8 |
+
}
|
9 |
+
|
10 |
+
public function getNum() {
|
11 |
+
return $this->num;
|
12 |
+
}
|
13 |
+
|
14 |
+
public static function staticOne() {
|
15 |
+
return 'static one';
|
16 |
+
}
|
17 |
+
|
18 |
+
public static function staticTwo() {
|
19 |
+
return 'static two';
|
20 |
+
}
|
21 |
+
|
22 |
+
public static function staticThree( $param1 ) {
|
23 |
+
return 'static two';
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
interface TestInterface{
|
28 |
+
public static function apiMethodOne( $param1 = 23 );
|
29 |
+
|
30 |
+
public function apiMethodTwo( $param1 );
|
31 |
+
}
|
32 |
+
|
33 |
+
class Container52CompatTest extends PHPUnit_Framework_TestCase {
|
34 |
+
|
35 |
+
public function boundVariables() {
|
36 |
+
return array(
|
37 |
+
array('bar'),
|
38 |
+
array(23),
|
39 |
+
array((object)array('prop' => 'value')),
|
40 |
+
array(''),
|
41 |
+
);
|
42 |
+
}
|
43 |
+
|
44 |
+
protected function setUp() {
|
45 |
+
ClassEight::reset();
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @test
|
50 |
+
* it should allow setting a var on the container
|
51 |
+
* @dataProvider boundVariables
|
52 |
+
*/
|
53 |
+
public function it_should_allow_setting_a_var_on_the_container($value) {
|
54 |
+
$container = new tad_DI52_Container();
|
55 |
+
|
56 |
+
$container->setVar('foo', $value);
|
57 |
+
|
58 |
+
$this->assertEquals($value, $container->getVar('foo'));
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @test
|
63 |
+
* it should allow setting a var on the container with ArrayAccess API
|
64 |
+
* @dataProvider boundVariables
|
65 |
+
*/
|
66 |
+
public function it_should_allow_setting_a_var_on_the_container_with_array_access_api($value) {
|
67 |
+
$container = new tad_DI52_Container();
|
68 |
+
|
69 |
+
$container['foo'] = $value;
|
70 |
+
|
71 |
+
$this->assertEquals($value, $container['foo']);
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @test
|
76 |
+
* it should return null when trying to get non existing var
|
77 |
+
*/
|
78 |
+
public function it_should_return_null_when_trying_to_get_non_existing_var() {
|
79 |
+
$container = new tad_DI52_Container();
|
80 |
+
|
81 |
+
$this->assertNull($container->getVar('foo'));
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* @test
|
86 |
+
* it should return throw when using ArrayAccess API to get non set var
|
87 |
+
*/
|
88 |
+
public function it_should_return_throw_when_using_array_access_api_to_get_non_set_var() {
|
89 |
+
$container = new tad_DI52_Container();
|
90 |
+
|
91 |
+
$this->setExpectedException('RuntimeException');
|
92 |
+
|
93 |
+
$this->assertNull($container['foo']);
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @test
|
98 |
+
* it should allow binding an implementation with no constructor to an interface
|
99 |
+
*/
|
100 |
+
public function it_should_allow_binding_an_implementation_with_no_constructor_to_an_interface() {
|
101 |
+
$container = new tad_DI52_Container();
|
102 |
+
|
103 |
+
$container->bind('One', 'ClassOne');
|
104 |
+
|
105 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @test
|
110 |
+
* it should return a different instance of a bound interface implementation on each build
|
111 |
+
*/
|
112 |
+
public function it_should_return_a_different_instance_of_a_bound_interface_implementation_on_each_build() {
|
113 |
+
$container = new tad_DI52_Container();
|
114 |
+
|
115 |
+
$container->bind('One', 'ClassOne');
|
116 |
+
|
117 |
+
$this->assertNotSame($container->make('One'), $container->make('One'));
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @test
|
122 |
+
* it should allow binding an implementation with constructor to an interface
|
123 |
+
*/
|
124 |
+
public function it_should_allow_binding_an_implementation_with_constructor_to_an_interface() {
|
125 |
+
$container = new tad_DI52_Container();
|
126 |
+
|
127 |
+
$container->bind('One', 'ClassOneOne');
|
128 |
+
|
129 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* @test
|
134 |
+
* it should allow binding an implementation with constructor arguments
|
135 |
+
*/
|
136 |
+
public function it_should_allow_binding_an_implementation_with_constructor_arguments() {
|
137 |
+
$container = new tad_DI52_Container();
|
138 |
+
|
139 |
+
$container->bind('One', 'ClassOneTwo');
|
140 |
+
|
141 |
+
$this->assertInstanceOf('ClassOneTwo', $container->make('One'));
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @test
|
146 |
+
* it should allow binding an implementation to a string slug
|
147 |
+
*/
|
148 |
+
public function it_should_allow_binding_an_implementation_to_a_string_slug() {
|
149 |
+
$container = new tad_DI52_Container();
|
150 |
+
|
151 |
+
$container->bind('foo', 'ClassOneTwo');
|
152 |
+
|
153 |
+
$this->assertInstanceOf('ClassOneTwo', $container->make('foo'));
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* @test
|
158 |
+
* it should allow binding an implementation to a class
|
159 |
+
*/
|
160 |
+
public function it_should_allow_binding_an_implementation_to_a_class() {
|
161 |
+
$container = new tad_DI52_Container();
|
162 |
+
|
163 |
+
$container->bind('ClassOne', 'ClassOneOne');
|
164 |
+
|
165 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('ClassOne'));
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @test
|
170 |
+
* it should resolve unbound class with no constructor
|
171 |
+
*/
|
172 |
+
public function it_should_resolve_unbound_class_with_no_constructor() {
|
173 |
+
$container = new tad_DI52_Container();
|
174 |
+
|
175 |
+
$this->assertInstanceOf('ClassOne', $container->make('ClassOne'));
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* @test
|
180 |
+
* it should resolve an unbound class with a defaulted scalar dependency
|
181 |
+
*/
|
182 |
+
public function it_should_resolve_an_unbound_class_with_a_defaulted_scalar_dependency() {
|
183 |
+
$container = new tad_DI52_Container();
|
184 |
+
|
185 |
+
$this->assertInstanceOf('ClassOneTwo', $container->make('ClassOneTwo'));
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* @test
|
190 |
+
* it should throw if trying to resolve class with unbound interface dependency
|
191 |
+
*/
|
192 |
+
public function it_should_throw_if_trying_to_resolve_class_with_unbound_interface_dependency() {
|
193 |
+
$this->setExpectedException('RuntimeException');
|
194 |
+
|
195 |
+
$container = new tad_DI52_Container();
|
196 |
+
|
197 |
+
$container->make('ClassTwo');
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* @test
|
202 |
+
* it should resolve an unbound class with an interface dependency
|
203 |
+
*/
|
204 |
+
public function it_should_resolve_an_unbound_class_with_an_interface_dependency() {
|
205 |
+
$container = new tad_DI52_Container();
|
206 |
+
|
207 |
+
$container->bind('One', 'ClassOne');
|
208 |
+
|
209 |
+
$this->assertInstanceOf('ClassTwo', $container->make('ClassTwo'));
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* @test
|
214 |
+
* it should resolve an unbound class with a class dependency
|
215 |
+
*/
|
216 |
+
public function it_should_resolve_an_unbound_class_with_a_class_dependency() {
|
217 |
+
$container = new tad_DI52_Container();
|
218 |
+
|
219 |
+
$this->assertInstanceOf('ClassTwoOne', $container->make('ClassTwoOne'));
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* @test
|
224 |
+
* it should resolve an unbound class with plus one interface dependencies
|
225 |
+
*/
|
226 |
+
public function it_should_resolve_an_unbound_class_with_plus_one_interface_dependencies() {
|
227 |
+
$container = new tad_DI52_Container();
|
228 |
+
|
229 |
+
$container->bind('One', 'ClassOne');
|
230 |
+
$container->bind('Two', 'ClassTwo');
|
231 |
+
|
232 |
+
$this->assertInstanceOf('ClassThree', $container->make('ClassThree'));
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* @test
|
237 |
+
* it should resolve an unbound class with plus one class dependencies
|
238 |
+
*/
|
239 |
+
public function it_should_resolve_an_unbound_class_with_plus_one_class_dependencies() {
|
240 |
+
$container = new tad_DI52_Container();
|
241 |
+
|
242 |
+
$container->bind('One', 'ClassOne');
|
243 |
+
|
244 |
+
$this->assertInstanceOf('ClassThreeOne', $container->make('ClassThreeone'));
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* @test
|
249 |
+
* it should resolve an unbound class with plus one interface and class dependencies
|
250 |
+
*/
|
251 |
+
public function it_should_resolve_an_unbound_class_with_plus_one_interface_and_class_dependencies() {
|
252 |
+
$container = new tad_DI52_Container();
|
253 |
+
|
254 |
+
$this->assertInstanceOf('ClassThreeTwo', $container->make('ClassThreeTwo'));
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* @test
|
259 |
+
* it should throw if trying to resolve class with non type-hinted dependency without default
|
260 |
+
*/
|
261 |
+
public function it_should_throw_if_trying_to_resolve_class_with_non_type_hinted_dependency_without_default() {
|
262 |
+
$container = new tad_DI52_Container();
|
263 |
+
|
264 |
+
$this->setExpectedException('RuntimeException');
|
265 |
+
|
266 |
+
$container->make('ClassFour');
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* @test
|
271 |
+
* it should allow binding a class to an interface as a singleton
|
272 |
+
*/
|
273 |
+
public function it_should_allow_binding_a_class_to_an_interface_as_a_singleton() {
|
274 |
+
$container = new tad_DI52_Container();
|
275 |
+
|
276 |
+
$container->singleton('One', 'ClassOne');
|
277 |
+
|
278 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
279 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* @test
|
284 |
+
* it should allow binding a class to a class as a singleton
|
285 |
+
*/
|
286 |
+
public function it_should_allow_binding_a_class_to_a_class_as_a_singleton() {
|
287 |
+
$container = new tad_DI52_Container();
|
288 |
+
|
289 |
+
$container->singleton('ClassOne', 'ClassOneOne');
|
290 |
+
|
291 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('ClassOne'));
|
292 |
+
$this->assertSame($container->make('ClassOne'), $container->make('ClassOne'));
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* @test
|
297 |
+
* it should allow binding a class to a string slug as a singleton
|
298 |
+
*/
|
299 |
+
public function it_should_allow_binding_a_class_to_a_string_slug_as_a_singleton() {
|
300 |
+
$container = new tad_DI52_Container();
|
301 |
+
|
302 |
+
$container->singleton('one.foo', 'ClassOne');
|
303 |
+
|
304 |
+
$this->assertInstanceOf('ClassOne', $container->make('one.foo'));
|
305 |
+
$this->assertSame($container->make('one.foo'), $container->make('one.foo'));
|
306 |
+
}
|
307 |
+
|
308 |
+
public function implementationKeysAndValues() {
|
309 |
+
return array(
|
310 |
+
array('One', 'ClassOne'),
|
311 |
+
array('ClassOne', 'ClassOneOne'),
|
312 |
+
);
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* @test
|
317 |
+
* it should bind an implementation as singleton when using ArrayAccess API
|
318 |
+
* @dataProvider implementationKeysAndValues
|
319 |
+
*/
|
320 |
+
public function it_should_bind_an_implementation_as_singleton_when_using_array_access_api($key, $value) {
|
321 |
+
$container = new tad_DI52_Container();
|
322 |
+
|
323 |
+
$container[$key] = $value;
|
324 |
+
|
325 |
+
$this->assertInstanceOf($value, $container[$key]);
|
326 |
+
$this->assertSame($container[$key], $container[$key]);
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* @test
|
331 |
+
* it should allow binding a decorator chain to an interface
|
332 |
+
*/
|
333 |
+
public function it_should_allow_binding_a_decorator_chain_to_an_interface() {
|
334 |
+
$container = new tad_DI52_Container();
|
335 |
+
|
336 |
+
$container->bindDecorators('Four', array('FourDecoratorOne', 'FourDecoratorTwo', 'FourDecoratorThree', 'FourBase'));
|
337 |
+
|
338 |
+
$this->assertInstanceOf('Four', $container->make('Four'));
|
339 |
+
$this->assertNotSame($container->make('Four'), $container->make('Four'));
|
340 |
+
}
|
341 |
+
|
342 |
+
/**
|
343 |
+
* @test
|
344 |
+
* it should allow specifying after build methods to call on a decorator chain base
|
345 |
+
*/
|
346 |
+
public function it_should_allow_specifying_after_build_methods_to_call_on_a_decorator_chain_base() {
|
347 |
+
$container = new tad_DI52_Container();
|
348 |
+
|
349 |
+
$container->bindDecorators('Four', array('FourDecoratorOne', 'FourDecoratorTwo', 'FourDecoratorThree', 'FourBase'),
|
350 |
+
array('methodOne', 'methodTwo'));
|
351 |
+
|
352 |
+
$this->assertInstanceOf('Four', $container->make('Four'));
|
353 |
+
$this->assertNotSame($container->make('Four'), $container->make('Four'));
|
354 |
+
|
355 |
+
global $one, $two;
|
356 |
+
|
357 |
+
$this->assertEquals('FourBase', $one);
|
358 |
+
$this->assertEquals('FourBase', $two);
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* @test
|
363 |
+
* it should allow binding a chain as a singleton to an interface
|
364 |
+
*/
|
365 |
+
public function it_should_allow_binding_a_chain_as_a_singleton_to_an_interface() {
|
366 |
+
$container = new tad_DI52_Container();
|
367 |
+
|
368 |
+
$container->singletonDecorators('Four',
|
369 |
+
array('FourDecoratorOne', 'FourDecoratorTwo', 'FourDecoratorThree', 'FourBase'));
|
370 |
+
|
371 |
+
$this->assertInstanceOf('Four', $container->make('Four'));
|
372 |
+
$this->assertSame($container->make('Four'), $container->make('Four'));
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* @test
|
377 |
+
* it should allow binding a complex chain to an interface
|
378 |
+
*/
|
379 |
+
public function it_should_allow_binding_a_complex_chain_to_an_interface() {
|
380 |
+
$container = new tad_DI52_Container();
|
381 |
+
|
382 |
+
$container->bind('Four', 'FourTwo');
|
383 |
+
$container->bind('One', 'ClassOne');
|
384 |
+
$container->bind('Two', 'ClassTwo');
|
385 |
+
|
386 |
+
$container->bindDecorators('Five', array('FiveDecoratorOne', 'FiveDecoratorTwo', 'FiveDecoratorThree', 'FiveBase'));
|
387 |
+
|
388 |
+
$this->assertInstanceOf('Five', $container->make('Five'));
|
389 |
+
$this->assertNotSame($container->make('Five'), $container->make('Five'));
|
390 |
+
}
|
391 |
+
|
392 |
+
/**
|
393 |
+
* @test
|
394 |
+
* it should allow binding a complex chain as a singleton to an interface
|
395 |
+
*/
|
396 |
+
public function it_should_allow_binding_a_complex_chain_as_a_singleton_to_an_interface() {
|
397 |
+
$container = new tad_DI52_Container();
|
398 |
+
|
399 |
+
$container->bind('Four', 'FourTwo');
|
400 |
+
$container->bind('One', 'ClassOne');
|
401 |
+
$container->bind('Two', 'ClassTwo');
|
402 |
+
|
403 |
+
$container->singletonDecorators('Five',
|
404 |
+
array('FiveDecoratorOne', 'FiveDecoratorTwo', 'FiveDecoratorThree', 'FiveBase'));
|
405 |
+
|
406 |
+
$this->assertInstanceOf('Five', $container->make('Five'));
|
407 |
+
$this->assertSame($container->make('Five'), $container->make('Five'));
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* @test
|
412 |
+
* it should allow tagging and resolving tagged classes
|
413 |
+
*/
|
414 |
+
public function it_should_allow_tagging_and_resolving_tagged_classes() {
|
415 |
+
$container = new tad_DI52_Container();
|
416 |
+
|
417 |
+
$container->tag(array('ClassOne', 'ClassOneOne', 'ClassOneTwo'), 'foo');
|
418 |
+
$made = $container->tagged('foo');
|
419 |
+
|
420 |
+
$this->assertInstanceOf('ClassOne', $made[0]);
|
421 |
+
$this->assertInstanceOf('ClassOneOne', $made[1]);
|
422 |
+
$this->assertInstanceOf('ClassOneTwo', $made[2]);
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* @test
|
427 |
+
* it should throw if trying to resolve non existing tag
|
428 |
+
*/
|
429 |
+
public function it_should_throw_if_trying_to_resolve_non_existing_tag() {
|
430 |
+
$container = new tad_DI52_Container();
|
431 |
+
|
432 |
+
$this->setExpectedException('RuntimeException');
|
433 |
+
|
434 |
+
$container->tagged('foo');
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* @test
|
439 |
+
* it should allow tagging mixed values
|
440 |
+
*/
|
441 |
+
public function it_should_allow_tagging_mixed_values() {
|
442 |
+
$container = new tad_DI52_Container();
|
443 |
+
|
444 |
+
$container->tag(array('ClassOne', new ClassOneOne(), 'ClassOneTwo'), 'foo');
|
445 |
+
$made = $container->tagged('foo');
|
446 |
+
|
447 |
+
$this->assertInstanceOf('ClassOne', $made[0]);
|
448 |
+
$this->assertInstanceOf('ClassOneOne', $made[1]);
|
449 |
+
$this->assertInstanceOf('ClassOneTwo', $made[2]);
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* @test
|
454 |
+
* it should call register method on on deferred service providers when registering
|
455 |
+
*/
|
456 |
+
public function it_should_call_register_method_on_on_deferred_service_providers_when_registering() {
|
457 |
+
$container = new tad_DI52_Container();
|
458 |
+
|
459 |
+
$container->register('ProviderOne');
|
460 |
+
|
461 |
+
$this->assertTrue($container->isBound('foo'));
|
462 |
+
}
|
463 |
+
|
464 |
+
/**
|
465 |
+
* @test
|
466 |
+
* it should not call register method on deferred provider on registration
|
467 |
+
*/
|
468 |
+
public function it_should_not_call_register_method_on_deferred_provider_on_registration() {
|
469 |
+
DeferredProviderTwo::reset();
|
470 |
+
|
471 |
+
$container = new tad_DI52_Container();
|
472 |
+
|
473 |
+
$container->register('DeferredProviderTwo');
|
474 |
+
|
475 |
+
$this->assertEmpty(DeferredProviderTwo::wasRegistered());
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* @test
|
480 |
+
* it should throw if deferred provider is not providing anything
|
481 |
+
*/
|
482 |
+
public function it_should_throw_if_deferred_provider_is_not_providing_anything() {
|
483 |
+
$container = new tad_DI52_Container();
|
484 |
+
|
485 |
+
$this->setExpectedException('RuntimeException');
|
486 |
+
|
487 |
+
$container->register('DeferredProviderOne');
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* @test
|
492 |
+
* it should register deferred provider when trying to resolve provided class
|
493 |
+
*/
|
494 |
+
public function it_should_register_deferred_provider_when_trying_to_resolve_provided_class() {
|
495 |
+
DeferredProviderTwo::reset();
|
496 |
+
|
497 |
+
$container = new tad_DI52_Container();
|
498 |
+
|
499 |
+
$container->register('DeferredProviderTwo');
|
500 |
+
|
501 |
+
$this->assertFalse(DeferredProviderTwo::wasRegistered());
|
502 |
+
|
503 |
+
$container->make('One');
|
504 |
+
|
505 |
+
$this->assertTrue(DeferredProviderTwo::wasRegistered());
|
506 |
+
}
|
507 |
+
|
508 |
+
/**
|
509 |
+
* @test
|
510 |
+
* it should call boot method on providers when booting the container
|
511 |
+
*/
|
512 |
+
public function it_should_call_boot_method_on_providers_when_booting_the_container() {
|
513 |
+
$container = new tad_DI52_Container();
|
514 |
+
|
515 |
+
$container->register('ProviderThree');
|
516 |
+
|
517 |
+
$this->assertFalse($container->isBound('One'));
|
518 |
+
|
519 |
+
$container->boot();
|
520 |
+
|
521 |
+
$this->assertTrue($container->isBound('One'));
|
522 |
+
}
|
523 |
+
|
524 |
+
/**
|
525 |
+
* @test
|
526 |
+
* it should call after build methods on implementations
|
527 |
+
*/
|
528 |
+
public function it_should_call_after_build_methods_on_implementations() {
|
529 |
+
$container = new tad_DI52_Container();
|
530 |
+
|
531 |
+
$container->bind('One', 'ClassOneThree', array('methodOne', 'methodTwo'));
|
532 |
+
|
533 |
+
$one = $container->make('One');
|
534 |
+
$this->assertTrue($one->oneCalled);
|
535 |
+
$this->assertTrue($one->twoCalled);
|
536 |
+
}
|
537 |
+
|
538 |
+
/**
|
539 |
+
* @test
|
540 |
+
* it should bind an object implementation as a singleton even when using bind
|
541 |
+
*/
|
542 |
+
public function it_should_bind_an_object_implementation_as_a_singleton_even_when_using_bind() {
|
543 |
+
$container = new tad_DI52_Container();
|
544 |
+
|
545 |
+
$object = new stdClass();
|
546 |
+
|
547 |
+
$container->bind('foo', $object);
|
548 |
+
|
549 |
+
$this->assertInstanceOf('stdClass', $container->make('foo'));
|
550 |
+
$this->assertSame($container->make('foo'), $container->make('foo'));
|
551 |
+
}
|
552 |
+
|
553 |
+
/**
|
554 |
+
* @test
|
555 |
+
* it should allow binding an object to an interface as a singleton and resolving it using bind
|
556 |
+
*/
|
557 |
+
public function it_should_allow_binding_an_object_to_an_interface_as_a_singleton_and_resolving_it_using_bind() {
|
558 |
+
$container = new tad_DI52_Container();
|
559 |
+
|
560 |
+
$object = new ClassOne();
|
561 |
+
|
562 |
+
$container->bind('One', $object);
|
563 |
+
|
564 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
565 |
+
$this->assertInstanceOf('ClassOne', $container['One']);
|
566 |
+
$this->assertSame($container->make('One'), $container['One']);
|
567 |
+
}
|
568 |
+
|
569 |
+
/**
|
570 |
+
* @test
|
571 |
+
* it should allow binding an object to an interface as a singleton and resolving it
|
572 |
+
*/
|
573 |
+
public function it_should_allow_binding_an_object_to_an_interface_as_a_singleton_and_resolving_it() {
|
574 |
+
$container = new tad_DI52_Container();
|
575 |
+
|
576 |
+
$object = new ClassOne();
|
577 |
+
|
578 |
+
$container->singleton('One', $object);
|
579 |
+
|
580 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
581 |
+
$this->assertInstanceOf('ClassOne', $container['One']);
|
582 |
+
$this->assertSame($container->make('One'), $container['One']);
|
583 |
+
}
|
584 |
+
|
585 |
+
/**
|
586 |
+
* @test
|
587 |
+
* it should support contextual binding of interfaces
|
588 |
+
*/
|
589 |
+
public function it_should_support_contextual_binding_of_interfaces() {
|
590 |
+
$container = new tad_DI52_Container();
|
591 |
+
|
592 |
+
$container->bind('One', 'ClassOne');
|
593 |
+
|
594 |
+
$container->when('ClassSix')
|
595 |
+
->needs('One')
|
596 |
+
->give('ClassOneOne');
|
597 |
+
|
598 |
+
$container->when('ClassSeven')
|
599 |
+
->needs('One')
|
600 |
+
->give('ClassOneTwo');
|
601 |
+
|
602 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
603 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('ClassSix')->getOne());
|
604 |
+
$this->assertInstanceOf('ClassOneTwo', $container->make('ClassSeven')->getOne());
|
605 |
+
}
|
606 |
+
|
607 |
+
/**
|
608 |
+
* @test
|
609 |
+
* it should support contextual binding of classes
|
610 |
+
*/
|
611 |
+
public function it_should_support_contextual_binding_of_classes() {
|
612 |
+
$container = new tad_DI52_Container();
|
613 |
+
|
614 |
+
$container->when('ClassSixOne')
|
615 |
+
->needs('ClassOne')
|
616 |
+
->give('ExtendingClassOneOne');
|
617 |
+
|
618 |
+
$container->when('ClassSevenOne')
|
619 |
+
->needs('ClassOne')
|
620 |
+
->give('ExtendingClassOneTwo');
|
621 |
+
|
622 |
+
$this->assertInstanceOf('ClassOne', $container->make('ClassOne'));
|
623 |
+
$this->assertInstanceOf('ExtendingClassOneOne', $container->make('ClassSixOne')->getOne());
|
624 |
+
$this->assertInstanceOf('ExtendingClassOneTwo', $container->make('ClassSevenOne')->getOne());
|
625 |
+
}
|
626 |
+
|
627 |
+
/**
|
628 |
+
* @test
|
629 |
+
* it should throw when trying to make non existing class
|
630 |
+
*/
|
631 |
+
public function it_should_throw_when_trying_to_make_non_existing_class() {
|
632 |
+
$container = new tad_DI52_Container();
|
633 |
+
|
634 |
+
$this->setExpectedException('RuntimeException');
|
635 |
+
|
636 |
+
$container->make('SomeNonExistingClass');
|
637 |
+
}
|
638 |
+
|
639 |
+
/**
|
640 |
+
* @test
|
641 |
+
* it should replace a binding when re-binding
|
642 |
+
*/
|
643 |
+
public function it_should_replace_a_binding_when_re_binding() {
|
644 |
+
$container = new tad_DI52_Container();
|
645 |
+
|
646 |
+
$container->bind('One', 'ClassOne');
|
647 |
+
|
648 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
649 |
+
|
650 |
+
$container->bind('One', 'ClassOneOne');
|
651 |
+
|
652 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
653 |
+
}
|
654 |
+
|
655 |
+
/**
|
656 |
+
* @test
|
657 |
+
* it should replace a singleton bind when re-binding a singleton binding
|
658 |
+
*/
|
659 |
+
public function it_should_replace_a_singleton_bind_when_re_binding_a_singleton_binding() {
|
660 |
+
$container = new tad_DI52_Container();
|
661 |
+
|
662 |
+
$container->singleton('One', 'ClassOne');
|
663 |
+
|
664 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
665 |
+
|
666 |
+
$container->bind('One', 'ClassOneOne');
|
667 |
+
|
668 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
669 |
+
$this->assertNotSame($container->make('One'), $container->make('One'));
|
670 |
+
}
|
671 |
+
|
672 |
+
/**
|
673 |
+
* @test
|
674 |
+
* it should replace bind with singleton if re-binding as singleton
|
675 |
+
*/
|
676 |
+
public function it_should_replace_bind_with_singleton_if_re_binding_as_singleton() {
|
677 |
+
$container = new tad_DI52_Container();
|
678 |
+
|
679 |
+
$container->singleton('One', 'ClassOne');
|
680 |
+
|
681 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
682 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
683 |
+
|
684 |
+
$container->singleton('One', 'ClassOneOne');
|
685 |
+
|
686 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
687 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
688 |
+
}
|
689 |
+
|
690 |
+
/**
|
691 |
+
* @test
|
692 |
+
* it should replace singleton with simple bind if re-binding as non singleton
|
693 |
+
*/
|
694 |
+
public function it_should_replace_singleton_with_simple_bind_if_re_binding_as_non_singleton() {
|
695 |
+
$container = new tad_DI52_Container();
|
696 |
+
|
697 |
+
$container->singleton('One', 'ClassOne');
|
698 |
+
|
699 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
700 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
701 |
+
|
702 |
+
$container->bind('One', 'ClassOneOne');
|
703 |
+
|
704 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
705 |
+
$this->assertNotSame($container->make('One'), $container->make('One'));
|
706 |
+
}
|
707 |
+
|
708 |
+
/**
|
709 |
+
* @test
|
710 |
+
* it should allow tagging non concrete implementations
|
711 |
+
*/
|
712 |
+
public function it_should_allow_tagging_non_concrete_implementations() {
|
713 |
+
$container = new tad_DI52_Container();
|
714 |
+
|
715 |
+
$container->bind('foo', 'ClassOne');
|
716 |
+
$container->bind('One', 'ClassOne');
|
717 |
+
|
718 |
+
$container->tag(array('foo', 'One'), 'bar');
|
719 |
+
|
720 |
+
$resolved = $container->tagged('bar');
|
721 |
+
|
722 |
+
$this->assertCount(2, $resolved);
|
723 |
+
$this->assertInstanceOf('ClassOne', $resolved[0]);
|
724 |
+
$this->assertInstanceOf('ClassOne', $resolved[1]);
|
725 |
+
$this->assertNotSame($resolved[0], $resolved[1]);
|
726 |
+
}
|
727 |
+
|
728 |
+
/**
|
729 |
+
* @test
|
730 |
+
* it should allow lazy building an interface binding
|
731 |
+
*/
|
732 |
+
public function it_should_allow_lazy_building_an_interface_binding() {
|
733 |
+
$container = new tad_DI52_Container();
|
734 |
+
|
735 |
+
$container->bind('Eight', 'ClassEight');
|
736 |
+
$f = $container->callback('Eight', 'methodOne');
|
737 |
+
|
738 |
+
$f();
|
739 |
+
|
740 |
+
$this->assertEquals(array('methodOne'), ClassEight::$called);
|
741 |
+
$this->assertNotSame($container->make('Eight'), $container->make('Eight'));
|
742 |
+
}
|
743 |
+
|
744 |
+
/**
|
745 |
+
* @test
|
746 |
+
* it should allow lazy building an class binding
|
747 |
+
*/
|
748 |
+
public function it_should_allow_lazy_building_an_class_binding() {
|
749 |
+
$container = new tad_DI52_Container();
|
750 |
+
|
751 |
+
$container->bind('ClassEight', 'ClassEightExtension');
|
752 |
+
$f = $container->callback('ClassEight', 'methodOne');
|
753 |
+
|
754 |
+
$f();
|
755 |
+
|
756 |
+
$this->assertEquals(array('methodOne'), ClassEightExtension::$called);
|
757 |
+
$this->assertNotSame($container->make('ClassEight'), $container->make('ClassEight'));
|
758 |
+
}
|
759 |
+
|
760 |
+
/**
|
761 |
+
* @test
|
762 |
+
* it should allow lazy building an slug binding
|
763 |
+
*/
|
764 |
+
public function it_should_allow_lazy_building_an_slug_binding() {
|
765 |
+
$container = new tad_DI52_Container();
|
766 |
+
|
767 |
+
$container->bind('foo', 'ClassEight');
|
768 |
+
$f = $container->callback('foo', 'methodOne');
|
769 |
+
|
770 |
+
$f();
|
771 |
+
|
772 |
+
$this->assertEquals(array('methodOne'), ClassEight::$called);
|
773 |
+
$this->assertNotSame($container->make('foo'), $container->make('foo'));
|
774 |
+
}
|
775 |
+
|
776 |
+
/**
|
777 |
+
* @test
|
778 |
+
* it should allow lazy binding a singleton interface binding
|
779 |
+
*/
|
780 |
+
public function it_should_allow_lazy_binding_a_singleton_interface_binding() {
|
781 |
+
$container = new tad_DI52_Container();
|
782 |
+
|
783 |
+
$container->singleton('Eight', 'ClassEight');
|
784 |
+
$f = $container->callback('Eight', 'methodOne');
|
785 |
+
|
786 |
+
$f();
|
787 |
+
|
788 |
+
$this->assertSame($container->make('Eight'), $container->make('Eight'));
|
789 |
+
$this->assertEquals(array('methodOne'), ClassEight::$called);
|
790 |
+
}
|
791 |
+
|
792 |
+
/**
|
793 |
+
* @test
|
794 |
+
* it should allow lazy binding a singleton class binding
|
795 |
+
*/
|
796 |
+
public function it_should_allow_lazy_binding_a_singleton_class_binding() {
|
797 |
+
$container = new tad_DI52_Container();
|
798 |
+
|
799 |
+
$container->singleton('ClassEight', 'ClassEightExtension');
|
800 |
+
$f = $container->callback('ClassEight', 'methodOne');
|
801 |
+
|
802 |
+
$f();
|
803 |
+
|
804 |
+
$this->assertSame($container->make('ClassEight'), $container->make('ClassEight'));
|
805 |
+
$this->assertEquals(array('methodOne'), ClassEight::$called);
|
806 |
+
}
|
807 |
+
|
808 |
+
/**
|
809 |
+
* @test
|
810 |
+
* it should allow lazy binding a singleton slug binding
|
811 |
+
*/
|
812 |
+
public function it_should_allow_lazy_binding_a_singleton_slug_binding() {
|
813 |
+
$container = new tad_DI52_Container();
|
814 |
+
|
815 |
+
$container->singleton('foo', 'ClassEight');
|
816 |
+
$f = $container->callback('foo', 'methodOne');
|
817 |
+
|
818 |
+
$f();
|
819 |
+
|
820 |
+
$this->assertSame($container->make('foo'), $container->make('foo'));
|
821 |
+
$this->assertEquals(array('methodOne'), ClassEight::$called);
|
822 |
+
}
|
823 |
+
|
824 |
+
/**
|
825 |
+
* @test
|
826 |
+
* it should pass the calling arguments to the lazy made instance
|
827 |
+
*/
|
828 |
+
public function it_should_pass_the_calling_arguments_to_the_lazy_made_instance() {
|
829 |
+
$container = new tad_DI52_Container();
|
830 |
+
|
831 |
+
$container->bind('foo', 'ClassEight');
|
832 |
+
$f = $container->callback('foo', 'methodFour');
|
833 |
+
|
834 |
+
$f('foo', 23);
|
835 |
+
$this->assertEquals(array('foo', 23), ClassEight::$calledWith);
|
836 |
+
}
|
837 |
+
|
838 |
+
/**
|
839 |
+
* @test
|
840 |
+
* it should allow lazy making a decorator binding
|
841 |
+
*/
|
842 |
+
public function it_should_allow_lazy_making_a_decorator_binding() {
|
843 |
+
$container = new tad_DI52_Container();
|
844 |
+
|
845 |
+
$container->bindDecorators('Four', array('FourDecoratorOne', 'FourDecoratorTwo', 'FourDecoratorThree', 'FourBase'));
|
846 |
+
|
847 |
+
$f = $container->callback('Four', 'methodOne');
|
848 |
+
$this->assertEquals(26, $f(3));
|
849 |
+
}
|
850 |
+
|
851 |
+
/**
|
852 |
+
* @test
|
853 |
+
* it should allow lazy making a decorator singleton binding
|
854 |
+
*/
|
855 |
+
public function it_should_allow_lazy_making_a_decorator_singleton_binding() {
|
856 |
+
$container = new tad_DI52_Container();
|
857 |
+
|
858 |
+
$container->singletonDecorators('Four',
|
859 |
+
array('FourDecoratorOne', 'FourDecoratorTwo', 'FourDecoratorThree', 'FourBase'));
|
860 |
+
|
861 |
+
$f = $container->callback('Four', 'methodOne');
|
862 |
+
$this->assertEquals(26, $f(3));
|
863 |
+
$this->assertSame($container->make('Four'), $container->make('Four'));
|
864 |
+
}
|
865 |
+
|
866 |
+
/**
|
867 |
+
* @test
|
868 |
+
* it should allow lazy making an unbound class
|
869 |
+
*/
|
870 |
+
public function it_should_allow_lazy_making_an_unbound_class() {
|
871 |
+
$container = new tad_DI52_Container();
|
872 |
+
|
873 |
+
$f = $container->callback('FourBase', 'methodThree');
|
874 |
+
|
875 |
+
$this->assertEquals(26, $f(3));
|
876 |
+
}
|
877 |
+
|
878 |
+
/**
|
879 |
+
* @test
|
880 |
+
* it should throw if trying to lazy make a non string method
|
881 |
+
*/
|
882 |
+
public function it_should_throw_if_trying_to_lazy_make_a_non_string_method() {
|
883 |
+
$container = new tad_DI52_Container();
|
884 |
+
|
885 |
+
$this->setExpectedException('RuntimeException');
|
886 |
+
|
887 |
+
$container->callback('foo', 23);
|
888 |
+
}
|
889 |
+
|
890 |
+
/**
|
891 |
+
* @test
|
892 |
+
* it should apply contextual binding to unbound classes
|
893 |
+
*/
|
894 |
+
public function it_should_apply_contextual_binding_to_unbound_classes() {
|
895 |
+
$container = new tad_DI52_Container();
|
896 |
+
|
897 |
+
$container->bind('One', 'ClassOne');
|
898 |
+
$container->bind('Two', 'ClassTwo');
|
899 |
+
$container->when('ClassTwoOne')->needs('ClassOne')->give('ExtendingClassOneOne');
|
900 |
+
|
901 |
+
$resolved = $container->make('ClassTwoOne');
|
902 |
+
$this->assertInstanceOf('ExtendingClassOneOne', $resolved->getOne());
|
903 |
+
}
|
904 |
+
|
905 |
+
/**
|
906 |
+
* @test
|
907 |
+
* it should allow lazy making contextually bound interfaces
|
908 |
+
*/
|
909 |
+
public function it_should_allow_lazy_making_contextually_bound_interfaces() {
|
910 |
+
$container = new tad_DI52_Container();
|
911 |
+
|
912 |
+
$container->bind('One', 'ClassOne');
|
913 |
+
$container->bind('Two', 'ClassTwo');
|
914 |
+
$container->when('ClassTwoOne')->needs('ClassOne')->give('ExtendingClassOneOne');
|
915 |
+
|
916 |
+
$f = $container->callback('ClassTwoOne', 'getOne');
|
917 |
+
|
918 |
+
$this->assertInstanceOf('ExtendingClassOneOne', $f());
|
919 |
+
}
|
920 |
+
|
921 |
+
/**
|
922 |
+
* @test
|
923 |
+
* it should return same instance when lazy making contextually bound singleton
|
924 |
+
*/
|
925 |
+
public function it_should_return_same_instance_when_lazy_making_contextually_bound_singleton() {
|
926 |
+
$container = new tad_DI52_Container();
|
927 |
+
|
928 |
+
$container->bind('One', 'ClassOne');
|
929 |
+
$container->bind('Two', 'ClassTwo');
|
930 |
+
$container->singleton('two.one', 'ClassTwoOne');
|
931 |
+
$container->when('two.one')->needs('ClassOne')->give('ExtendingClassOneOne');
|
932 |
+
|
933 |
+
$f = $container->callback('two.one', 'getOne');
|
934 |
+
|
935 |
+
$this->assertInstanceOf('ExtendingClassOneOne', $f());
|
936 |
+
$this->assertSame($f(), $f());
|
937 |
+
}
|
938 |
+
|
939 |
+
/**
|
940 |
+
* @test
|
941 |
+
* it should not build lazy made object immediately
|
942 |
+
*/
|
943 |
+
public function it_should_not_build_lazy_made_object_immediately() {
|
944 |
+
$container = new tad_DI52_Container();
|
945 |
+
|
946 |
+
ClassNine::reset();
|
947 |
+
$f = $container->callback('ClassNine', 'methodOne');
|
948 |
+
|
949 |
+
global $nine;
|
950 |
+
$this->assertEmpty($nine);
|
951 |
+
|
952 |
+
$f();
|
953 |
+
|
954 |
+
$this->assertEquals('called', $nine);
|
955 |
+
}
|
956 |
+
|
957 |
+
/**
|
958 |
+
* @test
|
959 |
+
* it should mark a deferred implementation as bound before registering the service provider
|
960 |
+
*/
|
961 |
+
public function it_should_mark_a_deferred_implementation_as_bound_before_registering_the_service_provider() {
|
962 |
+
DeferredProviderTwo::reset();
|
963 |
+
|
964 |
+
$container = new tad_DI52_Container();
|
965 |
+
|
966 |
+
$container->register('DeferredProviderTwo');
|
967 |
+
|
968 |
+
$this->assertTrue($container->isBound('One'));
|
969 |
+
}
|
970 |
+
|
971 |
+
/**
|
972 |
+
* @test
|
973 |
+
* it should allow getting a callback to build an object
|
974 |
+
*/
|
975 |
+
public function it_should_allow_getting_a_callback_to_build_an_object() {
|
976 |
+
ClassTen::reset();
|
977 |
+
|
978 |
+
$container = new tad_DI52_Container();
|
979 |
+
|
980 |
+
$f = $container->instance('ClassTen', array('foo', 'baz', 'bar'));
|
981 |
+
|
982 |
+
$this->assertEquals(0, ClassTen::$builtTimes);
|
983 |
+
|
984 |
+
$instance1 = $f();
|
985 |
+
|
986 |
+
$this->assertEquals(1, ClassTen::$builtTimes);
|
987 |
+
$this->assertEquals('foo', $instance1->getVarOne());
|
988 |
+
$this->assertEquals('baz', $instance1->getVarTwo());
|
989 |
+
$this->assertEquals('bar', $instance1->getVarThree());
|
990 |
+
|
991 |
+
$instance2 = $f();
|
992 |
+
|
993 |
+
$this->assertEquals(2, ClassTen::$builtTimes);
|
994 |
+
$this->assertEquals('foo', $instance2->getVarOne());
|
995 |
+
$this->assertEquals('baz', $instance2->getVarTwo());
|
996 |
+
$this->assertEquals('bar', $instance2->getVarThree());
|
997 |
+
|
998 |
+
$instance3 = $f();
|
999 |
+
|
1000 |
+
$this->assertEquals(3, ClassTen::$builtTimes);
|
1001 |
+
$this->assertEquals('foo', $instance3->getVarOne());
|
1002 |
+
$this->assertEquals('baz', $instance3->getVarTwo());
|
1003 |
+
$this->assertEquals('bar', $instance3->getVarThree());
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
/**
|
1007 |
+
* @test
|
1008 |
+
* it should allow getting a callback to build an object with scalar and object dependencies
|
1009 |
+
*/
|
1010 |
+
public function it_should_allow_getting_a_callback_to_build_an_object_with_scalar_and_object_dependencies() {
|
1011 |
+
ClassEleven::reset();
|
1012 |
+
|
1013 |
+
$container = new tad_DI52_Container();
|
1014 |
+
|
1015 |
+
$container->bind('One', 'ClassOneTwo');
|
1016 |
+
$container->bind('Two', 'ClassTwo');
|
1017 |
+
|
1018 |
+
$f = $container->instance('ClassEleven', array('ClassOne', 'Two', 'bar'));
|
1019 |
+
|
1020 |
+
$this->assertEquals(0, ClassEleven::$builtTimes);
|
1021 |
+
|
1022 |
+
$instance1 = $f();
|
1023 |
+
|
1024 |
+
$this->assertEquals(1, ClassEleven::$builtTimes);
|
1025 |
+
$this->assertInstanceOf('ClassOne', $instance1->getVarOne());
|
1026 |
+
$this->assertInstanceOf('ClassTwo', $instance1->getVarTwo());
|
1027 |
+
$this->assertInstanceOf('ClassOneTwo', $instance1->getVarTwo()->getOne());
|
1028 |
+
$this->assertEquals('bar', $instance1->getVarThree());
|
1029 |
+
|
1030 |
+
$instance2 = $f();
|
1031 |
+
|
1032 |
+
$this->assertEquals(2, ClassEleven::$builtTimes);
|
1033 |
+
$this->assertInstanceOf('ClassOne', $instance2->getVarOne());
|
1034 |
+
$this->assertInstanceOf('ClassTwo', $instance2->getVarTwo());
|
1035 |
+
$this->assertInstanceOf('ClassOneTwo', $instance2->getVarTwo()->getOne());
|
1036 |
+
$this->assertEquals('bar', $instance2->getVarThree());
|
1037 |
+
|
1038 |
+
$instance3 = $f();
|
1039 |
+
|
1040 |
+
$this->assertEquals(3, ClassEleven::$builtTimes);
|
1041 |
+
$this->assertInstanceOf('ClassOne', $instance3->getVarOne());
|
1042 |
+
$this->assertInstanceOf('ClassTwo', $instance3->getVarTwo());
|
1043 |
+
$this->assertInstanceOf('ClassOneTwo', $instance3->getVarTwo()->getOne());
|
1044 |
+
$this->assertEquals('bar', $instance3->getVarThree());
|
1045 |
+
}
|
1046 |
+
|
1047 |
+
/**
|
1048 |
+
* @test
|
1049 |
+
* it should instance using bound implementations
|
1050 |
+
*/
|
1051 |
+
public function it_should_instance_using_bound_implementations() {
|
1052 |
+
ClassTwelve::reset();
|
1053 |
+
|
1054 |
+
$container = new tad_DI52_Container();
|
1055 |
+
|
1056 |
+
$container->bind('One', 'ClassOne');
|
1057 |
+
|
1058 |
+
$f = $container->instance('ClassTwelve', array('One'));
|
1059 |
+
|
1060 |
+
$instance1 = $f();
|
1061 |
+
|
1062 |
+
$this->assertEquals(1, ClassTwelve::$builtTimes);
|
1063 |
+
$this->assertInstanceOf('ClassOne', $instance1->getVarOne());
|
1064 |
+
}
|
1065 |
+
|
1066 |
+
/**
|
1067 |
+
* @test
|
1068 |
+
* it should allow overriding bound implementations in instance method
|
1069 |
+
*/
|
1070 |
+
public function it_should_allow_overriding_bound_implementations_in_instance_method() {
|
1071 |
+
ClassTwelve::reset();
|
1072 |
+
|
1073 |
+
$container = new tad_DI52_Container();
|
1074 |
+
|
1075 |
+
$container->bind('One', 'ClassOne');
|
1076 |
+
|
1077 |
+
$f = $container->instance('ClassTwelve', array('ClassOneOne'));
|
1078 |
+
|
1079 |
+
$instance1 = $f();
|
1080 |
+
|
1081 |
+
$this->assertEquals(1, ClassTwelve::$builtTimes);
|
1082 |
+
$this->assertInstanceOf('ClassOneOne', $instance1->getVarOne());
|
1083 |
+
}
|
1084 |
+
|
1085 |
+
/**
|
1086 |
+
* @test
|
1087 |
+
* it should allow referring bound slugs in instance method
|
1088 |
+
*/
|
1089 |
+
public function it_should_allow_referring_bound_slugs_in_instance_method() {
|
1090 |
+
ClassTwelve::reset();
|
1091 |
+
|
1092 |
+
$container = new tad_DI52_Container();
|
1093 |
+
|
1094 |
+
$container->bind('foo', 'ClassOne');
|
1095 |
+
|
1096 |
+
$f = $container->instance('ClassTwelve', array('foo'));
|
1097 |
+
|
1098 |
+
$instance1 = $f();
|
1099 |
+
|
1100 |
+
$this->assertEquals(1, ClassTwelve::$builtTimes);
|
1101 |
+
$this->assertInstanceOf('ClassOne', $instance1->getVarOne());
|
1102 |
+
}
|
1103 |
+
|
1104 |
+
/**
|
1105 |
+
* @test
|
1106 |
+
* it should use bound singletons as singletons in instance methods
|
1107 |
+
*/
|
1108 |
+
public function it_should_use_bound_singletons_as_singletons_in_instance_methods() {
|
1109 |
+
ClassTwelve::reset();
|
1110 |
+
|
1111 |
+
$container = new tad_DI52_Container();
|
1112 |
+
|
1113 |
+
$container->singleton('One', 'ClassOne');
|
1114 |
+
|
1115 |
+
$f = $container->instance('ClassTwelve', array('One'));
|
1116 |
+
|
1117 |
+
$this->assertInstanceOf('ClassOne', $f()->getVarOne());
|
1118 |
+
$this->assertSame($f()->getVarOne(), $f()->getVarOne());
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
/**
|
1122 |
+
* @test
|
1123 |
+
* it should resolve bound objects in instance method
|
1124 |
+
*/
|
1125 |
+
public function it_should_resolve_bound_objects_in_instance_method() {
|
1126 |
+
ClassTwelve::reset();
|
1127 |
+
|
1128 |
+
$container = new tad_DI52_Container();
|
1129 |
+
|
1130 |
+
$one = new ClassOne;
|
1131 |
+
$container->singleton('One', $one);
|
1132 |
+
|
1133 |
+
$f = $container->instance('ClassTwelve', array('One'));
|
1134 |
+
|
1135 |
+
$this->assertInstanceOf('ClassOne', $f()->getVarOne());
|
1136 |
+
$this->assertSame($one, $f()->getVarOne());
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
/**
|
1140 |
+
* @test
|
1141 |
+
* it should allow binding an instance in the container
|
1142 |
+
*/
|
1143 |
+
public function it_should_allow_binding_an_instance_in_the_container() {
|
1144 |
+
$container = new tad_DI52_Container();
|
1145 |
+
|
1146 |
+
$container->bind('One', $container->instance('ClassOneTwo', array('sudo-foo')));
|
1147 |
+
|
1148 |
+
$this->assertInstanceOf('ClassOneTwo', $container->make('One'));
|
1149 |
+
$this->assertEquals('sudo-foo', $container->make('One')->getFoo());
|
1150 |
+
$this->assertNotSame($container->make('One'), $container->make('One'));
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
/**
|
1154 |
+
* @test
|
1155 |
+
* it should allow binding an instance as a singleton in the container
|
1156 |
+
*/
|
1157 |
+
public function it_should_allow_binding_an_instance_as_a_singleton_in_the_container() {
|
1158 |
+
$container = new tad_DI52_Container();
|
1159 |
+
|
1160 |
+
$container->singleton('One', $container->instance('ClassOneTwo', array('sudo-foo')));
|
1161 |
+
|
1162 |
+
$this->assertInstanceOf('ClassOneTwo', $container->make('One'));
|
1163 |
+
$this->assertEquals('sudo-foo', $container->make('One')->getFoo());
|
1164 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
1165 |
+
}
|
1166 |
+
|
1167 |
+
/**
|
1168 |
+
* @test
|
1169 |
+
* it should build the instance with the container if not specifying arguments
|
1170 |
+
*/
|
1171 |
+
public function it_should_build_the_instance_with_the_container_if_not_specifying_arguments() {
|
1172 |
+
$container = new tad_DI52_Container();
|
1173 |
+
|
1174 |
+
$container->bind('One', 'ClassOneTwo');
|
1175 |
+
$f = $container->instance('One');
|
1176 |
+
|
1177 |
+
$this->assertInstanceOf('ClassOneTwo', $f());
|
1178 |
+
$this->assertEquals('bar', $f()->getFoo());
|
1179 |
+
$this->assertNotSame($f(), $f());
|
1180 |
+
}
|
1181 |
+
|
1182 |
+
/**
|
1183 |
+
* @test
|
1184 |
+
* it should use container binding settings when instancing
|
1185 |
+
*/
|
1186 |
+
public function it_should_use_container_binding_settings_when_instancing() {
|
1187 |
+
$container = new tad_DI52_Container();
|
1188 |
+
|
1189 |
+
$container->singleton('One', 'ClassOneTwo');
|
1190 |
+
$f = $container->instance('One');
|
1191 |
+
|
1192 |
+
$this->assertInstanceOf('ClassOneTwo', $f());
|
1193 |
+
$this->assertEquals('bar', $f()->getFoo());
|
1194 |
+
$this->assertSame($f(), $f());
|
1195 |
+
}
|
1196 |
+
|
1197 |
+
/**
|
1198 |
+
* @test
|
1199 |
+
* it should fetch correct objects when re-binding
|
1200 |
+
*/
|
1201 |
+
public function it_should_fetch_correct_objects_when_re_binding() {
|
1202 |
+
$container = new tad_DI52_Container();
|
1203 |
+
|
1204 |
+
$container->bind('One', 'ClassOneOne');
|
1205 |
+
|
1206 |
+
$firstInstance = $container->make('ClassTwo');
|
1207 |
+
|
1208 |
+
$this->assertInstanceOf('ClassOneOne', $firstInstance->getOne());
|
1209 |
+
|
1210 |
+
$container->bind('One', 'ClassOne');
|
1211 |
+
|
1212 |
+
$secondInstance = $container->make('ClassTwo');
|
1213 |
+
|
1214 |
+
$this->assertInstanceOf('ClassOne', $secondInstance->getOne());
|
1215 |
+
}
|
1216 |
+
|
1217 |
+
/**
|
1218 |
+
* @test
|
1219 |
+
* it should allow re-binding objects
|
1220 |
+
*/
|
1221 |
+
public function it_should_allow_re_binding_objects() {
|
1222 |
+
$container = new tad_DI52_Container();
|
1223 |
+
|
1224 |
+
$container->bind('One', new ClassOneOne());
|
1225 |
+
|
1226 |
+
$firstInstance = $container->make('ClassTwo');
|
1227 |
+
|
1228 |
+
$this->assertInstanceOf('ClassOneOne', $firstInstance->getOne());
|
1229 |
+
|
1230 |
+
$container->bind('One', new ClassOne());
|
1231 |
+
|
1232 |
+
$secondInstance = $container->make('ClassTwo');
|
1233 |
+
|
1234 |
+
$this->assertInstanceOf('ClassOne', $secondInstance->getOne());
|
1235 |
+
}
|
1236 |
+
|
1237 |
+
/**
|
1238 |
+
* @test
|
1239 |
+
* it should allow for built objects to passed to instance
|
1240 |
+
*/
|
1241 |
+
public function it_should_allow_for_built_objects_to_passed_to_instance() {
|
1242 |
+
$container = new tad_DI52_Container();
|
1243 |
+
|
1244 |
+
$obj = new ClassFour('foo');
|
1245 |
+
$instance = $container->instance($obj);
|
1246 |
+
|
1247 |
+
$this->assertInstanceOf('ClassFour', $instance());
|
1248 |
+
}
|
1249 |
+
|
1250 |
+
/**
|
1251 |
+
* @test
|
1252 |
+
* it should allow for built objects to be passed in callback
|
1253 |
+
*/
|
1254 |
+
public function it_should_allow_for_built_objects_to_be_passed_in_callback() {
|
1255 |
+
$container = new tad_DI52_Container();
|
1256 |
+
|
1257 |
+
$obj = new ClassFour('foo');
|
1258 |
+
$callback = $container->callback($obj, 'methodTwo');
|
1259 |
+
|
1260 |
+
$this->assertEquals(23, $callback());
|
1261 |
+
}
|
1262 |
+
|
1263 |
+
/**
|
1264 |
+
* @test
|
1265 |
+
* it should allow for callback to be fed to instance
|
1266 |
+
*/
|
1267 |
+
public function it_should_allow_for_callback_to_be_fed_to_instance() {
|
1268 |
+
$container = new tad_DI52_Container();
|
1269 |
+
|
1270 |
+
$callback = $container->callback('Factory', 'build');
|
1271 |
+
|
1272 |
+
$instance = $container->instance($callback);
|
1273 |
+
|
1274 |
+
$this->assertInstanceOf('ClassOne', $instance());
|
1275 |
+
}
|
1276 |
+
|
1277 |
+
/**
|
1278 |
+
* @test
|
1279 |
+
* it should allow for instance to be fed to callback
|
1280 |
+
*/
|
1281 |
+
public function it_should_allow_for_instance_to_be_fed_to_callback() {
|
1282 |
+
$container = new tad_DI52_Container();
|
1283 |
+
|
1284 |
+
$instance = $container->instance('Factory');
|
1285 |
+
|
1286 |
+
$callback = $container->callback($instance, 'build');
|
1287 |
+
|
1288 |
+
$this->assertInstanceOf('ClassOne', $callback());
|
1289 |
+
}
|
1290 |
+
|
1291 |
+
/**
|
1292 |
+
* @test
|
1293 |
+
* it should allow registering instance callbacks on class names
|
1294 |
+
*/
|
1295 |
+
public function it_should_allow_registering_instance_callbacks_on_class_names() {
|
1296 |
+
$container = new tad_DI52_Container();
|
1297 |
+
|
1298 |
+
$instance = $container->instance('ClassThirteen');
|
1299 |
+
|
1300 |
+
$this->assertInstanceOf('ClassThirteen', $instance());
|
1301 |
+
}
|
1302 |
+
|
1303 |
+
/**
|
1304 |
+
* @test
|
1305 |
+
* it should allow registering instance callbacks on classes with constructor arguments
|
1306 |
+
*/
|
1307 |
+
public function it_should_allow_registering_instance_callbacks_on_classes_with_constructor_arguments() {
|
1308 |
+
$container = new tad_DI52_Container();
|
1309 |
+
$container->bind('One', 'ClassOne');
|
1310 |
+
|
1311 |
+
$instance = $container->instance('ClassFifteen');
|
1312 |
+
|
1313 |
+
$this->assertInstanceOf('ClassFifteen', $instance());
|
1314 |
+
}
|
1315 |
+
|
1316 |
+
/**
|
1317 |
+
* @test
|
1318 |
+
* it should allow registering callback callbacks on class names
|
1319 |
+
*/
|
1320 |
+
public function it_should_allow_registering_callback_callbacks_on_class_names() {
|
1321 |
+
$container = new tad_DI52_Container();
|
1322 |
+
|
1323 |
+
$callback = $container->callback('ClassThirteen', 'doSomething');
|
1324 |
+
|
1325 |
+
$this->assertEquals('IDidSomething', $callback());
|
1326 |
+
}
|
1327 |
+
|
1328 |
+
/**
|
1329 |
+
* @test
|
1330 |
+
* it should allow registering callback callbacks on classes with constructor arguments
|
1331 |
+
*/
|
1332 |
+
public function it_should_allow_registering_callback_callbacks_on_classes_with_constructor_arguments() {
|
1333 |
+
$container = new tad_DI52_Container();
|
1334 |
+
$container->bind('One', 'ClassOne');
|
1335 |
+
|
1336 |
+
$callback = $container->callback('ClassFifteen', 'doSomething');
|
1337 |
+
|
1338 |
+
$this->assertEquals('IDidSomething', $callback());
|
1339 |
+
}
|
1340 |
+
|
1341 |
+
/**
|
1342 |
+
* It should return an interface argument default value if available and the interface is not bound
|
1343 |
+
*
|
1344 |
+
* @test
|
1345 |
+
*/
|
1346 |
+
public function it_should_return_an_interface_argument_default_value_if_available_and_the_interface_is_not_bound() {
|
1347 |
+
$reflectionMethod = new ReflectionMethod('TestInterface','apiMethodOne');
|
1348 |
+
$params = $reflectionMethod->getParameters();
|
1349 |
+
$reflectionParameter = reset($params);
|
1350 |
+
|
1351 |
+
$container = new tad_DI52_Container();
|
1352 |
+
$value = $container->_getParameter($reflectionParameter);
|
1353 |
+
|
1354 |
+
$this->assertEquals(23, $value);
|
1355 |
+
}
|
1356 |
+
|
1357 |
+
/**
|
1358 |
+
* It should throw an exception when trying to resolve unbound interface parameter with no default value
|
1359 |
+
*
|
1360 |
+
* @test
|
1361 |
+
*/
|
1362 |
+
public function it_should_throw_an_exception_when_trying_to_resolve_unbound_interface_parameter_with_no_default_value() {
|
1363 |
+
$reflectionMethod = new ReflectionMethod('TestInterface','apiMethodTwo');
|
1364 |
+
$params = $reflectionMethod->getParameters();
|
1365 |
+
$reflectionParameter = reset($params);
|
1366 |
+
|
1367 |
+
$this->setExpectedException('ReflectionException');
|
1368 |
+
|
1369 |
+
$container = new tad_DI52_Container();
|
1370 |
+
$container->_getParameter($reflectionParameter);
|
1371 |
+
}
|
1372 |
+
|
1373 |
+
/**
|
1374 |
+
* It should build not registered class dependencies anew each time
|
1375 |
+
*
|
1376 |
+
* @test
|
1377 |
+
*/
|
1378 |
+
public function it_should_build_not_registered_class_dependencies_anew_each_time() {
|
1379 |
+
$container = new tad_DI52_Container();
|
1380 |
+
|
1381 |
+
$d1 = $container->make('Depending');
|
1382 |
+
$d2 = $container->make('Depending');
|
1383 |
+
|
1384 |
+
$this->assertNotSame($d1,$d2);
|
1385 |
+
$this->assertNotSame($d1->getDependency(),$d2->getDependency());
|
1386 |
+
}
|
1387 |
+
|
1388 |
+
/**
|
1389 |
+
* It should return different callbacks for different input objects
|
1390 |
+
*
|
1391 |
+
* @test
|
1392 |
+
*/
|
1393 |
+
public function should_return_different_callbacks_for_different_input_objects() {
|
1394 |
+
$o1 = new TestObject(23);
|
1395 |
+
$o2 = new TestObject(89);
|
1396 |
+
|
1397 |
+
$container = new tad_DI52_Container();
|
1398 |
+
|
1399 |
+
$o1Callback = $container->callback($o1,'getNum');
|
1400 |
+
$o2Callback = $container->callback($o2,'getNum');
|
1401 |
+
|
1402 |
+
$this->assertNotSame($o1Callback,$o2Callback);
|
1403 |
+
$this->assertEquals(23,$o1Callback());
|
1404 |
+
$this->assertEquals(89,$o2Callback());
|
1405 |
+
}
|
1406 |
+
|
1407 |
+
/**
|
1408 |
+
* It should return same callback when created for same object instance
|
1409 |
+
*
|
1410 |
+
* @test
|
1411 |
+
*/
|
1412 |
+
public function should_return_same_callback_when_created_for_same_object_instance() {
|
1413 |
+
$this->markTestSkipped('Not a feature yet.');
|
1414 |
+
|
1415 |
+
$o1 = new TestObject(23);
|
1416 |
+
|
1417 |
+
$container = new tad_DI52_Container();
|
1418 |
+
|
1419 |
+
$callback1 = $container->callback($o1,'getNum');
|
1420 |
+
$callback2 = $container->callback($o1,'getNum');
|
1421 |
+
|
1422 |
+
$this->assertSame($callback1,$callback2);
|
1423 |
+
$this->assertEquals(23,$callback1());
|
1424 |
+
$this->assertEquals(89,$callback2());
|
1425 |
+
}
|
1426 |
+
|
1427 |
+
/**
|
1428 |
+
* It should return the same callback when building for same class and static method
|
1429 |
+
*
|
1430 |
+
* @test
|
1431 |
+
*/
|
1432 |
+
public function should_return_the_same_callback_when_building_for_same_class_and_static_method() {
|
1433 |
+
$container = new tad_DI52_Container();
|
1434 |
+
|
1435 |
+
$callback1 = $container->callback('TestObject','staticOne');
|
1436 |
+
$callback2 = $container->callback('TestObject','staticOne');
|
1437 |
+
$callback3 = $container->callback('TestObject','staticTwo');
|
1438 |
+
$callback4 = $container->callback('TestObject','staticTwo');
|
1439 |
+
|
1440 |
+
$this->assertSame($callback1,$callback2);
|
1441 |
+
$this->assertSame($callback3,$callback4);
|
1442 |
+
$this->assertNotSame($callback1,$callback3);
|
1443 |
+
$this->assertEquals('static one',$callback1());
|
1444 |
+
$this->assertEquals('static one',$callback2());
|
1445 |
+
$this->assertEquals('static two',$callback3());
|
1446 |
+
$this->assertEquals('static two',$callback4());
|
1447 |
+
}
|
1448 |
+
}
|
vendor/lucatume/di52/tests/52-compat/autoloadTest.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class autoloadTest extends PHPUnit_Framework_TestCase
|
5 |
+
{
|
6 |
+
|
7 |
+
public function projectClasses()
|
8 |
+
{
|
9 |
+
$classes = glob(dirname(dirname(dirname(__FILE__))) . '/src/tad/DI52/*.php');
|
10 |
+
$data = array();
|
11 |
+
foreach ($classes as $class) {
|
12 |
+
$name = 'tad_DI52_' . basename($class, '.php');
|
13 |
+
if ($name === 'closuresSupport') {
|
14 |
+
continue;
|
15 |
+
}
|
16 |
+
$data[] = array($name, $class);
|
17 |
+
}
|
18 |
+
|
19 |
+
return $data;
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Autoload classes
|
24 |
+
*
|
25 |
+
* @dataProvider projectClasses
|
26 |
+
*/
|
27 |
+
public function test_autoload_classes($className, $classPath)
|
28 |
+
{
|
29 |
+
include_once dirname(dirname(dirname(__FILE__))) . '/autoload.php';
|
30 |
+
$this->assertEquals($classPath, di52_findFile($className));
|
31 |
+
}
|
32 |
+
}
|
vendor/lucatume/di52/tests/53-above/Container53CompatTest.php
ADDED
@@ -0,0 +1,811 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Container53CompatTest extends \PHPUnit_Framework_TestCase
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @test
|
7 |
+
* it should allow setting a closure var on the container
|
8 |
+
*/
|
9 |
+
public function it_should_allow_setting_a_closure_var_on_the_container()
|
10 |
+
{
|
11 |
+
$container = new tad_DI52_Container();
|
12 |
+
|
13 |
+
$closure = function ($value) {
|
14 |
+
return $value + 1;
|
15 |
+
};
|
16 |
+
|
17 |
+
$container->setVar('foo', $container->protect($closure));
|
18 |
+
|
19 |
+
$this->assertEquals($closure, $container->getVar('foo'));
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @test
|
24 |
+
* it should allow setting a closure as a variable using the ArrayAccess API
|
25 |
+
*/
|
26 |
+
public function it_should_allow_setting_a_closure_as_a_variable_using_the_array_access_api()
|
27 |
+
{
|
28 |
+
$container = new tad_DI52_Container();
|
29 |
+
|
30 |
+
$closure = function ($value) {
|
31 |
+
return $value + 1;
|
32 |
+
};
|
33 |
+
|
34 |
+
$container['foo'] = $container->protect($closure);
|
35 |
+
|
36 |
+
$this->assertEquals($closure, $container['foo']);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @test
|
41 |
+
* it should allow binding a closure as implementation of an interface
|
42 |
+
*/
|
43 |
+
public function it_should_allow_binding_a_closure_as_implementation_of_an_interface()
|
44 |
+
{
|
45 |
+
$container = new tad_DI52_Container();
|
46 |
+
|
47 |
+
$container->bind(
|
48 |
+
'One', function () {
|
49 |
+
return new ClassOne();
|
50 |
+
}
|
51 |
+
);
|
52 |
+
|
53 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @test
|
58 |
+
* it should pass the container as parameter to the closure implementation
|
59 |
+
*/
|
60 |
+
public function it_should_pass_the_container_as_parameter_to_the_closure_implementation()
|
61 |
+
{
|
62 |
+
$container = new tad_DI52_Container();
|
63 |
+
|
64 |
+
$passedContainer = null;
|
65 |
+
|
66 |
+
$container->bind(
|
67 |
+
'One', function ($container) use (&$passedContainer) {
|
68 |
+
$passedContainer = $container;
|
69 |
+
return new ClassOne();
|
70 |
+
}
|
71 |
+
);
|
72 |
+
|
73 |
+
$container->make('One');
|
74 |
+
|
75 |
+
$this->assertSame($container, $passedContainer);
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @test
|
80 |
+
* it should allow binding a closure to a string slug
|
81 |
+
*/
|
82 |
+
public function it_should_allow_binding_a_closure_to_a_string_slug()
|
83 |
+
{
|
84 |
+
$container = new tad_DI52_Container();
|
85 |
+
|
86 |
+
$container->bind(
|
87 |
+
'foo.bar', function () {
|
88 |
+
return 23;
|
89 |
+
}
|
90 |
+
);
|
91 |
+
|
92 |
+
$this->assertEquals(23, $container->make('foo.bar'));
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @test
|
97 |
+
* it should allow binding a closure to an interface as a singletong
|
98 |
+
*/
|
99 |
+
public function it_should_allow_binding_a_closure_to_an_interface_as_a_singletong()
|
100 |
+
{
|
101 |
+
$container = new tad_DI52_Container();
|
102 |
+
|
103 |
+
$container->singleton(
|
104 |
+
'One', function () {
|
105 |
+
return new ClassOne();
|
106 |
+
}
|
107 |
+
);
|
108 |
+
|
109 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
110 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @test
|
115 |
+
* it should allow binding a closure to a string slug as a singleton
|
116 |
+
*/
|
117 |
+
public function it_should_allow_binding_a_closure_to_a_string_slug_as_a_singleton()
|
118 |
+
{
|
119 |
+
$container = new tad_DI52_Container();
|
120 |
+
|
121 |
+
$container->singleton(
|
122 |
+
'foo.one', function () {
|
123 |
+
return new ClassOne();
|
124 |
+
}
|
125 |
+
);
|
126 |
+
|
127 |
+
$this->assertInstanceOf('ClassOne', $container->make('foo.one'));
|
128 |
+
$this->assertSame($container->make('foo.one'), $container->make('foo.one'));
|
129 |
+
}
|
130 |
+
|
131 |
+
public function namespacedKeysAndValues()
|
132 |
+
{
|
133 |
+
return array(
|
134 |
+
array('Acme\One', 'Acme\ClassOne'),
|
135 |
+
array('\Acme\One', '\Acme\ClassOne'),
|
136 |
+
array('Acme\One', '\Acme\ClassOne'),
|
137 |
+
array('\Acme\One', 'Acme\ClassOne'),
|
138 |
+
array('foo.one', '\Acme\ClassOne'),
|
139 |
+
array('foo.one', 'Acme\ClassOne'),
|
140 |
+
);
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @test
|
145 |
+
* it should allow binding fully namespaced interfaces and classes with or without leading slash
|
146 |
+
* @dataProvider namespacedKeysAndValues
|
147 |
+
*/
|
148 |
+
public function it_should_allow_binding_fully_namespaced_interfaces_and_classes_with_or_without_leading_slash(
|
149 |
+
$key,
|
150 |
+
$value
|
151 |
+
) {
|
152 |
+
$container = new tad_DI52_Container();
|
153 |
+
|
154 |
+
$container->bind($key, $value);
|
155 |
+
|
156 |
+
$this->assertInstanceOf('\\' . ltrim($value, '\\'), $container->make($key));
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @test
|
161 |
+
* it should allow tagging mixed values
|
162 |
+
*/
|
163 |
+
public function it_should_allow_tagging_mixed_values()
|
164 |
+
{
|
165 |
+
$container = new tad_DI52_Container();
|
166 |
+
|
167 |
+
$container->tag(
|
168 |
+
array(
|
169 |
+
'ClassOne',
|
170 |
+
new ClassOneOne(),
|
171 |
+
function ($container) {
|
172 |
+
return $container->make('ClassOneTwo');
|
173 |
+
}
|
174 |
+
), 'foo'
|
175 |
+
);
|
176 |
+
$made = $container->tagged('foo');
|
177 |
+
|
178 |
+
$this->assertInstanceOf('ClassOne', $made[0]);
|
179 |
+
$this->assertInstanceOf('ClassOneOne', $made[1]);
|
180 |
+
$this->assertInstanceOf('ClassOneTwo', $made[2]);
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* @test
|
185 |
+
* it should allow contextual binding of closures
|
186 |
+
*/
|
187 |
+
public function it_should_allow_contextual_binding_of_closures()
|
188 |
+
{
|
189 |
+
$container = new tad_DI52_Container();
|
190 |
+
|
191 |
+
$container->when('ClassSixOne')
|
192 |
+
->needs('ClassOne')
|
193 |
+
->give(
|
194 |
+
function ($container) {
|
195 |
+
return $container->make('ExtendingClassOneOne');
|
196 |
+
}
|
197 |
+
);
|
198 |
+
|
199 |
+
$container->when('ClassSevenOne')
|
200 |
+
->needs('ClassOne')
|
201 |
+
->give(
|
202 |
+
function ($container) {
|
203 |
+
return $container->make('ExtendingClassOneTwo');
|
204 |
+
}
|
205 |
+
);
|
206 |
+
|
207 |
+
$this->assertInstanceOf('ClassOne', $container->make('ClassOne'));
|
208 |
+
$this->assertInstanceOf('ExtendingClassOneOne', $container->make('ClassSixOne')->getOne());
|
209 |
+
$this->assertInstanceOf('ExtendingClassOneTwo', $container->make('ClassSevenOne')->getOne());
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* @test
|
214 |
+
* it should call a closure when bound to an offset in ArrayAccess API
|
215 |
+
*/
|
216 |
+
public function it_should_call_a_closure_when_bound_to_an_offset_in_array_access_api()
|
217 |
+
{
|
218 |
+
$container = new tad_DI52_Container();
|
219 |
+
|
220 |
+
$container['foo'] = function () {
|
221 |
+
return 'bar';
|
222 |
+
};
|
223 |
+
|
224 |
+
$this->assertEquals('bar', $container['foo']);
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* @test
|
229 |
+
* it should replace a binding when re-binding
|
230 |
+
*/
|
231 |
+
public function it_should_replace_a_binding_when_re_binding()
|
232 |
+
{
|
233 |
+
$container = new tad_DI52_Container();
|
234 |
+
|
235 |
+
$container->bind(
|
236 |
+
'One', function ($container) {
|
237 |
+
return $container->make('ClassOne');
|
238 |
+
}
|
239 |
+
);
|
240 |
+
|
241 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
242 |
+
|
243 |
+
$container->bind(
|
244 |
+
'One', function ($container) {
|
245 |
+
return $container->make('ClassOneOne');
|
246 |
+
}
|
247 |
+
);
|
248 |
+
|
249 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* @test
|
254 |
+
* it should replace a singleton bind when re-binding a singleton binding
|
255 |
+
*/
|
256 |
+
public function it_should_replace_a_singleton_bind_when_re_binding_a_singleton_binding()
|
257 |
+
{
|
258 |
+
$container = new tad_DI52_Container();
|
259 |
+
|
260 |
+
$container->singleton(
|
261 |
+
'One', function ($container) {
|
262 |
+
return $container->make('ClassOne');
|
263 |
+
}
|
264 |
+
);
|
265 |
+
|
266 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
267 |
+
|
268 |
+
$container->bind(
|
269 |
+
'One', function ($container) {
|
270 |
+
return $container->make('ClassOneOne');
|
271 |
+
}
|
272 |
+
);
|
273 |
+
|
274 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
275 |
+
$this->assertNotSame($container->make('One'), $container->make('One'));
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* @test
|
280 |
+
* it should replace bind with singleton if re-binding as singleton
|
281 |
+
*/
|
282 |
+
public function it_should_replace_bind_with_singleton_if_re_binding_as_singleton()
|
283 |
+
{
|
284 |
+
$container = new tad_DI52_Container();
|
285 |
+
|
286 |
+
$container->singleton(
|
287 |
+
'One', function ($container) {
|
288 |
+
return $container->make('ClassOne');
|
289 |
+
}
|
290 |
+
);
|
291 |
+
|
292 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
293 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
294 |
+
|
295 |
+
$container->singleton(
|
296 |
+
'One', function ($container) {
|
297 |
+
return $container->make('ClassOneOne');
|
298 |
+
}
|
299 |
+
);
|
300 |
+
|
301 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
302 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* @test
|
307 |
+
* it should replace singleton with simple bind if re-binding as non singleton
|
308 |
+
*/
|
309 |
+
public function it_should_replace_singleton_with_simple_bind_if_re_binding_as_non_singleton()
|
310 |
+
{
|
311 |
+
$container = new tad_DI52_Container();
|
312 |
+
|
313 |
+
$container->singleton(
|
314 |
+
'One', function ($container) {
|
315 |
+
return $container->make('ClassOne');
|
316 |
+
}
|
317 |
+
);
|
318 |
+
|
319 |
+
$this->assertInstanceOf('ClassOne', $container->make('One'));
|
320 |
+
$this->assertSame($container->make('One'), $container->make('One'));
|
321 |
+
|
322 |
+
$container->bind(
|
323 |
+
'One', function ($container) {
|
324 |
+
return $container->make('ClassOneOne');
|
325 |
+
}
|
326 |
+
);
|
327 |
+
|
328 |
+
$this->assertInstanceOf('ClassOneOne', $container->make('One'));
|
329 |
+
$this->assertNotSame($container->make('One'), $container->make('One'));
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* @test
|
334 |
+
* it should allow to lazy make a closure
|
335 |
+
*/
|
336 |
+
public function it_should_allow_to_lazy_make_a_closure()
|
337 |
+
{
|
338 |
+
$container = new tad_DI52_Container();
|
339 |
+
|
340 |
+
$container->bind(
|
341 |
+
'foo', function ($container) {
|
342 |
+
return $container->make('FourBase');
|
343 |
+
}
|
344 |
+
);
|
345 |
+
|
346 |
+
$f = $container->callback('foo', 'methodThree');
|
347 |
+
|
348 |
+
$this->assertEquals(28, $f(5));
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* @test
|
353 |
+
* it should resolve bound closures in instance method
|
354 |
+
*/
|
355 |
+
public function it_should_resolve_bound_closures_in_instance_method()
|
356 |
+
{
|
357 |
+
ClassTwelve::reset();
|
358 |
+
|
359 |
+
$container = new tad_DI52_Container();
|
360 |
+
|
361 |
+
$one = function ($container) {
|
362 |
+
return $container->make('ClassOne');
|
363 |
+
};
|
364 |
+
|
365 |
+
$container->bind('One', $one);
|
366 |
+
|
367 |
+
$f = $container->instance('ClassTwelve', array('One'));
|
368 |
+
|
369 |
+
$this->assertInstanceOf('ClassOne', $f()->getVarOne());
|
370 |
+
}
|
371 |
+
|
372 |
+
/**
|
373 |
+
* @test
|
374 |
+
* it should resolve singleton closures in instance method
|
375 |
+
*/
|
376 |
+
public function it_should_resolve_singleton_closures_in_instance_method()
|
377 |
+
{
|
378 |
+
ClassTwelve::reset();
|
379 |
+
|
380 |
+
$container = new tad_DI52_Container();
|
381 |
+
|
382 |
+
$one = function ($container) {
|
383 |
+
return $container->make('ClassOne');
|
384 |
+
};
|
385 |
+
|
386 |
+
$container->singleton('One', $one);
|
387 |
+
|
388 |
+
$f = $container->instance('ClassTwelve', array('One'));
|
389 |
+
|
390 |
+
$this->assertInstanceOf('ClassOne', $f()->getVarOne());
|
391 |
+
$this->assertSame($f()->getVarOne(), $f()->getVarOne());
|
392 |
+
}
|
393 |
+
|
394 |
+
/**
|
395 |
+
* @test
|
396 |
+
* it should resolve slug bound closures in instance method
|
397 |
+
*/
|
398 |
+
public function it_should_resolve_slug_bound_closures_in_instance_method()
|
399 |
+
{
|
400 |
+
ClassTwelve::reset();
|
401 |
+
|
402 |
+
$container = new tad_DI52_Container();
|
403 |
+
|
404 |
+
$one = function ($container) {
|
405 |
+
return $container->make('ClassOne');
|
406 |
+
};
|
407 |
+
|
408 |
+
$container->bind('foo', $one);
|
409 |
+
|
410 |
+
$f = $container->instance('ClassTwelve', array('foo'));
|
411 |
+
|
412 |
+
$this->assertInstanceOf('ClassOne', $f()->getVarOne());
|
413 |
+
$this->assertNotSame($f()->getVarOne(), $f()->getVarOne());
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* @test
|
418 |
+
* it should resolve singleton slug bound closures in instance method
|
419 |
+
*/
|
420 |
+
public function it_should_resolve_singleton_slug_bound_closures_in_instance_method()
|
421 |
+
{
|
422 |
+
ClassTwelve::reset();
|
423 |
+
|
424 |
+
$container = new tad_DI52_Container();
|
425 |
+
|
426 |
+
$one = function ($container) {
|
427 |
+
return $container->make('ClassOne');
|
428 |
+
};
|
429 |
+
|
430 |
+
$container->singleton('foo', $one);
|
431 |
+
|
432 |
+
$f = $container->instance('ClassTwelve', array('foo'));
|
433 |
+
|
434 |
+
$this->assertInstanceOf('ClassOne', $f()->getVarOne());
|
435 |
+
$this->assertSame($f()->getVarOne(), $f()->getVarOne());
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* @test
|
440 |
+
* it should allow binding and getting an object built as a closure
|
441 |
+
*/
|
442 |
+
public function it_should_allow_binding_and_getting_an_object_built_as_a_closure()
|
443 |
+
{
|
444 |
+
$container = new tad_DI52_Container();
|
445 |
+
|
446 |
+
$container->bind(
|
447 |
+
'One', function ($container) {
|
448 |
+
return $container->make('ClassOne');
|
449 |
+
}
|
450 |
+
);
|
451 |
+
|
452 |
+
$this->assertInstanceOf('ClassOne', $container['One']);
|
453 |
+
$this->assertNotSame($container['One'], $container['One']);
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* @test
|
458 |
+
* it should allow getting a callback to build an object
|
459 |
+
*/
|
460 |
+
public function it_should_allow_getting_a_callback_to_build_an_object()
|
461 |
+
{
|
462 |
+
Acme\ClassTen::reset();
|
463 |
+
|
464 |
+
$container = new tad_DI52_Container();
|
465 |
+
|
466 |
+
$f = $container->instance('Acme\ClassTen', array('foo', 'baz', 'bar'));
|
467 |
+
|
468 |
+
$this->assertEquals(0, Acme\ClassTen::$builtTimes);
|
469 |
+
|
470 |
+
$instance1 = $f();
|
471 |
+
|
472 |
+
$this->assertEquals(1, Acme\ClassTen::$builtTimes);
|
473 |
+
$this->assertEquals('foo', $instance1->getVarOne());
|
474 |
+
$this->assertEquals('baz', $instance1->getVarTwo());
|
475 |
+
$this->assertEquals('bar', $instance1->getVarThree());
|
476 |
+
|
477 |
+
$instance2 = $f();
|
478 |
+
|
479 |
+
$this->assertEquals(2, Acme\ClassTen::$builtTimes);
|
480 |
+
$this->assertEquals('foo', $instance2->getVarOne());
|
481 |
+
$this->assertEquals('baz', $instance2->getVarTwo());
|
482 |
+
$this->assertEquals('bar', $instance2->getVarThree());
|
483 |
+
|
484 |
+
$instance3 = $f();
|
485 |
+
|
486 |
+
$this->assertEquals(3, Acme\ClassTen::$builtTimes);
|
487 |
+
$this->assertEquals('foo', $instance3->getVarOne());
|
488 |
+
$this->assertEquals('baz', $instance3->getVarTwo());
|
489 |
+
$this->assertEquals('bar', $instance3->getVarThree());
|
490 |
+
}
|
491 |
+
|
492 |
+
/**
|
493 |
+
* @test
|
494 |
+
* it should allow getting a callback to build an object with scalar and object dependencies
|
495 |
+
*/
|
496 |
+
public function it_should_allow_getting_a_callback_to_build_an_object_with_scalar_and_object_dependencies()
|
497 |
+
{
|
498 |
+
Acme\ClassEleven::reset();
|
499 |
+
|
500 |
+
$container = new tad_DI52_Container();
|
501 |
+
|
502 |
+
$container->bind('Acme\One', 'Acme\ClassOne');
|
503 |
+
$container->bind('Acme\Two', 'Acme\ClassTwo');
|
504 |
+
|
505 |
+
$f = $container->instance('Acme\ClassEleven', array('Acme\ClassOne', 'Acme\Two', 'bar'));
|
506 |
+
|
507 |
+
$this->assertEquals(0, Acme\ClassEleven::$builtTimes);
|
508 |
+
|
509 |
+
$instance1 = $f();
|
510 |
+
|
511 |
+
$this->assertEquals(1, Acme\ClassEleven::$builtTimes);
|
512 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance1->getVarOne());
|
513 |
+
$this->assertInstanceOf('Acme\ClassTwo', $instance1->getVarTwo());
|
514 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance1->getVarTwo()->getOne());
|
515 |
+
$this->assertEquals('bar', $instance1->getVarThree());
|
516 |
+
|
517 |
+
$instance2 = $f();
|
518 |
+
|
519 |
+
$this->assertEquals(2, Acme\ClassEleven::$builtTimes);
|
520 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance2->getVarOne());
|
521 |
+
$this->assertInstanceOf('Acme\ClassTwo', $instance2->getVarTwo());
|
522 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance2->getVarTwo()->getOne());
|
523 |
+
$this->assertEquals('bar', $instance2->getVarThree());
|
524 |
+
|
525 |
+
$instance3 = $f();
|
526 |
+
|
527 |
+
$this->assertEquals(3, Acme\ClassEleven::$builtTimes);
|
528 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance3->getVarOne());
|
529 |
+
$this->assertInstanceOf('Acme\ClassTwo', $instance3->getVarTwo());
|
530 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance3->getVarTwo()->getOne());
|
531 |
+
$this->assertEquals('bar', $instance3->getVarThree());
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* @test
|
536 |
+
* it should instance using bound implementations
|
537 |
+
*/
|
538 |
+
public function it_should_instance_using_bound_implementations()
|
539 |
+
{
|
540 |
+
Acme\ClassTwelve::reset();
|
541 |
+
|
542 |
+
$container = new tad_DI52_Container();
|
543 |
+
|
544 |
+
$container->bind('Acme\One', 'Acme\ClassOne');
|
545 |
+
$container->bind('Acme\ClassOne', 'Acme\ClassOne');
|
546 |
+
|
547 |
+
$f = $container->instance('Acme\ClassTwelve', array('Acme\ClassOne'));
|
548 |
+
|
549 |
+
$instance1 = $f();
|
550 |
+
|
551 |
+
$this->assertEquals(1, Acme\ClassTwelve::$builtTimes);
|
552 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance1->getVarOne());
|
553 |
+
}
|
554 |
+
|
555 |
+
/**
|
556 |
+
* @test
|
557 |
+
* it should allow overriding bound implementations in instance method
|
558 |
+
*/
|
559 |
+
public function it_should_allow_overriding_bound_implementations_in_instance_method()
|
560 |
+
{
|
561 |
+
Acme\ClassTwelve::reset();
|
562 |
+
|
563 |
+
$container = new tad_DI52_Container();
|
564 |
+
|
565 |
+
$container->bind('Acme\ClassOne', 'Acme\ClassOne');
|
566 |
+
|
567 |
+
$f = $container->instance('Acme\ClassTwelve', array('Acme\ClassOneOne'));
|
568 |
+
|
569 |
+
$instance1 = $f();
|
570 |
+
|
571 |
+
$this->assertEquals(1, Acme\ClassTwelve::$builtTimes);
|
572 |
+
$this->assertInstanceOf('Acme\ClassOneOne', $instance1->getVarOne());
|
573 |
+
}
|
574 |
+
|
575 |
+
/**
|
576 |
+
* @test
|
577 |
+
* it should allow referring bound slugs in instance method
|
578 |
+
*/
|
579 |
+
public function it_should_allow_referring_bound_slugs_in_instance_method()
|
580 |
+
{
|
581 |
+
Acme\ClassTwelve::reset();
|
582 |
+
|
583 |
+
$container = new tad_DI52_Container();
|
584 |
+
|
585 |
+
$container->bind('foo', 'Acme\ClassOne');
|
586 |
+
|
587 |
+
$f = $container->instance('Acme\ClassTwelve', array('foo'));
|
588 |
+
|
589 |
+
$instance1 = $f();
|
590 |
+
|
591 |
+
$this->assertEquals(1, Acme\ClassTwelve::$builtTimes);
|
592 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance1->getVarOne());
|
593 |
+
}
|
594 |
+
|
595 |
+
/**
|
596 |
+
* @test
|
597 |
+
* it should use bound singletons as singletons in instance methods
|
598 |
+
*/
|
599 |
+
public function it_should_use_bound_singletons_as_singletons_in_instance_methods()
|
600 |
+
{
|
601 |
+
Acme\ClassTwelve::reset();
|
602 |
+
|
603 |
+
$container = new tad_DI52_Container();
|
604 |
+
|
605 |
+
$container->singleton('Acme\ClassOne', 'Acme\ClassOne');
|
606 |
+
|
607 |
+
$f = $container->instance('Acme\ClassTwelve', array('Acme\ClassOne'));
|
608 |
+
|
609 |
+
$this->assertInstanceOf('Acme\ClassOne', $f()->getVarOne());
|
610 |
+
$this->assertSame($f()->getVarOne(), $f()->getVarOne());
|
611 |
+
}
|
612 |
+
|
613 |
+
/**
|
614 |
+
* @test
|
615 |
+
* it should resolve bound objects in instance method
|
616 |
+
*/
|
617 |
+
public function it_should_resolve_bound_objects_in_instance_method()
|
618 |
+
{
|
619 |
+
Acme\ClassTwelve::reset();
|
620 |
+
|
621 |
+
$container = new tad_DI52_Container();
|
622 |
+
|
623 |
+
$one = new Acme\ClassOne;
|
624 |
+
$container->singleton('Acme\ClassOne', $one);
|
625 |
+
|
626 |
+
$f = $container->instance('Acme\ClassTwelve', array('Acme\ClassOne'));
|
627 |
+
|
628 |
+
$this->assertInstanceOf('Acme\ClassOne', $f()->getVarOne());
|
629 |
+
$this->assertSame($one, $f()->getVarOne());
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* @test
|
634 |
+
* it should allow binding an instance in the container
|
635 |
+
*/
|
636 |
+
public function it_should_allow_binding_an_instance_in_the_container()
|
637 |
+
{
|
638 |
+
$container = new tad_DI52_Container();
|
639 |
+
|
640 |
+
$container->bind('Acme\ClassOne', $container->instance('Acme\ClassOneTwo', array('sudo-foo')));
|
641 |
+
|
642 |
+
$this->assertInstanceOf('Acme\ClassOneTwo', $container->make('Acme\ClassOne'));
|
643 |
+
$this->assertEquals('sudo-foo', $container->make('Acme\ClassOne')->getFoo());
|
644 |
+
$this->assertNotSame($container->make('Acme\ClassOne'), $container->make('Acme\ClassOne'));
|
645 |
+
}
|
646 |
+
|
647 |
+
/**
|
648 |
+
* @test
|
649 |
+
* it should allow binding an instance as a singleton in the container
|
650 |
+
*/
|
651 |
+
public function it_should_allow_binding_an_instance_as_a_singleton_in_the_container()
|
652 |
+
{
|
653 |
+
$container = new tad_DI52_Container();
|
654 |
+
|
655 |
+
$container->singleton('Acme\ClassOne', $container->instance('Acme\ClassOneTwo', array('sudo-foo')));
|
656 |
+
|
657 |
+
$this->assertInstanceOf('Acme\ClassOneTwo', $container->make('Acme\ClassOne'));
|
658 |
+
$this->assertEquals('sudo-foo', $container->make('Acme\ClassOne')->getFoo());
|
659 |
+
$this->assertSame($container->make('Acme\ClassOne'), $container->make('Acme\ClassOne'));
|
660 |
+
}
|
661 |
+
|
662 |
+
/**
|
663 |
+
* @test
|
664 |
+
* it should build the instance with the container if not specifying arguments
|
665 |
+
*/
|
666 |
+
public function it_should_build_the_instance_with_the_container_if_not_specifying_arguments()
|
667 |
+
{
|
668 |
+
$container = new tad_DI52_Container();
|
669 |
+
|
670 |
+
$container->bind('Acme\ClassOne', 'Acme\ClassOneTwo');
|
671 |
+
$f = $container->instance('Acme\ClassOne');
|
672 |
+
|
673 |
+
$this->assertInstanceOf('Acme\ClassOneTwo', $f());
|
674 |
+
$this->assertEquals('bar', $f()->getFoo());
|
675 |
+
$this->assertNotSame($f(), $f());
|
676 |
+
}
|
677 |
+
|
678 |
+
/**
|
679 |
+
* @test
|
680 |
+
* it should use container binding settings when instancing
|
681 |
+
*/
|
682 |
+
public function it_should_use_container_binding_settings_when_instancing()
|
683 |
+
{
|
684 |
+
$container = new tad_DI52_Container();
|
685 |
+
|
686 |
+
$container->singleton('Acme\ClassOne', 'Acme\ClassOneTwo');
|
687 |
+
$f = $container->instance('Acme\ClassOne');
|
688 |
+
|
689 |
+
$this->assertInstanceOf('Acme\ClassOneTwo', $f());
|
690 |
+
$this->assertEquals('bar', $f()->getFoo());
|
691 |
+
$this->assertSame($f(), $f());
|
692 |
+
}
|
693 |
+
|
694 |
+
/**
|
695 |
+
* @test
|
696 |
+
* it should allow re-binding closuress
|
697 |
+
*/
|
698 |
+
public function it_should_allow_re_binding_closuress()
|
699 |
+
{
|
700 |
+
$container = new tad_DI52_Container();
|
701 |
+
|
702 |
+
$container->bind('One', function () {
|
703 |
+
return new ClassOneOne();
|
704 |
+
});
|
705 |
+
|
706 |
+
$firstInstance = $container->make('ClassTwo');
|
707 |
+
|
708 |
+
$this->assertInstanceOf('ClassOneOne', $firstInstance->getOne());
|
709 |
+
|
710 |
+
$container->bind('One', function () {
|
711 |
+
return new ClassOne();
|
712 |
+
});
|
713 |
+
|
714 |
+
$secondInstance = $container->make('ClassTwo');
|
715 |
+
|
716 |
+
$this->assertInstanceOf('ClassOne', $secondInstance->getOne());
|
717 |
+
}
|
718 |
+
/**
|
719 |
+
* @test
|
720 |
+
* it should allow for callback to be fed to instance
|
721 |
+
*/
|
722 |
+
public function it_should_allow_for_callback_to_be_fed_to_instance() {
|
723 |
+
$container = new tad_DI52_Container();
|
724 |
+
|
725 |
+
$callback = $container->callback('Acme\Factory', 'build');
|
726 |
+
|
727 |
+
$instance = $container->instance($callback);
|
728 |
+
|
729 |
+
$this->assertInstanceOf('Acme\ClassOne', $instance());
|
730 |
+
}
|
731 |
+
|
732 |
+
/**
|
733 |
+
* @test
|
734 |
+
* it should allow for instance to be fed to callback
|
735 |
+
*/
|
736 |
+
public function it_should_allow_for_instance_to_be_fed_to_callback() {
|
737 |
+
$container = new tad_DI52_Container();
|
738 |
+
|
739 |
+
$instance = $container->instance('Acme\Factory');
|
740 |
+
|
741 |
+
$callback = $container->callback($instance, 'build');
|
742 |
+
|
743 |
+
$this->assertInstanceOf('Acme\ClassOne', $callback());
|
744 |
+
}
|
745 |
+
|
746 |
+
/**
|
747 |
+
* @test
|
748 |
+
* it should allow to bind with one parameter
|
749 |
+
*/
|
750 |
+
public function it_should_allow_to_bind_with_one_parameter() {
|
751 |
+
$container = new tad_DI52_Container();
|
752 |
+
|
753 |
+
$container->bind('ClassFourteen');
|
754 |
+
|
755 |
+
$instance = $container->make('ClassFourteen');
|
756 |
+
|
757 |
+
$this->assertInstanceOf('ClassFourteen', $instance);
|
758 |
+
}
|
759 |
+
|
760 |
+
/**
|
761 |
+
* @test
|
762 |
+
* it should allow to bind singleton with one parameter
|
763 |
+
*/
|
764 |
+
public function it_should_allow_to_bind_singleton_with_one_parameter() {
|
765 |
+
$container = new tad_DI52_Container();
|
766 |
+
|
767 |
+
$container->singleton('ClassFourteen');
|
768 |
+
|
769 |
+
$instance1 = $container->make('ClassFourteen');
|
770 |
+
$instance2 = $container->make('ClassFourteen');
|
771 |
+
|
772 |
+
$this->assertInstanceOf('ClassFourteen', $instance1);
|
773 |
+
$this->assertEquals($instance1, $instance2);
|
774 |
+
}
|
775 |
+
|
776 |
+
/** @test */
|
777 |
+
public function it_should_throw_if_binding_string_with_one_parameter() {
|
778 |
+
$this->setExpectedException('ReflectionException');
|
779 |
+
|
780 |
+
$container = new tad_DI52_Container();
|
781 |
+
|
782 |
+
$container->bind('not-a-class');
|
783 |
+
}
|
784 |
+
|
785 |
+
/** @test */
|
786 |
+
public function it_should_throw_if_binding_interface_with_one_parameter() {
|
787 |
+
$this->setExpectedException('InvalidArgumentException');
|
788 |
+
|
789 |
+
$container = new tad_DI52_Container();
|
790 |
+
|
791 |
+
$container->bind('One');
|
792 |
+
}
|
793 |
+
|
794 |
+
/** @test */
|
795 |
+
public function it_should_throw_if_binding_abstract_with_one_parameter() {
|
796 |
+
$this->setExpectedException('InvalidArgumentException');
|
797 |
+
|
798 |
+
$container = new tad_DI52_Container();
|
799 |
+
|
800 |
+
$container->bind('AbstractClass');
|
801 |
+
}
|
802 |
+
|
803 |
+
/** @test */
|
804 |
+
public function it_should_throw_if_binding_private_constructor_with_one_parameter() {
|
805 |
+
$this->setExpectedException('InvalidArgumentException');
|
806 |
+
|
807 |
+
$container = new tad_DI52_Container();
|
808 |
+
|
809 |
+
$container->bind('PrivateConstructor');
|
810 |
+
}
|
811 |
+
}
|
vendor/lucatume/di52/tests/bootstrap.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
require_once dirname(dirname(__FILE__)) . '/vendor/autoload_52.php';
|
3 |
+
require_once dirname(__FILE__) . '/data/test-classes.php';
|
4 |
+
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
5 |
+
require_once dirname(__FILE__) . '/data/namespaced-test-classes.php';
|
6 |
+
}
|
7 |
+
require_once dirname(__FILE__) . '/data/test-providers.php';
|
vendor/lucatume/di52/tests/data/namespaced-test-classes.php
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Acme;
|
4 |
+
|
5 |
+
interface One
|
6 |
+
{
|
7 |
+
|
8 |
+
}
|
9 |
+
|
10 |
+
interface Two
|
11 |
+
{
|
12 |
+
|
13 |
+
}
|
14 |
+
|
15 |
+
class ClassOne implements One
|
16 |
+
{
|
17 |
+
|
18 |
+
}
|
19 |
+
|
20 |
+
class ClassOneOne implements One
|
21 |
+
{
|
22 |
+
public function __construct()
|
23 |
+
{
|
24 |
+
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
class ClassOneTwo implements One
|
29 |
+
{
|
30 |
+
/**
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
private $foo;
|
34 |
+
|
35 |
+
public function __construct($foo = 'bar')
|
36 |
+
{
|
37 |
+
|
38 |
+
$this->foo = $foo;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @return string
|
43 |
+
*/
|
44 |
+
public function getFoo()
|
45 |
+
{
|
46 |
+
return $this->foo;
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
class ClassTwo implements Two
|
51 |
+
{
|
52 |
+
/**
|
53 |
+
* @var One
|
54 |
+
*/
|
55 |
+
private $one;
|
56 |
+
|
57 |
+
public function __construct(One $one)
|
58 |
+
{
|
59 |
+
|
60 |
+
$this->one = $one;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @return One
|
65 |
+
*/
|
66 |
+
public function getOne()
|
67 |
+
{
|
68 |
+
return $this->one;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
class ClassTen
|
73 |
+
{
|
74 |
+
public static $builtTimes = 0;
|
75 |
+
private $varOne;
|
76 |
+
private $varTwo;
|
77 |
+
private $varThree;
|
78 |
+
|
79 |
+
public static function reset()
|
80 |
+
{
|
81 |
+
self::$builtTimes = 0;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function __construct($varOne, $varTwo, $varThree)
|
85 |
+
{
|
86 |
+
self::$builtTimes++;
|
87 |
+
$this->varOne = $varOne;
|
88 |
+
$this->varTwo = $varTwo;
|
89 |
+
$this->varThree = $varThree;
|
90 |
+
}
|
91 |
+
|
92 |
+
public function getVarOne()
|
93 |
+
{
|
94 |
+
return $this->varOne;
|
95 |
+
}
|
96 |
+
|
97 |
+
public function getVarTwo()
|
98 |
+
{
|
99 |
+
return $this->varTwo;
|
100 |
+
}
|
101 |
+
|
102 |
+
public function getVarThree()
|
103 |
+
{
|
104 |
+
return $this->varThree;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
class ClassEleven
|
109 |
+
{
|
110 |
+
public static $builtTimes = 0;
|
111 |
+
private $varOne;
|
112 |
+
private $varTwo;
|
113 |
+
private $varThree;
|
114 |
+
|
115 |
+
public static function reset()
|
116 |
+
{
|
117 |
+
self::$builtTimes = 0;
|
118 |
+
}
|
119 |
+
|
120 |
+
public function __construct(One $varOne, ClassTwo $varTwo, $varThree)
|
121 |
+
{
|
122 |
+
self::$builtTimes++;
|
123 |
+
$this->varOne = $varOne;
|
124 |
+
$this->varTwo = $varTwo;
|
125 |
+
$this->varThree = $varThree;
|
126 |
+
}
|
127 |
+
|
128 |
+
public function getVarOne()
|
129 |
+
{
|
130 |
+
return $this->varOne;
|
131 |
+
}
|
132 |
+
|
133 |
+
public function getVarTwo()
|
134 |
+
{
|
135 |
+
return $this->varTwo;
|
136 |
+
}
|
137 |
+
|
138 |
+
public function getVarThree()
|
139 |
+
{
|
140 |
+
return $this->varThree;
|
141 |
+
}
|
142 |
+
}
|
143 |
+
|
144 |
+
class ClassTwelve
|
145 |
+
{
|
146 |
+
public static $builtTimes = 0;
|
147 |
+
private $varOne;
|
148 |
+
|
149 |
+
public static function reset()
|
150 |
+
{
|
151 |
+
self::$builtTimes = 0;
|
152 |
+
}
|
153 |
+
|
154 |
+
public function __construct(One $varOne)
|
155 |
+
{
|
156 |
+
self::$builtTimes++;
|
157 |
+
$this->varOne = $varOne;
|
158 |
+
}
|
159 |
+
|
160 |
+
public function getVarOne()
|
161 |
+
{
|
162 |
+
return $this->varOne;
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
class Factory {
|
167 |
+
public function build() {
|
168 |
+
return new ClassOne();
|
169 |
+
}
|
170 |
+
}
|
vendor/lucatume/di52/tests/data/test-classes.php
ADDED
@@ -0,0 +1,435 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface One {
|
4 |
+
|
5 |
+
}
|
6 |
+
|
7 |
+
interface Two {
|
8 |
+
|
9 |
+
}
|
10 |
+
|
11 |
+
interface Four {
|
12 |
+
|
13 |
+
}
|
14 |
+
|
15 |
+
interface Five {
|
16 |
+
|
17 |
+
}
|
18 |
+
|
19 |
+
class ClassOne implements One {
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
class ExtendingClassOneOne extends ClassOne {
|
24 |
+
|
25 |
+
}
|
26 |
+
|
27 |
+
class ExtendingClassOneTwo extends ClassOne {
|
28 |
+
|
29 |
+
}
|
30 |
+
|
31 |
+
class ClassOneOne implements One {
|
32 |
+
public function __construct() {
|
33 |
+
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
class ClassOneTwo implements One {
|
38 |
+
/**
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
private $foo;
|
42 |
+
|
43 |
+
public function __construct($foo = 'bar') {
|
44 |
+
|
45 |
+
$this->foo = $foo;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @return string
|
50 |
+
*/
|
51 |
+
public function getFoo() {
|
52 |
+
return $this->foo;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
class ClassOneThree {
|
57 |
+
public $oneCalled;
|
58 |
+
public $twoCalled;
|
59 |
+
|
60 |
+
public function methodOne() {
|
61 |
+
$this->oneCalled = true;
|
62 |
+
}
|
63 |
+
|
64 |
+
public function methodTwo() {
|
65 |
+
$this->twoCalled = true;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
class ClassTwo implements Two {
|
70 |
+
/**
|
71 |
+
* @var One
|
72 |
+
*/
|
73 |
+
private $one;
|
74 |
+
|
75 |
+
public function __construct(One $one) {
|
76 |
+
|
77 |
+
$this->one = $one;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @return One
|
82 |
+
*/
|
83 |
+
public function getOne() {
|
84 |
+
return $this->one;
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
class ClassTwoOne implements Two {
|
89 |
+
private $one;
|
90 |
+
|
91 |
+
public function __construct(ClassOne $one) {
|
92 |
+
|
93 |
+
$this->one = $one;
|
94 |
+
}
|
95 |
+
|
96 |
+
public function getOne() {
|
97 |
+
return $this->one;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
class ClassTwoTwo implements Two {
|
102 |
+
public function __construct(One $one) {
|
103 |
+
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
class ClassThree {
|
108 |
+
public function __construct(One $one, Two $two, $three = 3) {
|
109 |
+
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
class ClassThreeOne {
|
114 |
+
public function __construct(One $one, ClassTwo $two, $three = 3) {
|
115 |
+
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
class ClassThreeTwo {
|
120 |
+
public function __construct(ClassOne $one, ClassOneOne $two, $three = 3) {
|
121 |
+
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
class ClassFour {
|
126 |
+
public function __construct($some) {
|
127 |
+
|
128 |
+
}
|
129 |
+
|
130 |
+
public function methodOne($n) {
|
131 |
+
return $n + 23;
|
132 |
+
}
|
133 |
+
|
134 |
+
public function methodTwo() {
|
135 |
+
return 23;
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
class FourBase implements Four {
|
140 |
+
public function __construct() {
|
141 |
+
|
142 |
+
}
|
143 |
+
|
144 |
+
public function methodOne() {
|
145 |
+
global $one;
|
146 |
+
$one = __CLASS__;
|
147 |
+
}
|
148 |
+
|
149 |
+
public function methodTwo() {
|
150 |
+
global $two;
|
151 |
+
$two = __CLASS__;
|
152 |
+
}
|
153 |
+
|
154 |
+
public function methodThree($n) {
|
155 |
+
return $n + 23;
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
class FourTwo implements Four {
|
160 |
+
|
161 |
+
}
|
162 |
+
|
163 |
+
class FourDecoratorOne implements Four {
|
164 |
+
public function __construct(Four $decorated) {
|
165 |
+
|
166 |
+
}
|
167 |
+
|
168 |
+
public function methodOne($n) {
|
169 |
+
return $n + 23;
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
class FourDecoratorTwo implements Four {
|
174 |
+
public function __construct(Four $decorated) {
|
175 |
+
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
class FourDecoratorThree implements Four {
|
180 |
+
public function __construct(Four $decorated) {
|
181 |
+
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
class FiveBase implements Five {
|
186 |
+
public function __construct($foo = 10) {
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
class FiveDecoratorOne implements Five {
|
191 |
+
public function __construct(Five $five, Four $four) {
|
192 |
+
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
class FiveDecoratorTwo implements Five {
|
197 |
+
public function __construct(Five $five, One $one) {
|
198 |
+
|
199 |
+
}
|
200 |
+
}
|
201 |
+
|
202 |
+
class FiveDecoratorThree implements Five {
|
203 |
+
public function __construct(Five $five, Two $two) {
|
204 |
+
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
class FiveTwo implements Five {
|
209 |
+
|
210 |
+
}
|
211 |
+
|
212 |
+
|
213 |
+
class ClassSix {
|
214 |
+
private $one;
|
215 |
+
|
216 |
+
public function __construct(One $one) {
|
217 |
+
$this->one = $one;
|
218 |
+
}
|
219 |
+
|
220 |
+
public function getOne() {
|
221 |
+
return $this->one;
|
222 |
+
}
|
223 |
+
}
|
224 |
+
|
225 |
+
class ClassSeven {
|
226 |
+
private $one;
|
227 |
+
|
228 |
+
public function __construct(One $one) {
|
229 |
+
|
230 |
+
$this->one = $one;
|
231 |
+
}
|
232 |
+
|
233 |
+
public function getOne() {
|
234 |
+
return $this->one;
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
class ClassSixOne {
|
239 |
+
private $one;
|
240 |
+
|
241 |
+
public function __construct(ClassOne $one) {
|
242 |
+
$this->one = $one;
|
243 |
+
}
|
244 |
+
|
245 |
+
public function getOne() {
|
246 |
+
return $this->one;
|
247 |
+
}
|
248 |
+
}
|
249 |
+
|
250 |
+
class ClassSevenOne {
|
251 |
+
private $one;
|
252 |
+
|
253 |
+
public function __construct(ClassOne $one) {
|
254 |
+
|
255 |
+
$this->one = $one;
|
256 |
+
}
|
257 |
+
|
258 |
+
public function getOne() {
|
259 |
+
return $this->one;
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
interface Eight {
|
264 |
+
public function methodOne();
|
265 |
+
|
266 |
+
public function methodTwo();
|
267 |
+
|
268 |
+
public function methodThree();
|
269 |
+
}
|
270 |
+
|
271 |
+
class ClassEight implements Eight {
|
272 |
+
public static $called = array();
|
273 |
+
public static $calledWith = array();
|
274 |
+
|
275 |
+
public static function reset() {
|
276 |
+
self::$called = array();
|
277 |
+
self::$calledWith = array();
|
278 |
+
}
|
279 |
+
|
280 |
+
public function methodOne() {
|
281 |
+
self::$called[] = 'methodOne';
|
282 |
+
}
|
283 |
+
|
284 |
+
public function methodTwo() {
|
285 |
+
self::$called[] = 'methodTwo';
|
286 |
+
}
|
287 |
+
|
288 |
+
public function methodThree() {
|
289 |
+
self::$called[] = 'methodThree';
|
290 |
+
}
|
291 |
+
|
292 |
+
public function methodFour() {
|
293 |
+
self::$calledWith = func_get_args();
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
class ClassEightExtension extends ClassEight {
|
298 |
+
}
|
299 |
+
|
300 |
+
class ClassNine {
|
301 |
+
public function __construct() {
|
302 |
+
|
303 |
+
}
|
304 |
+
|
305 |
+
public static function reset() {
|
306 |
+
unset($GLOBALS['nine']);
|
307 |
+
}
|
308 |
+
|
309 |
+
public function methodOne() {
|
310 |
+
$GLOBALS['nine'] = 'called';
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
class ClassTen {
|
315 |
+
public static $builtTimes = 0;
|
316 |
+
private $varOne;
|
317 |
+
private $varTwo;
|
318 |
+
private $varThree;
|
319 |
+
|
320 |
+
public static function reset() {
|
321 |
+
self::$builtTimes = 0;
|
322 |
+
}
|
323 |
+
|
324 |
+
public function __construct($varOne, $varTwo, $varThree) {
|
325 |
+
self::$builtTimes++;
|
326 |
+
$this->varOne = $varOne;
|
327 |
+
$this->varTwo = $varTwo;
|
328 |
+
$this->varThree = $varThree;
|
329 |
+
}
|
330 |
+
|
331 |
+
public function getVarOne() {
|
332 |
+
return $this->varOne;
|
333 |
+
}
|
334 |
+
|
335 |
+
public function getVarTwo() {
|
336 |
+
return $this->varTwo;
|
337 |
+
}
|
338 |
+
|
339 |
+
public function getVarThree() {
|
340 |
+
return $this->varThree;
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
class ClassEleven {
|
345 |
+
public static $builtTimes = 0;
|
346 |
+
private $varOne;
|
347 |
+
private $varTwo;
|
348 |
+
private $varThree;
|
349 |
+
|
350 |
+
public static function reset() {
|
351 |
+
self::$builtTimes = 0;
|
352 |
+
}
|
353 |
+
|
354 |
+
public function __construct(One $varOne, ClassTwo $varTwo, $varThree) {
|
355 |
+
self::$builtTimes++;
|
356 |
+
$this->varOne = $varOne;
|
357 |
+
$this->varTwo = $varTwo;
|
358 |
+
$this->varThree = $varThree;
|
359 |
+
}
|
360 |
+
|
361 |
+
public function getVarOne() {
|
362 |
+
return $this->varOne;
|
363 |
+
}
|
364 |
+
|
365 |
+
public function getVarTwo() {
|
366 |
+
return $this->varTwo;
|
367 |
+
}
|
368 |
+
|
369 |
+
public function getVarThree() {
|
370 |
+
return $this->varThree;
|
371 |
+
}
|
372 |
+
}
|
373 |
+
|
374 |
+
class ClassTwelve {
|
375 |
+
public static $builtTimes = 0;
|
376 |
+
private $varOne;
|
377 |
+
|
378 |
+
public static function reset() {
|
379 |
+
self::$builtTimes = 0;
|
380 |
+
}
|
381 |
+
|
382 |
+
public function __construct(One $varOne) {
|
383 |
+
self::$builtTimes++;
|
384 |
+
$this->varOne = $varOne;
|
385 |
+
}
|
386 |
+
|
387 |
+
public function getVarOne() {
|
388 |
+
return $this->varOne;
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
class Factory {
|
393 |
+
public function build() {
|
394 |
+
return new ClassOne();
|
395 |
+
}
|
396 |
+
}
|
397 |
+
|
398 |
+
class ClassThirteen {
|
399 |
+
public function doSomething() {
|
400 |
+
return 'IDidSomething';
|
401 |
+
}
|
402 |
+
}
|
403 |
+
|
404 |
+
class ClassFourteen {
|
405 |
+
}
|
406 |
+
|
407 |
+
class ClassFifteen {
|
408 |
+
public function __construct(One $one, ClassFourteen $fourteen) {
|
409 |
+
|
410 |
+
}
|
411 |
+
|
412 |
+
public function doSomething() {
|
413 |
+
return 'IDidSomething';
|
414 |
+
}
|
415 |
+
}
|
416 |
+
|
417 |
+
class Dependency {}
|
418 |
+
|
419 |
+
class Depending {
|
420 |
+
private $dependency;
|
421 |
+
|
422 |
+
public function __construct( Dependency $dependency ) {
|
423 |
+
$this->dependency = $dependency;
|
424 |
+
}
|
425 |
+
|
426 |
+
public function getDependency() {
|
427 |
+
return $this->dependency;
|
428 |
+
}
|
429 |
+
}
|
430 |
+
|
431 |
+
abstract class AbstractClass {};
|
432 |
+
|
433 |
+
class PrivateConstructor {
|
434 |
+
private function __construct() {}
|
435 |
+
}
|
vendor/lucatume/di52/tests/data/test-providers.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class ProviderOne extends tad_DI52_ServiceProvider
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* Binds and sets up implementations.
|
7 |
+
*/
|
8 |
+
public function register()
|
9 |
+
{
|
10 |
+
$this->container->bind('foo', 23);
|
11 |
+
}
|
12 |
+
}
|
13 |
+
|
14 |
+
class DeferredProviderOne extends tad_DI52_ServiceProvider
|
15 |
+
{
|
16 |
+
|
17 |
+
protected $deferred = true;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Binds and sets up implementations.
|
21 |
+
*/
|
22 |
+
public function register()
|
23 |
+
{
|
24 |
+
$this->container->bind('foo', 23);
|
25 |
+
}
|
26 |
+
|
27 |
+
}
|
28 |
+
|
29 |
+
class DeferredProviderTwo extends tad_DI52_ServiceProvider
|
30 |
+
{
|
31 |
+
|
32 |
+
protected static $wasRegistered = false;
|
33 |
+
protected $deferred = true;
|
34 |
+
|
35 |
+
public static function wasRegistered()
|
36 |
+
{
|
37 |
+
return self::$wasRegistered;
|
38 |
+
}
|
39 |
+
|
40 |
+
public static function reset()
|
41 |
+
{
|
42 |
+
self::$wasRegistered = false;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function provides()
|
46 |
+
{
|
47 |
+
return array('One');
|
48 |
+
}
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Binds and sets up implementations.
|
53 |
+
*/
|
54 |
+
public function register()
|
55 |
+
{
|
56 |
+
$this->container->bind('One', 'ClassOne');
|
57 |
+
self::$wasRegistered = true;
|
58 |
+
}
|
59 |
+
|
60 |
+
}
|
61 |
+
|
62 |
+
class ProviderThree extends tad_DI52_ServiceProvider
|
63 |
+
{
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Binds and sets up implementations.
|
67 |
+
*/
|
68 |
+
public function boot()
|
69 |
+
{
|
70 |
+
$this->container->bind('One', 'ClassOne');
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Binds and sets up implementations.
|
75 |
+
*/
|
76 |
+
public function register()
|
77 |
+
{
|
78 |
+
// no-op
|
79 |
+
}
|
80 |
+
}
|
vendor/lucatume/di52/todo.txt
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
- hasTag() to check for tagging
|
vendor/symfony/polyfill-ctype/bootstrap.php
CHANGED
@@ -12,35 +12,35 @@
|
|
12 |
use Symfony\Polyfill\Ctype as p;
|
13 |
|
14 |
if (!function_exists('ctype_alnum')) {
|
15 |
-
function ctype_alnum($
|
16 |
}
|
17 |
if (!function_exists('ctype_alpha')) {
|
18 |
-
function ctype_alpha($
|
19 |
}
|
20 |
if (!function_exists('ctype_cntrl')) {
|
21 |
-
function ctype_cntrl($
|
22 |
}
|
23 |
if (!function_exists('ctype_digit')) {
|
24 |
-
function ctype_digit($
|
25 |
}
|
26 |
if (!function_exists('ctype_graph')) {
|
27 |
-
function ctype_graph($
|
28 |
}
|
29 |
if (!function_exists('ctype_lower')) {
|
30 |
-
function ctype_lower($
|
31 |
}
|
32 |
if (!function_exists('ctype_print')) {
|
33 |
-
function ctype_print($
|
34 |
}
|
35 |
if (!function_exists('ctype_punct')) {
|
36 |
-
function ctype_punct($
|
37 |
}
|
38 |
if (!function_exists('ctype_space')) {
|
39 |
-
function ctype_space($
|
40 |
}
|
41 |
if (!function_exists('ctype_upper')) {
|
42 |
-
function ctype_upper($
|
43 |
}
|
44 |
if (!function_exists('ctype_xdigit')) {
|
45 |
-
function ctype_xdigit($
|
46 |
}
|
12 |
use Symfony\Polyfill\Ctype as p;
|
13 |
|
14 |
if (!function_exists('ctype_alnum')) {
|
15 |
+
function ctype_alnum($input) { return p\Ctype::ctype_alnum($input); }
|
16 |
}
|
17 |
if (!function_exists('ctype_alpha')) {
|
18 |
+
function ctype_alpha($input) { return p\Ctype::ctype_alpha($input); }
|
19 |
}
|
20 |
if (!function_exists('ctype_cntrl')) {
|
21 |
+
function ctype_cntrl($input) { return p\Ctype::ctype_cntrl($input); }
|
22 |
}
|
23 |
if (!function_exists('ctype_digit')) {
|
24 |
+
function ctype_digit($input) { return p\Ctype::ctype_digit($input); }
|
25 |
}
|
26 |
if (!function_exists('ctype_graph')) {
|
27 |
+
function ctype_graph($input) { return p\Ctype::ctype_graph($input); }
|
28 |
}
|
29 |
if (!function_exists('ctype_lower')) {
|
30 |
+
function ctype_lower($input) { return p\Ctype::ctype_lower($input); }
|
31 |
}
|
32 |
if (!function_exists('ctype_print')) {
|
33 |
+
function ctype_print($input) { return p\Ctype::ctype_print($input); }
|
34 |
}
|
35 |
if (!function_exists('ctype_punct')) {
|
36 |
+
function ctype_punct($input) { return p\Ctype::ctype_punct($input); }
|
37 |
}
|
38 |
if (!function_exists('ctype_space')) {
|
39 |
+
function ctype_space($input) { return p\Ctype::ctype_space($input); }
|
40 |
}
|
41 |
if (!function_exists('ctype_upper')) {
|
42 |
+
function ctype_upper($input) { return p\Ctype::ctype_upper($input); }
|
43 |
}
|
44 |
if (!function_exists('ctype_xdigit')) {
|
45 |
+
function ctype_xdigit($input) { return p\Ctype::ctype_xdigit($input); }
|
46 |
}
|
vendor/symfony/polyfill-ctype/composer.json
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
"minimum-stability": "dev",
|
29 |
"extra": {
|
30 |
"branch-alias": {
|
31 |
-
"dev-
|
32 |
},
|
33 |
"thanks": {
|
34 |
"name": "symfony/polyfill",
|
28 |
"minimum-stability": "dev",
|
29 |
"extra": {
|
30 |
"branch-alias": {
|
31 |
+
"dev-main": "1.19-dev"
|
32 |
},
|
33 |
"thanks": {
|
34 |
"name": "symfony/polyfill",
|
vendor/xrstf/composer-php52/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
/vendor/
|
vendor/xrstf/composer-php52/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2013 Christoph Mewes
|
2 |
+
|
3 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4 |
+
of this software and associated documentation files (the "Software"), to deal
|
5 |
+
in the Software without restriction, including without limitation the rights
|
6 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7 |
+
copies of the Software, and to permit persons to whom the Software is furnished
|
8 |
+
to do so, subject to the following conditions:
|
9 |
+
|
10 |
+
The above copyright notice and this permission notice shall be included in all
|
11 |
+
copies or substantial portions of the Software.
|
12 |
+
|
13 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19 |
+
THE SOFTWARE.
|
vendor/xrstf/composer-php52/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
PHP 5.2 Autoloading for Composer
|
2 |
+
================================
|
3 |
+
|
4 |
+
This package provides an easy way to get a PHP 5.2 compatible autoloader out of Composer. The generated autoloader is fully compatible to the original and is written into separate files, each ending with `_52.php`.
|
5 |
+
|
6 |
+
Legacy
|
7 |
+
------
|
8 |
+
|
9 |
+
Please do not use this, if you can avoid it. It's a horrible hack, often breaks and is extremely tied to Composer's interna. This package was originally developed in 2012, when PHP 5.2 was much more common on cheap webhosts.
|
10 |
+
|
11 |
+
In 2016, this package has been moved from Bitbucket to a Github organization, because the original developer could no longer reliably maintain it. This is the reason for this legacy package name ``xrstf/...``.
|
12 |
+
|
13 |
+
Usage
|
14 |
+
-----
|
15 |
+
|
16 |
+
In your project's `composer.json`, add the following lines:
|
17 |
+
|
18 |
+
```json
|
19 |
+
{
|
20 |
+
"require": {
|
21 |
+
"xrstf/composer-php52": "1.*"
|
22 |
+
},
|
23 |
+
"scripts": {
|
24 |
+
"post-install-cmd": [
|
25 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
26 |
+
],
|
27 |
+
"post-update-cmd": [
|
28 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
29 |
+
],
|
30 |
+
"post-autoload-dump": [
|
31 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
32 |
+
]
|
33 |
+
}
|
34 |
+
}
|
35 |
+
```
|
36 |
+
|
37 |
+
After the next update/install, you will have a `vendor/autoload_52.php` file, that you can simply include and use in PHP 5.2 projects.
|
vendor/xrstf/composer-php52/composer.json
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "xrstf/composer-php52",
|
3 |
+
"license": "MIT",
|
4 |
+
"support": {
|
5 |
+
"source": "https://github.com/composer-php52/composer-php52",
|
6 |
+
"issues": "https://github.com/composer-php52/composer-php52/issues"
|
7 |
+
},
|
8 |
+
"autoload": {
|
9 |
+
"psr-0": {
|
10 |
+
"xrstf\\Composer52": "lib/"
|
11 |
+
}
|
12 |
+
},
|
13 |
+
"scripts": {
|
14 |
+
"post-install-cmd": [
|
15 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
16 |
+
],
|
17 |
+
"post-update-cmd": [
|
18 |
+
"xrstf\\Composer52\\Generator::onPostInstallCmd"
|
19 |
+
]
|
20 |
+
},
|
21 |
+
"extra": {
|
22 |
+
"branch-alias": {
|
23 |
+
"dev-default": "1.x-dev"
|
24 |
+
}
|
25 |
+
}
|
26 |
+
}
|
vendor/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php
ADDED
@@ -0,0 +1,346 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de
|
4 |
+
*
|
5 |
+
* This file is released under the terms of the MIT license. You can find the
|
6 |
+
* complete text in the attached LICENSE file or online at:
|
7 |
+
*
|
8 |
+
* http://www.opensource.org/licenses/mit-license.php
|
9 |
+
*
|
10 |
+
* --------------------------------------------------------------------------
|
11 |
+
*
|
12 |
+
* 99% of this is copied as-is from the original Composer source code and is
|
13 |
+
* released under MIT license as well. Copyright goes to:
|
14 |
+
*
|
15 |
+
* - Igor Wiedler <igor@wiedler.ch>
|
16 |
+
* - Jordi Boggiano <j.boggiano@seld.be>
|
17 |
+
*/
|
18 |
+
|
19 |
+
namespace xrstf\Composer52;
|
20 |
+
|
21 |
+
use Composer\Autoload\AutoloadGenerator as BaseGenerator;
|
22 |
+
use Composer\Autoload\ClassMapGenerator;
|
23 |
+
use Composer\Config;
|
24 |
+
use Composer\Installer\InstallationManager;
|
25 |
+
use Composer\Package\AliasPackage;
|
26 |
+
use Composer\Package\PackageInterface;
|
27 |
+
use Composer\Repository\InstalledRepositoryInterface;
|
28 |
+
use Composer\Util\Filesystem;
|
29 |
+
|
30 |
+
class AutoloadGenerator extends BaseGenerator {
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var bool
|
34 |
+
*/
|
35 |
+
private $classMapAuthoritative = false;
|
36 |
+
|
37 |
+
public function __construct() {
|
38 |
+
// do nothing (but keep this constructor so we can build an instance without the need for an event dispatcher)
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Whether or not generated autoloader considers the class map
|
43 |
+
* authoritative.
|
44 |
+
*
|
45 |
+
* @param bool $classMapAuthoritative
|
46 |
+
*/
|
47 |
+
public function setClassMapAuthoritative($classMapAuthoritative)
|
48 |
+
{
|
49 |
+
$this->classMapAuthoritative = (boolean) $classMapAuthoritative;
|
50 |
+
}
|
51 |
+
|
52 |
+
public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '') {
|
53 |
+
if ($this->classMapAuthoritative) {
|
54 |
+
// Force scanPsr0Packages when classmap is authoritative
|
55 |
+
$scanPsr0Packages = true;
|
56 |
+
}
|
57 |
+
|
58 |
+
$filesystem = new Filesystem();
|
59 |
+
$filesystem->ensureDirectoryExists($config->get('vendor-dir'));
|
60 |
+
|
61 |
+
$cwd = getcwd();
|
62 |
+
$basePath = $filesystem->normalizePath($cwd);
|
63 |
+
$vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
|
64 |
+
$targetDir = $vendorPath.'/'.$targetDir;
|
65 |
+
$filesystem->ensureDirectoryExists($targetDir);
|
66 |
+
|
67 |
+
$useGlobalIncludePath = (bool) $config->get('use-include-path');
|
68 |
+
$prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true';
|
69 |
+
$classMapAuthoritative = $config->get('classmap-authoritative');
|
70 |
+
|
71 |
+
$vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
|
72 |
+
$vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true);
|
73 |
+
|
74 |
+
$appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true);
|
75 |
+
$appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode);
|
76 |
+
|
77 |
+
// add 5.2 compat
|
78 |
+
$vendorPathCode = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode);
|
79 |
+
$vendorPathToTargetDirCode = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathToTargetDirCode);
|
80 |
+
|
81 |
+
$packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages());
|
82 |
+
$autoloads = $this->parseAutoloads($packageMap, $mainPackage);
|
83 |
+
|
84 |
+
// add custom psr-0 autoloading if the root package has a target dir
|
85 |
+
$targetDirLoader = null;
|
86 |
+
$mainAutoload = $mainPackage->getAutoload();
|
87 |
+
if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) {
|
88 |
+
$levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir())));
|
89 |
+
$prefixes = implode(', ', array_map(function ($prefix) {
|
90 |
+
return var_export($prefix, true);
|
91 |
+
}, array_keys($mainAutoload['psr-0'])));
|
92 |
+
|
93 |
+
$baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true);
|
94 |
+
|
95 |
+
$targetDirLoader = <<<EOF
|
96 |
+
|
97 |
+
public static function autoload(\$class) {
|
98 |
+
\$dir = $baseDirFromTargetDirCode.'/';
|
99 |
+
\$prefixes = array($prefixes);
|
100 |
+
|
101 |
+
foreach (\$prefixes as \$prefix) {
|
102 |
+
if (0 !== strpos(\$class, \$prefix)) {
|
103 |
+
continue;
|
104 |
+
}
|
105 |
+
|
106 |
+
\$path = explode(DIRECTORY_SEPARATOR, self::getClassPath(\$class));
|
107 |
+
\$path = \$dir.implode('/', array_slice(\$path, $levels));
|
108 |
+
|
109 |
+
if (!\$path = self::resolveIncludePath(\$path)) {
|
110 |
+
return false;
|
111 |
+
}
|
112 |
+
|
113 |
+
require \$path;
|
114 |
+
return true;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
EOF;
|
119 |
+
}
|
120 |
+
|
121 |
+
$filesCode = "";
|
122 |
+
$autoloads['files'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['files']));
|
123 |
+
foreach ($autoloads['files'] as $functionFile) {
|
124 |
+
// don't include file if it is using PHP 5.3+ syntax
|
125 |
+
// https://bitbucket.org/xrstf/composer-php52/issue/4
|
126 |
+
if ($this->isPHP53($functionFile)) {
|
127 |
+
$filesCode .= '// require '.$this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile)."; // disabled because of PHP 5.3 syntax\n";
|
128 |
+
}
|
129 |
+
else {
|
130 |
+
$filesCode .= ' require '.$this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile).";\n";
|
131 |
+
}
|
132 |
+
}
|
133 |
+
|
134 |
+
if (!$suffix) {
|
135 |
+
$suffix = md5(uniqid('', true));
|
136 |
+
}
|
137 |
+
|
138 |
+
$includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode);
|
139 |
+
|
140 |
+
file_put_contents($vendorPath.'/autoload_52.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
|
141 |
+
file_put_contents($targetDir.'/autoload_real_52.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader));
|
142 |
+
|
143 |
+
// use stream_copy_to_stream instead of copy
|
144 |
+
// to work around https://bugs.php.net/bug.php?id=64634
|
145 |
+
$sourceLoader = fopen(__DIR__.'/ClassLoader.php', 'r');
|
146 |
+
$targetLoader = fopen($targetDir.'/ClassLoader52.php', 'w+');
|
147 |
+
stream_copy_to_stream($sourceLoader, $targetLoader);
|
148 |
+
fclose($sourceLoader);
|
149 |
+
fclose($targetLoader);
|
150 |
+
unset($sourceLoader, $targetLoader);
|
151 |
+
}
|
152 |
+
|
153 |
+
protected function isPHP53($file) {
|
154 |
+
$tokens = token_get_all(file_get_contents($file));
|
155 |
+
$php53 = array(T_DIR, T_GOTO, T_NAMESPACE, T_NS_C, T_NS_SEPARATOR, T_USE);
|
156 |
+
|
157 |
+
// PHP 5.4+
|
158 |
+
if (defined('T_TRAIT')) {
|
159 |
+
$php53[] = T_TRAIT;
|
160 |
+
$php53[] = T_TRAIT_C;
|
161 |
+
$php53[] = T_TRAIT_C;
|
162 |
+
}
|
163 |
+
|
164 |
+
// PHP 5.5+
|
165 |
+
if (defined('T_FINALLY')) {
|
166 |
+
$php53[] = T_FINALLY;
|
167 |
+
$php53[] = T_YIELD;
|
168 |
+
}
|
169 |
+
|
170 |
+
foreach ($tokens as $token) {
|
171 |
+
if (is_array($token) && in_array($token[0], $php53)) {
|
172 |
+
return true;
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
return false;
|
177 |
+
}
|
178 |
+
|
179 |
+
protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode) {
|
180 |
+
$includePaths = array();
|
181 |
+
|
182 |
+
foreach ($packageMap as $item) {
|
183 |
+
list($package, $installPath) = $item;
|
184 |
+
|
185 |
+
if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
|
186 |
+
$installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
|
187 |
+
}
|
188 |
+
|
189 |
+
foreach ($package->getIncludePaths() as $includePath) {
|
190 |
+
$includePath = trim($includePath, '/');
|
191 |
+
$includePaths[] = empty($installPath) ? $includePath : $installPath.'/'.$includePath;
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
if (!$includePaths) {
|
196 |
+
return;
|
197 |
+
}
|
198 |
+
|
199 |
+
$includePathsFile = <<<EOF
|
200 |
+
<?php
|
201 |
+
|
202 |
+
// include_paths_52.php generated by xrstf/composer-php52
|
203 |
+
|
204 |
+
\$vendorDir = $vendorPathCode;
|
205 |
+
\$baseDir = $appBaseDirCode;
|
206 |
+
|
207 |
+
return array(
|
208 |
+
|
209 |
+
EOF;
|
210 |
+
|
211 |
+
foreach ($includePaths as $path) {
|
212 |
+
$includePathsFile .= "\t" . $this->getPathCode($filesystem, $basePath, $vendorPath, $path) . ",\n";
|
213 |
+
}
|
214 |
+
|
215 |
+
return $includePathsFile . ");\n";
|
216 |
+
}
|
217 |
+
|
218 |
+
protected function getAutoloadFile($vendorPathToTargetDirCode, $suffix) {
|
219 |
+
return <<<AUTOLOAD
|
220 |
+
<?php
|
221 |
+
|
222 |
+
// autoload_52.php generated by xrstf/composer-php52
|
223 |
+
|
224 |
+
require_once $vendorPathToTargetDirCode.'/autoload_real_52.php';
|
225 |
+
|
226 |
+
return ComposerAutoloaderInit$suffix::getLoader();
|
227 |
+
|
228 |
+
AUTOLOAD;
|
229 |
+
}
|
230 |
+
|
231 |
+
protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion = 70000) {
|
232 |
+
// TODO the class ComposerAutoloaderInit should be revert to a closure
|
233 |
+
// when APC has been fixed:
|
234 |
+
// - https://github.com/composer/composer/issues/959
|
235 |
+
// - https://bugs.php.net/bug.php?id=52144
|
236 |
+
// - https://bugs.php.net/bug.php?id=61576
|
237 |
+
// - https://bugs.php.net/bug.php?id=59298
|
238 |
+
|
239 |
+
if ($filesCode) {
|
240 |
+
$filesCode = "\n\n".rtrim($filesCode);
|
241 |
+
}
|
242 |
+
|
243 |
+
$file = <<<HEADER
|
244 |
+
<?php
|
245 |
+
|
246 |
+
// autoload_real_52.php generated by xrstf/composer-php52
|
247 |
+
|
248 |
+
class ComposerAutoloaderInit$suffix {
|
249 |
+
private static \$loader;
|
250 |
+
|
251 |
+
public static function loadClassLoader(\$class) {
|
252 |
+
if ('xrstf_Composer52_ClassLoader' === \$class) {
|
253 |
+
require dirname(__FILE__).'/ClassLoader52.php';
|
254 |
+
}
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* @return xrstf_Composer52_ClassLoader
|
259 |
+
*/
|
260 |
+
public static function getLoader() {
|
261 |
+
if (null !== self::\$loader) {
|
262 |
+
return self::\$loader;
|
263 |
+
}
|
264 |
+
|
265 |
+
spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'), true /*, true */);
|
266 |
+
self::\$loader = \$loader = new xrstf_Composer52_ClassLoader();
|
267 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'));
|
268 |
+
|
269 |
+
\$vendorDir = $vendorPathCode;
|
270 |
+
\$baseDir = $appBaseDirCode;
|
271 |
+
\$dir = dirname(__FILE__);
|
272 |
+
|
273 |
+
|
274 |
+
HEADER;
|
275 |
+
|
276 |
+
if ($useIncludePath) {
|
277 |
+
$file .= <<<'INCLUDE_PATH'
|
278 |
+
$includePaths = require $dir.'/include_paths.php';
|
279 |
+
array_push($includePaths, get_include_path());
|
280 |
+
set_include_path(implode(PATH_SEPARATOR, $includePaths));
|
281 |
+
|
282 |
+
|
283 |
+
INCLUDE_PATH;
|
284 |
+
}
|
285 |
+
|
286 |
+
$file .= <<<'PSR0'
|
287 |
+
$map = require $dir.'/autoload_namespaces.php';
|
288 |
+
foreach ($map as $namespace => $path) {
|
289 |
+
$loader->add($namespace, $path);
|
290 |
+
}
|
291 |
+
|
292 |
+
|
293 |
+
PSR0;
|
294 |
+
|
295 |
+
if ($useClassMap) {
|
296 |
+
$file .= <<<'CLASSMAP'
|
297 |
+
$classMap = require $dir.'/autoload_classmap.php';
|
298 |
+
if ($classMap) {
|
299 |
+
$loader->addClassMap($classMap);
|
300 |
+
}
|
301 |
+
|
302 |
+
|
303 |
+
CLASSMAP;
|
304 |
+
}
|
305 |
+
|
306 |
+
if ($this->classMapAuthoritative) {
|
307 |
+
$file .= <<<'CLASSMAPAUTHORITATIVE'
|
308 |
+
$loader->setClassMapAuthoritative(true);
|
309 |
+
|
310 |
+
CLASSMAPAUTHORITATIVE;
|
311 |
+
}
|
312 |
+
|
313 |
+
if ($useGlobalIncludePath) {
|
314 |
+
$file .= <<<'INCLUDEPATH'
|
315 |
+
$loader->setUseIncludePath(true);
|
316 |
+
|
317 |
+
|
318 |
+
INCLUDEPATH;
|
319 |
+
}
|
320 |
+
|
321 |
+
if ($targetDirLoader) {
|
322 |
+
$file .= <<<REGISTER_AUTOLOAD
|
323 |
+
spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'autoload'), true);
|
324 |
+
|
325 |
+
|
326 |
+
REGISTER_AUTOLOAD;
|
327 |
+
|
328 |
+
}
|
329 |
+
|
330 |
+
$file .= <<<METHOD_FOOTER
|
331 |
+
\$loader->register($prependAutoloader);{$filesCode}
|
332 |
+
|
333 |
+
return \$loader;
|
334 |
+
}
|
335 |
+
|
336 |
+
METHOD_FOOTER;
|
337 |
+
|
338 |
+
$file .= $targetDirLoader;
|
339 |
+
|
340 |
+
return $file . <<<FOOTER
|
341 |
+
}
|
342 |
+
|
343 |
+
FOOTER;
|
344 |
+
|
345 |
+
}
|
346 |
+
}
|
vendor/xrstf/composer-php52/lib/xrstf/Composer52/ClassLoader.php
ADDED
@@ -0,0 +1,271 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de
|
4 |
+
*
|
5 |
+
* This file is released under the terms of the MIT license. You can find the
|
6 |
+
* complete text in the attached LICENSE file or online at:
|
7 |
+
*
|
8 |
+
* http://www.opensource.org/licenses/mit-license.php
|
9 |
+
*
|
10 |
+
* --------------------------------------------------------------------------
|
11 |
+
*
|
12 |
+
* 99% of this is copied as-is from the original Composer source code and is
|
13 |
+
* released under MIT license as well. Copyright goes to:
|
14 |
+
*
|
15 |
+
* - Fabien Potencier <fabien@symfony.com>
|
16 |
+
* - Jordi Boggiano <j.boggiano@seld.be>
|
17 |
+
*/
|
18 |
+
|
19 |
+
class xrstf_Composer52_ClassLoader {
|
20 |
+
private $prefixes = array();
|
21 |
+
private $fallbackDirs = array();
|
22 |
+
private $useIncludePath = false;
|
23 |
+
private $classMap = array();
|
24 |
+
private $classMapAuthoratative = false;
|
25 |
+
private $allowUnderscore = false;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @param boolean $flag true to allow class names with a leading underscore, false to disable
|
29 |
+
*/
|
30 |
+
public function setAllowUnderscore($flag) {
|
31 |
+
$this->allowUnderscore = (boolean) $flag;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return array
|
36 |
+
*/
|
37 |
+
public function getPrefixes() {
|
38 |
+
return $this->prefixes;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Turns off searching the prefix and fallback directories for classes
|
43 |
+
* that have not been registered with the class map.
|
44 |
+
*
|
45 |
+
* @param bool $classMapAuthoratative
|
46 |
+
*/
|
47 |
+
public function setClassMapAuthoritative($classMapAuthoratative) {
|
48 |
+
$this->classMapAuthoratative = $classMapAuthoratative;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Should class lookup fail if not found in the current class map?
|
53 |
+
*
|
54 |
+
* @return bool
|
55 |
+
*/
|
56 |
+
public function getClassMapAuthoratative() {
|
57 |
+
return $this->classMapAuthoratative;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @return array
|
62 |
+
*/
|
63 |
+
public function getFallbackDirs() {
|
64 |
+
return $this->fallbackDirs;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @return array
|
69 |
+
*/
|
70 |
+
public function getClassMap() {
|
71 |
+
return $this->classMap;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param array $classMap class to filename map
|
76 |
+
*/
|
77 |
+
public function addClassMap(array $classMap) {
|
78 |
+
if ($this->classMap) {
|
79 |
+
$this->classMap = array_merge($this->classMap, $classMap);
|
80 |
+
}
|
81 |
+
else {
|
82 |
+
$this->classMap = $classMap;
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Registers a set of classes, merging with any others previously set.
|
88 |
+
*
|
89 |
+
* @param string $prefix the classes prefix
|
90 |
+
* @param array|string $paths the location(s) of the classes
|
91 |
+
* @param bool $prepend prepend the location(s)
|
92 |
+
*/
|
93 |
+
public function add($prefix, $paths, $prepend = false) {
|
94 |
+
if (!$prefix) {
|
95 |
+
if ($prepend) {
|
96 |
+
$this->fallbackDirs = array_merge(
|
97 |
+
(array) $paths,
|
98 |
+
$this->fallbackDirs
|
99 |
+
);
|
100 |
+
}
|
101 |
+
else {
|
102 |
+
$this->fallbackDirs = array_merge(
|
103 |
+
$this->fallbackDirs,
|
104 |
+
(array) $paths
|
105 |
+
);
|
106 |
+
}
|
107 |
+
|
108 |
+
return;
|
109 |
+
}
|
110 |
+
|
111 |
+
if (!isset($this->prefixes[$prefix])) {
|
112 |
+
$this->prefixes[$prefix] = (array) $paths;
|
113 |
+
return;
|
114 |
+
}
|
115 |
+
|
116 |
+
if ($prepend) {
|
117 |
+
$this->prefixes[$prefix] = array_merge(
|
118 |
+
(array) $paths,
|
119 |
+
$this->prefixes[$prefix]
|
120 |
+
);
|
121 |
+
}
|
122 |
+
else {
|
123 |
+
$this->prefixes[$prefix] = array_merge(
|
124 |
+
$this->prefixes[$prefix],
|
125 |
+
(array) $paths
|
126 |
+
);
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Registers a set of classes, replacing any others previously set.
|
132 |
+
*
|
133 |
+
* @param string $prefix the classes prefix
|
134 |
+
* @param array|string $paths the location(s) of the classes
|
135 |
+
*/
|
136 |
+
public function set($prefix, $paths) {
|
137 |
+
if (!$prefix) {
|
138 |
+
$this->fallbackDirs = (array) $paths;
|
139 |
+
return;
|
140 |
+
}
|
141 |
+
|
142 |
+
$this->prefixes[$prefix] = (array) $paths;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Turns on searching the include path for class files.
|
147 |
+
*
|
148 |
+
* @param bool $useIncludePath
|
149 |
+
*/
|
150 |
+
public function setUseIncludePath($useIncludePath) {
|
151 |
+
$this->useIncludePath = $useIncludePath;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Can be used to check if the autoloader uses the include path to check
|
156 |
+
* for classes.
|
157 |
+
*
|
158 |
+
* @return bool
|
159 |
+
*/
|
160 |
+
public function getUseIncludePath() {
|
161 |
+
return $this->useIncludePath;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Registers this instance as an autoloader.
|
166 |
+
*/
|
167 |
+
public function register() {
|
168 |
+
spl_autoload_register(array($this, 'loadClass'), true);
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Unregisters this instance as an autoloader.
|
173 |
+
*/
|
174 |
+
public function unregister() {
|
175 |
+
spl_autoload_unregister(array($this, 'loadClass'));
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Loads the given class or interface.
|
180 |
+
*
|
181 |
+
* @param string $class the name of the class
|
182 |
+
* @return bool|null true, if loaded
|
183 |
+
*/
|
184 |
+
public function loadClass($class) {
|
185 |
+
if ($file = $this->findFile($class)) {
|
186 |
+
include $file;
|
187 |
+
return true;
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Finds the path to the file where the class is defined.
|
193 |
+
*
|
194 |
+
* @param string $class the name of the class
|
195 |
+
* @return string|null the path, if found
|
196 |
+
*/
|
197 |
+
public function findFile($class) {
|
198 |
+
if ('\\' === $class[0]) {
|
199 |
+
$class = substr($class, 1);
|
200 |
+
}
|
201 |
+
|
202 |
+
if (isset($this->classMap[$class])) {
|
203 |
+
return $this->classMap[$class];
|
204 |
+
}
|
205 |
+
elseif ($this->classMapAuthoratative) {
|
206 |
+
return false;
|
207 |
+
}
|
208 |
+
|
209 |
+
$classPath = $this->getClassPath($class);
|
210 |
+
|
211 |
+
foreach ($this->prefixes as $prefix => $dirs) {
|
212 |
+
if (0 === strpos($class, $prefix)) {
|
213 |
+
foreach ($dirs as $dir) {
|
214 |
+
if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) {
|
215 |
+
return $dir.DIRECTORY_SEPARATOR.$classPath;
|
216 |
+
}
|
217 |
+
}
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
foreach ($this->fallbackDirs as $dir) {
|
222 |
+
if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) {
|
223 |
+
return $dir.DIRECTORY_SEPARATOR.$classPath;
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
if ($this->useIncludePath && $file = self::resolveIncludePath($classPath)) {
|
228 |
+
return $file;
|
229 |
+
}
|
230 |
+
|
231 |
+
return $this->classMap[$class] = false;
|
232 |
+
}
|
233 |
+
|
234 |
+
private function getClassPath($class) {
|
235 |
+
if (false !== $pos = strrpos($class, '\\')) {
|
236 |
+
// namespaced class name
|
237 |
+
$classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)).DIRECTORY_SEPARATOR;
|
238 |
+
$className = substr($class, $pos + 1);
|
239 |
+
}
|
240 |
+
else {
|
241 |
+
// PEAR-like class name
|
242 |
+
$classPath = null;
|
243 |
+
$className = $class;
|
244 |
+
}
|
245 |
+
|
246 |
+
$className = str_replace('_', DIRECTORY_SEPARATOR, $className);
|
247 |
+
|
248 |
+
// restore the prefix
|
249 |
+
if ($this->allowUnderscore && DIRECTORY_SEPARATOR === $className[0]) {
|
250 |
+
$className[0] = '_';
|
251 |
+
}
|
252 |
+
|
253 |
+
$classPath .= $className.'.php';
|
254 |
+
|
255 |
+
return $classPath;
|
256 |
+
}
|
257 |
+
|
258 |
+
public static function resolveIncludePath($classPath) {
|
259 |
+
$paths = explode(PATH_SEPARATOR, get_include_path());
|
260 |
+
|
261 |
+
foreach ($paths as $path) {
|
262 |
+
$path = rtrim($path, '/\\');
|
263 |
+
|
264 |
+
if ($file = file_exists($path.DIRECTORY_SEPARATOR.$file)) {
|
265 |
+
return $file;
|
266 |
+
}
|
267 |
+
}
|
268 |
+
|
269 |
+
return false;
|
270 |
+
}
|
271 |
+
}
|
vendor/xrstf/composer-php52/lib/xrstf/Composer52/Generator.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de
|
4 |
+
*
|
5 |
+
* This file is released under the terms of the MIT license. You can find the
|
6 |
+
* complete text in the attached LICENSE file or online at:
|
7 |
+
*
|
8 |
+
* http://www.opensource.org/licenses/mit-license.php
|
9 |
+
*/
|
10 |
+
|
11 |
+
namespace xrstf\Composer52;
|
12 |
+
|
13 |
+
use Composer\Repository\CompositeRepository;
|
14 |
+
use Composer\Script\Event;
|
15 |
+
|
16 |
+
class Generator {
|
17 |
+
public static function onPostInstallCmd(Event $event) {
|
18 |
+
$composer = $event->getComposer();
|
19 |
+
$installationManager = $composer->getInstallationManager();
|
20 |
+
$repoManager = $composer->getRepositoryManager();
|
21 |
+
$localRepo = $repoManager->getLocalRepository();
|
22 |
+
$package = $composer->getPackage();
|
23 |
+
$config = $composer->getConfig();
|
24 |
+
|
25 |
+
// We can't gain access to the Command's input object, so we have to look
|
26 |
+
// for -o / --optimize-autoloader ourselves. Sadly, neither getopt() works
|
27 |
+
// (always returns an empty array), nor does Symfony's Console Input, as
|
28 |
+
// it expects a full definition of the current command line and we can't
|
29 |
+
// provide that.
|
30 |
+
|
31 |
+
$args = $_SERVER['argv'];
|
32 |
+
$optimize = in_array('-o', $args) || in_array('--optimize-autoloader', $args) || in_array('--optimize', $args);
|
33 |
+
|
34 |
+
$suffix = $config->get('autoloader-suffix');
|
35 |
+
|
36 |
+
$generator = new AutoloadGenerator();
|
37 |
+
$generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize, $suffix);
|
38 |
+
}
|
39 |
+
}
|
wp-staging.php
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
* Author: WP-STAGING
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi
|
10 |
-
* Version: 2.7.
|
11 |
* Text Domain: wp-staging
|
12 |
* Domain Path: /languages/
|
13 |
*
|
@@ -40,8 +40,16 @@ if (!defined('WPSTG_FREE_LOADED')) {
|
|
40 |
// Standalone requirement-checking script
|
41 |
require_once 'Requirements/WpstgFreeRequirements.php';
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
if (!class_exists('WpstgFreeBootstrap')) {
|
44 |
-
class WpstgFreeBootstrap
|
45 |
{
|
46 |
private $shouldBootstrap = true;
|
47 |
private $requirements;
|
@@ -71,18 +79,17 @@ if (!class_exists('WpstgFreeBootstrap')) {
|
|
71 |
return;
|
72 |
}
|
73 |
|
74 |
-
// Absolute path to plugin dir /var/www/.../plugins/wp-staging(-pro)
|
75 |
-
if (!defined('WPSTG_PLUGIN_DIR')) {
|
76 |
-
define('WPSTG_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
77 |
-
}
|
78 |
-
|
79 |
-
// Absolute path and name to main plugin entry file /var/www/.../plugins/wp-staging(-pro)/wp-staging(-pro).php
|
80 |
if (!defined('WPSTG_PLUGIN_FILE')) {
|
81 |
define('WPSTG_PLUGIN_FILE', __FILE__);
|
82 |
}
|
83 |
|
84 |
require_once(__DIR__ . '/_init.php');
|
85 |
}
|
|
|
|
|
|
|
|
|
|
|
86 |
}
|
87 |
}
|
88 |
|
@@ -90,3 +97,11 @@ $bootstrap = new WpstgFreeBootstrap(new WpstgFreeRequirements(__FILE__));
|
|
90 |
|
91 |
add_action('plugins_loaded', [$bootstrap, 'checkRequirements'], 5);
|
92 |
add_action('plugins_loaded', [$bootstrap, 'bootstrap'], 10);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
* Author: WP-STAGING
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi
|
10 |
+
* Version: 2.7.8
|
11 |
* Text Domain: wp-staging
|
12 |
* Domain Path: /languages/
|
13 |
*
|
40 |
// Standalone requirement-checking script
|
41 |
require_once 'Requirements/WpstgFreeRequirements.php';
|
42 |
|
43 |
+
if (!interface_exists('WpstgBootstrapInterface')) {
|
44 |
+
interface WpstgBootstrapInterface {
|
45 |
+
public function checkRequirements();
|
46 |
+
public function bootstrap();
|
47 |
+
public function passedRequirements();
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
if (!class_exists('WpstgFreeBootstrap')) {
|
52 |
+
class WpstgFreeBootstrap implements WpstgBootstrapInterface
|
53 |
{
|
54 |
private $shouldBootstrap = true;
|
55 |
private $requirements;
|
79 |
return;
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
if (!defined('WPSTG_PLUGIN_FILE')) {
|
83 |
define('WPSTG_PLUGIN_FILE', __FILE__);
|
84 |
}
|
85 |
|
86 |
require_once(__DIR__ . '/_init.php');
|
87 |
}
|
88 |
+
|
89 |
+
public function passedRequirements()
|
90 |
+
{
|
91 |
+
return $this->shouldBootstrap;
|
92 |
+
}
|
93 |
}
|
94 |
}
|
95 |
|
97 |
|
98 |
add_action('plugins_loaded', [$bootstrap, 'checkRequirements'], 5);
|
99 |
add_action('plugins_loaded', [$bootstrap, 'bootstrap'], 10);
|
100 |
+
|
101 |
+
/** Installation Hooks */
|
102 |
+
if (!class_exists('WPStaging\Install')) {
|
103 |
+
require_once __DIR__ . "/install.php";
|
104 |
+
|
105 |
+
$install = new \WPStaging\Install($bootstrap);
|
106 |
+
register_activation_hook(__FILE__, [$install, 'activation']);
|
107 |
+
}
|