Completed
Push — master ( 694826...a7f5ef )
by Ingo
26:11 queued 15:49
created

Core.php ➔ singleton()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 4
eloc 6
nc 8
nop 1
dl 0
loc 7
rs 9.2
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 36 and the first side effect is on line 23.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * This file is the Framework bootstrap.  It will get your environment ready to call Director::direct().
4
 *
5
 * It takes care of:
6
 *  - Including Constants.php to include _ss_environment and initialise necessary constants
7
 *  - Checking of PHP memory limit
8
 *  - Including all the files needed to get the manifest built
9
 *  - Building and including the manifest
10
 *
11
 * @todo This file currently contains a lot of bits and pieces, and its various responsibilities should probably be
12
 *       moved into different subsystems.
13
 * @todo A lot of this stuff is very order-dependent. This could be decoupled.
14
 *
15
 * @package framework
16
 * @subpackage core
17
 */
18
19
/**
20
 * All errors are reported, including E_STRICT by default *unless* the site is in
21
 * live mode, where reporting is limited to fatal errors and warnings (see later in this file)
22
 */
23
error_reporting(E_ALL | E_STRICT);
24
25
/**
26
 * Include Constants (if it hasn't already been included) to pull in BASE_PATH, etc
27
 */
28
require_once dirname(__FILE__).'/Constants.php';
29
30
global $_increase_time_limit_max;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
31
$_increase_time_limit_max = -1;
32
33
/**
34
 * Priorities definition. These constants are used in calls to _t() as an optional argument
35
 */
36
define('PR_HIGH',100);
37
define('PR_MEDIUM',50);
38
define('PR_LOW',10);
39
40
/**
41
 * Ensure we have enough memory
42
 */
43
increase_memory_limit_to('64M');
44
45
/**
46
 * Ensure we don't run into xdebug's fairly conservative infinite recursion protection limit
47
 */
48
increase_xdebug_nesting_level_to(200);
49
50
/**
51
 * Set default encoding
52
 */
53
mb_http_output('UTF-8');
54
mb_internal_encoding('UTF-8');
55
mb_regex_encoding('UTF-8');
56
57
/**
58
 * Enable better garbage collection
59
 */
60
gc_enable();
61
62
// Include the files needed the initial manifest building, as well as any files
63
// that are needed for the boostrap process on every request.
64
require_once 'cache/Cache.php';
65
require_once 'core/CustomMethods.php';
66
require_once 'core/Extensible.php';
67
require_once 'core/Injectable.php';
68
require_once 'core/Configurable.php';
69
require_once 'core/Object.php';
70
require_once 'core/ClassInfo.php';
71
require_once 'core/DAG.php';
72
require_once 'core/Config.php';
73
require_once 'view/TemplateGlobalProvider.php';
74
require_once 'control/Director.php';
75
require_once 'dev/Debug.php';
76
require_once 'dev/DebugView.php';
77
require_once 'dev/CliDebugView.php';
78
require_once 'dev/Backtrace.php';
79
require_once 'filesystem/FileFinder.php';
80
require_once 'core/manifest/ManifestCache.php';
81
require_once 'core/manifest/ClassLoader.php';
82
require_once 'core/manifest/ConfigManifest.php';
83
require_once 'core/manifest/ConfigStaticManifest.php';
84
require_once 'core/manifest/ClassManifest.php';
85
require_once 'core/manifest/ManifestFileFinder.php';
86
require_once 'core/manifest/TemplateLoader.php';
87
require_once 'core/manifest/TemplateManifest.php';
88
require_once 'core/manifest/TokenisedRegularExpression.php';
89
require_once 'control/injector/Injector.php';
90
91
// Initialise the dependency injector as soon as possible, as it is
92
// subsequently used by some of the following code
93
$injector = new Injector(array('locator' => 'SilverStripeServiceConfigurationLocator'));
94
Injector::set_inst($injector);
95
96
///////////////////////////////////////////////////////////////////////////////
97
// MANIFEST
98
99
// Regenerate the manifest if ?flush is set, or if the database is being built.
100
// The coupling is a hack, but it removes an annoying bug where new classes
101
// referenced in _config.php files can be referenced during the build process.
102
$requestURL = isset($_REQUEST['url']) ? trim($_REQUEST['url'], '/') : false;
103
$flush = (isset($_GET['flush']) || $requestURL === trim(BASE_URL . '/dev/build', '/'));
104
105
global $manifest;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
106
$manifest = new SS_ClassManifest(BASE_PATH, false, $flush);
107
108
// Register SilverStripe's class map autoload
109
$loader = SS_ClassLoader::instance();
110
$loader->registerAutoloader();
111
$loader->pushManifest($manifest);
112
113
// Fall back to Composer's autoloader (e.g. for PHPUnit), if composer is used
114
if(file_exists(BASE_PATH . '/vendor/autoload.php')) {
115
	require_once BASE_PATH . '/vendor/autoload.php';
116
}
117
118
// Now that the class manifest is up, load the static configuration
119
$configManifest = new SS_ConfigStaticManifest();
120
Config::inst()->pushConfigStaticManifest($configManifest);
121
122
// And then the yaml configuration
123
$configManifest = new SS_ConfigManifest(BASE_PATH, false, $flush);
124
Config::inst()->pushConfigYamlManifest($configManifest);
125
126
// Load template manifest
127
SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(
128
	BASE_PATH, project(), false, $flush
129
));
130
131
// If in live mode, ensure deprecation, strict and notices are not reported
132
if(Director::isLive()) {
133
	error_reporting(E_ALL & ~(E_DEPRECATED | E_STRICT | E_NOTICE));
134
}
135
136
///////////////////////////////////////////////////////////////////////////////
137
// POST-MANIFEST COMMANDS
138
139
/**
140
 * Load error handlers
141
 */
142
143
$errorHandler = Injector::inst()->get('ErrorHandler');
144
$errorHandler->start();
145
146
///////////////////////////////////////////////////////////////////////////////
147
// HELPER FUNCTIONS
148
149
/**
150
 * Creates a class instance by the "singleton" design pattern.
151
 * It will always return the same instance for this class,
152
 * which can be used for performance reasons and as a simple
153
 * way to access instance methods which don't rely on instance
154
 * data (e.g. the custom SilverStripe static handling).
155
 *
156
 * @param string $className
157
 * @return Object
158
 */
159
function singleton($className) {
160
	if($className == "Config") user_error("Don't pass Config to singleton()", E_USER_ERROR);
161
	if(!isset($className)) user_error("singleton() Called without a class", E_USER_ERROR);
162
	if(!is_string($className)) user_error("singleton() passed bad class_name: " . var_export($className,true),
163
		E_USER_ERROR);
164
	return Injector::inst()->get($className);
165
}
166
167
function project() {
168
	global $project;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
169
	return $project;
170
}
171
172
/**
173
 * @see i18n::_t()
174
 */
175
function _t($entity, $string = "", $context = "", $injection = "") {
176
	return i18n::_t($entity, $string, $context, $injection);
177
}
178
179
/**
180
 * Increase the memory limit to the given level if it's currently too low.
181
 * Only increases up to the maximum defined in {@link set_increase_memory_limit_max()},
182
 * and defaults to the 'memory_limit' setting in the PHP configuration.
183
 *
184
 * @param A memory limit string, such as "64M".  If omitted, unlimited memory will be set.
185
 * @return Boolean TRUE indicates a successful change, FALSE a denied change.
186
 */
187
function increase_memory_limit_to($memoryLimit = -1) {
188
	$curLimit = ini_get('memory_limit');
189
190
	// Can't go higher than infinite
191
	if($curLimit == -1 ) return true;
192
193
	// Check hard maximums
194
	$max = get_increase_memory_limit_max();
195
196
	if($max && $max != -1 && trANSLATE_MEMSTRING($memoryLimit) > translate_memstring($max)) return false;
197
198
	// Increase the memory limit if it's too low
199
	if($memoryLimit == -1 || translate_memstring($memoryLimit) > translate_memstring($curLimit)) {
200
		ini_set('memory_limit', $memoryLimit);
201
	}
202
203
	return true;
204
}
205
206
$_increase_memory_limit_max = ini_get('memory_limit');
207
208
/**
209
 * Set the maximum allowed value for {@link increase_memory_limit_to()}.
210
 * The same result can also be achieved through 'suhosin.memory_limit'
211
 * if PHP is running with the Suhosin system.
212
 *
213
 * @param Memory limit string
214
 */
215
function set_increase_memory_limit_max($memoryLimit) {
216
	global $_increase_memory_limit_max;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
217
	$_increase_memory_limit_max = $memoryLimit;
218
}
219
220
/**
221
 * @return Memory limit string
222
 */
223
function get_increase_memory_limit_max() {
224
	global $_increase_memory_limit_max;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
225
	return $_increase_memory_limit_max;
226
}
227
228
/**
229
 * Increases the XDebug parameter max_nesting_level, which limits how deep recursion can go.
230
 * Only does anything if (a) xdebug is installed and (b) the new limit is higher than the existing limit
231
 *
232
 * @param int $limit - The new limit to increase to
233
 */
234
function increase_xdebug_nesting_level_to($limit) {
235
	if (function_exists('xdebug_enable')) {
236
		$current = ini_get('xdebug.max_nesting_level');
237
		if ((int)$current < $limit) ini_set('xdebug.max_nesting_level', $limit);
238
	}
239
}
240
241
/**
242
 * Turn a memory string, such as 512M into an actual number of bytes.
243
 *
244
 * @param A memory limit string, such as "64M"
245
 */
246
function translate_memstring($memString) {
247
	switch(strtolower(substr($memString, -1))) {
248
		case "k": return round(substr($memString, 0, -1)*1024);
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
249
		case "m": return round(substr($memString, 0, -1)*1024*1024);
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
250
		case "g": return round(substr($memString, 0, -1)*1024*1024*1024);
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
251
		default: return round($memString);
0 ignored issues
show
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
252
	}
253
}
254
255
/**
256
 * Increase the time limit of this script. By default, the time will be unlimited.
257
 * Only works if 'safe_mode' is off in the PHP configuration.
258
 * Only values up to {@link get_increase_time_limit_max()} are allowed.
259
 *
260
 * @param $timeLimit The time limit in seconds.  If omitted, no time limit will be set.
261
 * @return Boolean TRUE indicates a successful change, FALSE a denied change.
262
 */
263
function increase_time_limit_to($timeLimit = null) {
264
	$max = get_increase_time_limit_max();
265
	if($max != -1 && $max != null && $timeLimit > $max) return false;
266
267
	if(!ini_get('safe_mode')) {
268
		if(!$timeLimit) {
269
			set_time_limit(0);
270
			return true;
271
		} else {
272
			$currTimeLimit = ini_get('max_execution_time');
273
			// Only increase if its smaller
274
			if($currTimeLimit && $currTimeLimit < $timeLimit) {
275
				set_time_limit($timeLimit);
276
			}
277
			return true;
278
		}
279
	} else {
280
		return false;
281
	}
282
}
283
284
/**
285
 * Set the maximum allowed value for {@link increase_timeLimit_to()};
286
 *
287
 * @param Int Limit in seconds
288
 */
289
function set_increase_time_limit_max($timeLimit) {
290
	global $_increase_time_limit_max;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
291
	$_increase_time_limit_max = $timeLimit;
292
}
293
294
/**
295
 * @return Int Limit in seconds
296
 */
297
function get_increase_time_limit_max() {
298
	global $_increase_time_limit_max;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
299
	return $_increase_time_limit_max;
300
}
301