GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — develop (#155)
by
unknown
08:46
created
myth/CIModules/database/libraries/Seeder.php 1 patch
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -39,92 +39,92 @@
 block discarded – undo
39 39
  */
40 40
 class Seeder {
41 41
 
42
-    public $error_string    = '';
42
+	public $error_string    = '';
43 43
 
44
-    protected $ci;
44
+	protected $ci;
45 45
 
46
-    protected $is_cli = false;
46
+	protected $is_cli = false;
47 47
 
48
-    protected $db;
49
-    protected $dbforge;
48
+	protected $db;
49
+	protected $dbforge;
50 50
 
51
-    //--------------------------------------------------------------------
51
+	//--------------------------------------------------------------------
52 52
 
53
-    public function __construct ()
54
-    {
55
-        $this->ci =& get_instance();
53
+	public function __construct ()
54
+	{
55
+		$this->ci =& get_instance();
56 56
 
57
-        $this->is_cli = $this->ci->input->is_cli_request();
57
+		$this->is_cli = $this->ci->input->is_cli_request();
58 58
 
59
-        if ($this->is_cli)
60
-        {
61
-            $cli = new CLI();
62
-            $cli::_init();
63
-        }
59
+		if ($this->is_cli)
60
+		{
61
+			$cli = new CLI();
62
+			$cli::_init();
63
+		}
64 64
 
65
-        $this->ci->load->dbforge();
65
+		$this->ci->load->dbforge();
66 66
 
67
-        // Setup some convenience vars.
68
-        $this->db       =& $this->ci->db;
69
-        $this->dbforge  =& $this->ci->dbforge;
70
-    }
67
+		// Setup some convenience vars.
68
+		$this->db       =& $this->ci->db;
69
+		$this->dbforge  =& $this->ci->dbforge;
70
+	}
71 71
 
72
-    //--------------------------------------------------------------------
72
+	//--------------------------------------------------------------------
73 73
 
74 74
 
75
-    /**
76
-     * Run the database seeds. It's where the magic happens.
77
-     * This method MUST be overridden by child classes.
78
-     */
79
-    public function run ()
80
-    {
75
+	/**
76
+	 * Run the database seeds. It's where the magic happens.
77
+	 * This method MUST be overridden by child classes.
78
+	 */
79
+	public function run ()
80
+	{
81 81
 
82
-    }
82
+	}
83 83
 
84
-    //--------------------------------------------------------------------
84
+	//--------------------------------------------------------------------
85 85
 
86
-    /**
87
-     * Loads the class file and calls the run() method
88
-     * on the class.
89
-     *
90
-     * @param $class
91
-     */
92
-    public function call ($class)
93
-    {
94
-        if (empty($class))
95
-        {
96
-            // Ask the user...
97
-            $class = trim( CLI::prompt("Seeder name") );
86
+	/**
87
+	 * Loads the class file and calls the run() method
88
+	 * on the class.
89
+	 *
90
+	 * @param $class
91
+	 */
92
+	public function call ($class)
93
+	{
94
+		if (empty($class))
95
+		{
96
+			// Ask the user...
97
+			$class = trim( CLI::prompt("Seeder name") );
98 98
 
99
-            if (empty($class)) {
100
-                return CLI::error("\tNo Seeder was specified.");
101
-            }
102
-        }
99
+			if (empty($class)) {
100
+				return CLI::error("\tNo Seeder was specified.");
101
+			}
102
+		}
103 103
 
104
-        $path = APPPATH .'database/seeds/'. str_replace('.php', '', $class) .'.php';
104
+		$path = APPPATH .'database/seeds/'. str_replace('.php', '', $class) .'.php';
105 105
 
106
-        if ( ! is_file($path))
107
-        {
108
-            return CLI::error("\tUnable to find seed class: ". $class);
109
-        }
106
+		if ( ! is_file($path))
107
+		{
108
+			return CLI::error("\tUnable to find seed class: ". $class);
109
+		}
110 110
 
111
-        try {
112
-            require $path;
111
+		try {
112
+			require $path;
113 113
 
114
-            $seeder = new $class();
114
+			$seeder = new $class();
115 115
 
116
-            $seeder->run();
116
+			$seeder->run();
117 117
 
118
-            unset($seeder);
119
-        }
120
-        catch (\Exception $e)
121
-        {
122
-            show_error($e->getMessage(), $e->getCode());
123
-        }
118
+			unset($seeder);
119
+		}
120
+		catch (\Exception $e)
121
+		{
122
+			show_error($e->getMessage(), $e->getCode());
123
+		}
124 124
 
125
-        return Cli::write("\tSeeded: $class", 'green');
126
-    }
125
+		return Cli::write("\tSeeded: $class", 'green');
126
+	}
127 127
 
128
-    //--------------------------------------------------------------------
128
+	//--------------------------------------------------------------------
129 129
 
130 130
 }
Please login to merge, or discard this patch.
myth/CIModules/docs/config/docs.php 1 patch
Indentation   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -57,8 +57,8 @@
 block discarded – undo
57 57
 | if realpath cannot find/read the folder.
58 58
 */
59 59
 $config['docs.folders'] = [
60
-    'application'   => APPPATH .'docs',
61
-    'developer'     => APPPATH .'../myth/_docs_src'
60
+	'application'   => APPPATH .'docs',
61
+	'developer'     => APPPATH .'../myth/_docs_src'
62 62
 ];
63 63
 
64 64
 /*
Please login to merge, or discard this patch.
myth/CIModules/forge/controllers/Forge.php 1 patch
Indentation   +168 added lines, -168 removed lines patch added patch discarded remove patch
@@ -34,133 +34,133 @@  discard block
 block discarded – undo
34 34
 
35 35
 class Forge extends \Myth\Controllers\CLIController {
36 36
 
37
-    public function __construct()
38
-    {
39
-        parent::__construct();
37
+	public function __construct()
38
+	{
39
+		parent::__construct();
40 40
 
41
-        $this->load->config('forge');
42
-    }
41
+		$this->load->config('forge');
42
+	}
43 43
 
44
-    //--------------------------------------------------------------------
44
+	//--------------------------------------------------------------------
45 45
 
46 46
 
47
-    public function _remap($method, $params)
48
-    {
49
-        if (method_exists($this, $method))
50
-        {
51
-            call_user_func_array( [$this, $method], $params);
52
-        }
53
-        else
54
-        {
55
-	        $params = array_merge([CLI::cli_string()], $params);
47
+	public function _remap($method, $params)
48
+	{
49
+		if (method_exists($this, $method))
50
+		{
51
+			call_user_func_array( [$this, $method], $params);
52
+		}
53
+		else
54
+		{
55
+			$params = array_merge([CLI::cli_string()], $params);
56 56
 
57
-            call_user_func_array( [$this, 'run'], $params);
58
-        }
59
-    }
57
+			call_user_func_array( [$this, 'run'], $params);
58
+		}
59
+	}
60 60
     
61
-    //--------------------------------------------------------------------
62
-
63
-    /**
64
-     * Overrides to implement dynamic description building based on
65
-     * scanning the collections and grabbing the information from
66
-     * 'forge.php' files.
67
-     */
68
-    public function index()
69
-    {
70
-        $collections = config_item('forge.collections');
71
-
72
-        if (! is_array($collections) || ! count($collections) )
73
-        {
74
-            return CLI::error('No generator collections found.');
75
-        }
76
-
77
-        // We loop through each collection scanning
78
-        // for any generator folders that have a
79
-        // 'forge.php' file. For each one found
80
-        // we build out another section in our help commands
81
-        foreach ($collections as $alias => $path)
82
-        {
83
-            $path = rtrim($path, '/ ') .'/';
84
-            $folders = scandir($path);
85
-
86
-            $_descriptions = [];
87
-
88
-            foreach ($folders as $dir)
89
-            {
90
-                if ($dir == '.' || $dir == '..' || ! is_file($path . $dir .'/forge.php'))
91
-                {
92
-                    continue;
93
-                }
94
-
95
-                include $path . $dir .'/forge.php';
96
-
97
-                // Don't have valid arrays to work with? Move along...
98
-                if (! isset($descriptions))
99
-                {
100
-                    log_message('debug', '[Forge] Invalid forge.php file at: '. $path . $dir .'/forge.php');
101
-                    continue;
102
-                }
103
-
104
-                $_descriptions = array_merge($descriptions, $_descriptions);
105
-            }
106
-
107
-	        ksort($_descriptions);
108
-
109
-            CLI::new_line();
110
-            CLI::write(ucwords( str_replace('_', ' ', $alias)) .' Collection');
111
-            $this->sayDescriptions($_descriptions);
112
-        }
113
-    }
114
-
115
-    //--------------------------------------------------------------------
116
-
117
-    /**
118
-     * The primary method that calls the correct generator and
119
-     * makes it run.
120
-     */
121
-    public function run($command)
122
-    {
123
-	    $quiet = false;
124
-
125
-	    $segments = explode(" ", $command);
126
-
127
-	    // Get rid of the 'forge' command
128
-	    if ($segments[0] == 'forge') {
129
-		    array_shift( $segments );
130
-	    }
131
-
132
-	    $command = trim(str_ireplace("forge", '', array_shift($segments)));
61
+	//--------------------------------------------------------------------
62
+
63
+	/**
64
+	 * Overrides to implement dynamic description building based on
65
+	 * scanning the collections and grabbing the information from
66
+	 * 'forge.php' files.
67
+	 */
68
+	public function index()
69
+	{
70
+		$collections = config_item('forge.collections');
71
+
72
+		if (! is_array($collections) || ! count($collections) )
73
+		{
74
+			return CLI::error('No generator collections found.');
75
+		}
76
+
77
+		// We loop through each collection scanning
78
+		// for any generator folders that have a
79
+		// 'forge.php' file. For each one found
80
+		// we build out another section in our help commands
81
+		foreach ($collections as $alias => $path)
82
+		{
83
+			$path = rtrim($path, '/ ') .'/';
84
+			$folders = scandir($path);
85
+
86
+			$_descriptions = [];
87
+
88
+			foreach ($folders as $dir)
89
+			{
90
+				if ($dir == '.' || $dir == '..' || ! is_file($path . $dir .'/forge.php'))
91
+				{
92
+					continue;
93
+				}
94
+
95
+				include $path . $dir .'/forge.php';
96
+
97
+				// Don't have valid arrays to work with? Move along...
98
+				if (! isset($descriptions))
99
+				{
100
+					log_message('debug', '[Forge] Invalid forge.php file at: '. $path . $dir .'/forge.php');
101
+					continue;
102
+				}
103
+
104
+				$_descriptions = array_merge($descriptions, $_descriptions);
105
+			}
106
+
107
+			ksort($_descriptions);
108
+
109
+			CLI::new_line();
110
+			CLI::write(ucwords( str_replace('_', ' ', $alias)) .' Collection');
111
+			$this->sayDescriptions($_descriptions);
112
+		}
113
+	}
114
+
115
+	//--------------------------------------------------------------------
116
+
117
+	/**
118
+	 * The primary method that calls the correct generator and
119
+	 * makes it run.
120
+	 */
121
+	public function run($command)
122
+	{
123
+		$quiet = false;
124
+
125
+		$segments = explode(" ", $command);
126
+
127
+		// Get rid of the 'forge' command
128
+		if ($segments[0] == 'forge') {
129
+			array_shift( $segments );
130
+		}
131
+
132
+		$command = trim(str_ireplace("forge", '', array_shift($segments)));
133 133
 
134 134
 		$dir = $this->locateGenerator($command);
135 135
 
136 136
 		$class_name = ucfirst($command) .'Generator';
137 137
 
138
-	    if (! file_exists($dir . $class_name .'.php'))
139
-	    {
140
-		    return CLI::error("Generator file not found for: {$class_name}");
141
-	    }
138
+		if (! file_exists($dir . $class_name .'.php'))
139
+		{
140
+			return CLI::error("Generator file not found for: {$class_name}");
141
+		}
142 142
 
143 143
 		require_once $dir . $class_name .'.php';
144 144
 
145
-	    if (! class_exists($class_name, false))
146
-	    {
147
-		    return CLI::error("No class `{$class_name}` found in generator file.");
148
-	    }
145
+		if (! class_exists($class_name, false))
146
+		{
147
+			return CLI::error("No class `{$class_name}` found in generator file.");
148
+		}
149 149
 
150
-	    // Should we run the process quietly?
151
-	    if ( (CLI::option('q') || CLI::option('quiet')))
152
-	    {
153
-		    $quiet = true;
154
-	    }
150
+		// Should we run the process quietly?
151
+		if ( (CLI::option('q') || CLI::option('quiet')))
152
+		{
153
+			$quiet = true;
154
+		}
155 155
 
156
-	    CLI::write('Invoked '. CLI::color($class_name, 'yellow'));
156
+		CLI::write('Invoked '. CLI::color($class_name, 'yellow'));
157 157
 
158 158
 		$class = new $class_name();
159 159
 
160
-	    $class->run( $segments, $quiet );
161
-    }
160
+		$class->run( $segments, $quiet );
161
+	}
162 162
 
163
-    //--------------------------------------------------------------------
163
+	//--------------------------------------------------------------------
164 164
 
165 165
 	/**
166 166
 	 * Displays the readme file for a generator if it exists.
@@ -205,67 +205,67 @@  discard block
 block discarded – undo
205 205
 	//--------------------------------------------------------------------
206 206
 
207 207
 
208
-    /**
209
-     * Overrides CLIController's version to support searching our
210
-     * collections for the help description.
211
-     *
212
-     * @param null $method
213
-     */
214
-    public function longDescribeMethod($method=null)
215
-    {
216
-	    $collections = config_item('forge.collections');
217
-
218
-	    if (! is_array($collections) || ! count($collections) )
219
-	    {
220
-		    return CLI::error('No generator collections found.');
221
-	    }
222
-
223
-	    // We loop through each collection scanning
224
-	    // for any generator folders that have a
225
-	    // 'forge.php' file. For each one found
226
-	    // we build out another section in our help commands
227
-	    foreach ($collections as $alias => $path)
228
-	    {
229
-
230
-		    $path = rtrim($path, '/ ') .'/';
231
-		    $folders = scandir($path);
232
-
233
-		    if (! $i = array_search(ucfirst($method), $folders))
234
-		    {
235
-			    continue;
236
-		    }
237
-
238
-		    $dir = $path . $folders[$i] .'/';
239
-
240
-		    if (! is_file($dir .'/forge.php'))
241
-		    {
242
-			    CLI::error("The {$method} command does not have any cli help available.");
243
-		    }
244
-
245
-		    include $dir .'/forge.php';
246
-
247
-		    // Don't have valid arrays to work with? Move along...
248
-		    if (! isset($long_description))
249
-		    {
250
-			    log_message('debug', '[Forge] Invalid forge.php file at: '. $dir .'/forge.php');
251
-			    continue;
252
-		    }
253
-
254
-		    if (empty($long_description))
255
-		    {
256
-			    return CLI::error("The {$method} command does not have an cli help available.");
257
-		    }
258
-
259
-		    CLI::new_line();
260
-		    CLI::write( CLI::color(ucfirst($method) .' Help', 'yellow') );
261
-		    return CLI::write( CLI::wrap($long_description, CLI::getWidth()) );
262
-	    }
263
-
264
-	    // Still here?
265
-	    CLI::error("No help found for command: {$method}");
266
-    }
267
-
268
-    //--------------------------------------------------------------------
208
+	/**
209
+	 * Overrides CLIController's version to support searching our
210
+	 * collections for the help description.
211
+	 *
212
+	 * @param null $method
213
+	 */
214
+	public function longDescribeMethod($method=null)
215
+	{
216
+		$collections = config_item('forge.collections');
217
+
218
+		if (! is_array($collections) || ! count($collections) )
219
+		{
220
+			return CLI::error('No generator collections found.');
221
+		}
222
+
223
+		// We loop through each collection scanning
224
+		// for any generator folders that have a
225
+		// 'forge.php' file. For each one found
226
+		// we build out another section in our help commands
227
+		foreach ($collections as $alias => $path)
228
+		{
229
+
230
+			$path = rtrim($path, '/ ') .'/';
231
+			$folders = scandir($path);
232
+
233
+			if (! $i = array_search(ucfirst($method), $folders))
234
+			{
235
+				continue;
236
+			}
237
+
238
+			$dir = $path . $folders[$i] .'/';
239
+
240
+			if (! is_file($dir .'/forge.php'))
241
+			{
242
+				CLI::error("The {$method} command does not have any cli help available.");
243
+			}
244
+
245
+			include $dir .'/forge.php';
246
+
247
+			// Don't have valid arrays to work with? Move along...
248
+			if (! isset($long_description))
249
+			{
250
+				log_message('debug', '[Forge] Invalid forge.php file at: '. $dir .'/forge.php');
251
+				continue;
252
+			}
253
+
254
+			if (empty($long_description))
255
+			{
256
+				return CLI::error("The {$method} command does not have an cli help available.");
257
+			}
258
+
259
+			CLI::new_line();
260
+			CLI::write( CLI::color(ucfirst($method) .' Help', 'yellow') );
261
+			return CLI::write( CLI::wrap($long_description, CLI::getWidth()) );
262
+		}
263
+
264
+		// Still here?
265
+		CLI::error("No help found for command: {$method}");
266
+	}
267
+
268
+	//--------------------------------------------------------------------
269 269
 
270 270
 	/**
271 271
 	 * Scans through the collections for the folder for this generator.
Please login to merge, or discard this patch.
myth/Controllers/BaseController.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -100,7 +100,7 @@  discard block
 block discarded – undo
100 100
 	{
101 101
 		parent::__construct();
102 102
 
103
-        $this->load->library('session');
103
+		$this->load->library('session');
104 104
 
105 105
 		$this->setupCache();
106 106
 
@@ -236,8 +236,8 @@  discard block
 block discarded – undo
236 236
 		}
237 237
 
238 238
 		$this->output->enable_profiler( FALSE )
239
-		             ->set_content_type( 'text/plain' )
240
-		             ->set_output( $text );
239
+					 ->set_content_type( 'text/plain' )
240
+					 ->set_output( $text );
241 241
 	}
242 242
 
243 243
 	//--------------------------------------------------------------------
@@ -267,8 +267,8 @@  discard block
 block discarded – undo
267 267
 		}
268 268
 
269 269
 		$this->output->enable_profiler( FALSE )
270
-		             ->set_content_type( 'application/json' )
271
-		             ->set_output( json_encode( $json ) );
270
+					 ->set_content_type( 'application/json' )
271
+					 ->set_output( json_encode( $json ) );
272 272
 	}
273 273
 
274 274
 	//--------------------------------------------------------------------
@@ -292,8 +292,8 @@  discard block
 block discarded – undo
292 292
 		}
293 293
 
294 294
 		$this->output->enable_profiler( FALSE )
295
-		             ->set_content_type( 'application/x-javascript' )
296
-		             ->set_output( $js );
295
+					 ->set_content_type( 'application/x-javascript' )
296
+					 ->set_output( $js );
297 297
 	}
298 298
 
299 299
 	//--------------------------------------------------------------------
Please login to merge, or discard this patch.
myth/Controllers/ThemedController.php 1 patch
Indentation   +353 added lines, -353 removed lines patch added patch discarded remove patch
@@ -41,358 +41,358 @@
 block discarded – undo
41 41
  */
42 42
 class ThemedController extends BaseController
43 43
 {
44
-    /**
45
-     * Stores data variables to be sent to the view.
46
-     * @var array
47
-     */
48
-    protected $vars = array();
49
-
50
-    /**
51
-     * Stores current status message.
52
-     * @var
53
-     */
54
-    protected $message;
55
-
56
-    /**
57
-     * The UIKit to make available to the template views.
58
-     * @var string
59
-     */
60
-    protected $uikit = '';
61
-
62
-    /**
63
-     * An instance of an active Themer to use.
64
-     * @var null
65
-     */
66
-    protected $themer = null;
67
-
68
-    /**
69
-     * Allows per-controller override of theme.
70
-     * @var null
71
-     */
72
-    protected $theme = null;
73
-
74
-    /**
75
-     * Per-controller override of the current layout file.
76
-     * @var null
77
-     */
78
-    protected $layout = null;
79
-
80
-    /**
81
-     * Stores an array of javascript files.
82
-     * @var array
83
-     */
84
-    protected $external_scripts = array();
85
-
86
-    /**
87
-     * Stores an array of CSS stylesheets.
88
-     * @var array
89
-     */
90
-    protected $stylesheets = array();
91
-
92
-    /**
93
-     * A MenuCollection instance
94
-     * @var
95
-     */
96
-    protected $meta;
97
-
98
-    /**
99
-     * Whether set() should escape the output...
100
-     * @var bool
101
-     */
102
-    protected $auto_escape = null;
103
-
104
-    /**
105
-     * An instance of ZendFrameworks Escaper
106
-     * @var null
107
-     */
108
-    protected $escaper = null;
109
-
110
-    //--------------------------------------------------------------------
111
-
112
-    /**
113
-     * Constructor takes care of getting the template engine up and running
114
-     * and bound to our DI object, as well as any other preliminary needs,
115
-     * like detecting the variant to use, etc.
116
-     */
117
-    public function __construct()
118
-    {
119
-        parent::__construct();
120
-
121
-        // Setup our Template Engine
122
-        $themer = config_item('active_themer');
123
-
124
-        if (empty($themer)) {
125
-            throw new \RuntimeException( lang('no_themer') );
126
-        }
127
-
128
-        $this->themer = new $themer( get_instance() );
129
-
130
-        // Register our paths with the themer
131
-        $paths = config_item('theme.paths');
132
-
133
-        foreach ($paths as $key => $path) {
134
-            $this->themer->addThemePath($key, $path);
135
-        }
136
-
137
-        // Set our default theme.
138
-        $this->themer->setDefaultTheme( config_item('theme.default_theme') );
139
-
140
-        // Register our variants with the engine.
141
-        $variants = config_item('theme.variants');
142
-
143
-        foreach ($variants as $key => $value) {
144
-            $this->themer->addVariant($key, $value);
145
-        }
146
-
147
-        $this->detectVariant();
148
-
149
-        // Ensure that our UIKit is loaded up if we're using one.
150
-        $uikit = config_item('theme.uikit');
151
-
152
-        if ($uikit)
153
-        {
154
-            $this->uikit = new $uikit();
155
-        }
156
-
157
-        // Load up our meta collection
158
-        $this->meta = new MetaCollection( get_instance() );
159
-
160
-        // Should we autoescape vars?
161
-        if (is_null($this->auto_escape))
162
-        {
163
-            $this->auto_escape = config_item( 'theme.auto_escape' );
164
-        }
165
-    }
166
-
167
-    //--------------------------------------------------------------------
168
-
169
-    /**
170
-     * Provides a common interface with the other rendering methods to
171
-     * set the output of the method. Uses the current instance of $this->template.
172
-     * Ensures that any data we've stored through $this->setVar() are present
173
-     * and includes the status messages into the data.
174
-     *
175
-     * @param array $data
176
-     * @param int   $cache_time
177
-     */
178
-    public function render($data = array(), $cache_time=0)
179
-    {
180
-	    if ($cache_time > 0)
181
-	    {
182
-		    $this->output->cache( (int)$cache_time );
183
-	    }
184
-
185
-        // Determine the correct theme to use
186
-        $theme = ! empty($this->theme) ? $this->theme : config_item('theme.default_theme');
187
-        $this->themer->setTheme($theme);
188
-
189
-        // Determine the correct layout to use
190
-        $layout = !empty($this->layout) ? $this->layout : null;
191
-        $this->themer->setLayout($layout);
192
-
193
-        // Merge any saved vars into the data
194
-        // But first, escape the data if needed
195
-        if ($this->auto_escape)
196
-        {
197
-            $data = esc($data, 'html');
198
-        }
199
-        $data = array_merge($data, $this->vars);
200
-
201
-        // Make sure the MetaCollection is available in the view.
202
-        $data['html_meta'] = $this->meta;
203
-
204
-        // Include our UIKit so views can use it
205
-        if (! empty($this->uikit)) {
206
-            $data['uikit'] = $this->uikit;
207
-        }
208
-
209
-        // Build our notices from the theme's view file.
210
-        $data['notice'] = $this->themer->display($this->themer->theme() . ':notice', ["notice" => $this->message()]);
211
-
212
-        // Make sure any scripts/stylesheets are available to the view
213
-        $data['external_scripts'] = $this->external_scripts;
214
-        $data['stylesheets'] = $this->stylesheets;
215
-
216
-        $this->themer->set($data);
217
-
218
-        $this->output->set_content_type('html')
219
-                     ->set_output($this->themer->render());
220
-    }
221
-
222
-    //--------------------------------------------------------------------
223
-
224
-    /**
225
-     * Sets a data variable to be sent to the view during the render() method.
226
-     * Will auto-escape data on the way in, unless specifically told not to.
227
-     *
228
-     * Uses ZendFramework's Escaper to handle the data escaping,
229
-     * based on context. Valid contexts are:
230
-     *      - html
231
-     *      - htmlAttr
232
-     *      - js
233
-     *      - css
234
-     *      - url
235
-     *
236
-     * @param string $name
237
-     * @param mixed $value
238
-     * @param string $context
239
-     * @param bool $do_escape
240
-     */
241
-    public function setVar($name, $value = null, $context='html', $do_escape=null)
242
-    {
243
-        $escape = $do_escape == true ? true : $this->auto_escape;
244
-
245
-        if (is_null($this->escaper))
246
-        {
247
-            $this->escaper = new Escaper(config_item('charset'));
248
-        }
249
-
250
-        if (is_array($name))
251
-        {
252
-            foreach ($name as $k => $v)
253
-            {
254
-                $this->vars[$k] = $escape ? esc($v, $context, $this->escaper) : $v;
255
-            }
256
-        }
257
-        else
258
-        {
259
-            $this->vars[$name] = $escape ? esc($value, $context, $this->escaper) : $value;
260
-        }
261
-    }
262
-
263
-    //--------------------------------------------------------------------
264
-
265
-    //--------------------------------------------------------------------
266
-    // Status Messages
267
-    //--------------------------------------------------------------------
268
-
269
-    /**
270
-     * Sets a status message (for displaying small success/error messages).
271
-     * This is used in place of the session->flashdata functions since you
272
-     * don't always want to have to refresh the page to show the message.
273
-     *
274
-     * @param string $message The message to save.
275
-     * @param string $type The string to be included as the CSS class of the containing div.
276
-     */
277
-    public function setMessage($message = '', $type = 'info')
278
-    {
279
-        if (! empty($message)) {
280
-            if (isset($this->session)) {
281
-                $this->session->set_flashdata('message', $type . '::' . $message);
282
-            }
283
-
284
-            $this->message = array(
285
-                'type' => $type,
286
-                'message' => $message
287
-            );
288
-        }
289
-    }
290
-
291
-    //--------------------------------------------------------------------
292
-
293
-    /**
294
-     * Retrieves the status message to display (if any).
295
-     *
296
-     * @param  string $message [description]
297
-     * @param  string $type [description]
298
-     * @return array
299
-     */
300
-    public function message($message = '', $type = 'info')
301
-    {
302
-        $return = array(
303
-            'message' => $message,
304
-            'type' => $type
305
-        );
306
-
307
-        // Does session data exist?
308
-        if (empty($message) && class_exists('CI_Session')) {
309
-            $message = $this->session->flashdata('message');
310
-
311
-            if (! empty($message)) {
312
-                // Split out our message parts
313
-                $temp_message = explode('::', $message);
314
-                $return['type'] = $temp_message[0];
315
-                $return['message'] = $temp_message[1];
316
-
317
-                unset($temp_message);
318
-            }
319
-        }
320
-
321
-        // If message is empty, we need to check our own storage.
322
-        if (empty($message)) {
323
-            if (empty($this->message['message'])) {
324
-                return '';
325
-            }
326
-
327
-            $return = $this->message;
328
-        }
329
-
330
-        // Clear our session data so we don't get extra messages on rare occasions.
331
-        if (class_exists('CI_Session')) {
332
-            $this->session->set_flashdata('message', '');
333
-        }
334
-
335
-        return $return;
336
-    }
337
-
338
-    //--------------------------------------------------------------------
339
-
340
-    //--------------------------------------------------------------------
341
-    // Utility Methods
342
-    //--------------------------------------------------------------------
343
-
344
-    /**
345
-     * Detects whether the item is being displayed on a desktop, phone,
346
-     * or tablet device.
347
-     */
348
-    protected function detectVariant()
349
-    {
350
-        // Variant Detection and setup
351
-        if (config_item('autodetect_variant') === true) {
352
-            $detect = new \Mobile_Detect();
353
-
354
-            if ($detect->isMobile()) {
355
-                $this->template->setVariant('phone');
356
-            } else if ($detect->isTablet()) {
357
-                $this->template->setVariant('tablet');
358
-            }
359
-        }
360
-    }
361
-
362
-    //--------------------------------------------------------------------
363
-
364
-    //--------------------------------------------------------------------
365
-    // 'Asset' functions
366
-    //--------------------------------------------------------------------
367
-
368
-    /**
369
-     * Adds an external javascript file to the 'external_scripts' array.
370
-     *
371
-     * @param [type] $filename [description]
372
-     */
373
-    public function addScript($filename)
374
-    {
375
-        if (strpos($filename, 'http') === FALSE) {
376
-            $filename = base_url() . 'assets/js/' . $filename;
377
-        }
378
-
379
-        $this->external_scripts[] = $filename;
380
-    }
381
-
382
-    //--------------------------------------------------------------------
383
-
384
-    /**
385
-     * Adds an external stylesheet file to the 'stylesheets' array.
386
-     */
387
-    public function addStyle($filename)
388
-    {
389
-        if (strpos($filename, 'http') === FALSE) {
390
-            $filename = base_url() . 'assets/css/' . $filename;
391
-        }
392
-
393
-        $this->stylesheets[] = $filename;
394
-    }
395
-
396
-    //--------------------------------------------------------------------
44
+	/**
45
+	 * Stores data variables to be sent to the view.
46
+	 * @var array
47
+	 */
48
+	protected $vars = array();
49
+
50
+	/**
51
+	 * Stores current status message.
52
+	 * @var
53
+	 */
54
+	protected $message;
55
+
56
+	/**
57
+	 * The UIKit to make available to the template views.
58
+	 * @var string
59
+	 */
60
+	protected $uikit = '';
61
+
62
+	/**
63
+	 * An instance of an active Themer to use.
64
+	 * @var null
65
+	 */
66
+	protected $themer = null;
67
+
68
+	/**
69
+	 * Allows per-controller override of theme.
70
+	 * @var null
71
+	 */
72
+	protected $theme = null;
73
+
74
+	/**
75
+	 * Per-controller override of the current layout file.
76
+	 * @var null
77
+	 */
78
+	protected $layout = null;
79
+
80
+	/**
81
+	 * Stores an array of javascript files.
82
+	 * @var array
83
+	 */
84
+	protected $external_scripts = array();
85
+
86
+	/**
87
+	 * Stores an array of CSS stylesheets.
88
+	 * @var array
89
+	 */
90
+	protected $stylesheets = array();
91
+
92
+	/**
93
+	 * A MenuCollection instance
94
+	 * @var
95
+	 */
96
+	protected $meta;
97
+
98
+	/**
99
+	 * Whether set() should escape the output...
100
+	 * @var bool
101
+	 */
102
+	protected $auto_escape = null;
103
+
104
+	/**
105
+	 * An instance of ZendFrameworks Escaper
106
+	 * @var null
107
+	 */
108
+	protected $escaper = null;
109
+
110
+	//--------------------------------------------------------------------
111
+
112
+	/**
113
+	 * Constructor takes care of getting the template engine up and running
114
+	 * and bound to our DI object, as well as any other preliminary needs,
115
+	 * like detecting the variant to use, etc.
116
+	 */
117
+	public function __construct()
118
+	{
119
+		parent::__construct();
120
+
121
+		// Setup our Template Engine
122
+		$themer = config_item('active_themer');
123
+
124
+		if (empty($themer)) {
125
+			throw new \RuntimeException( lang('no_themer') );
126
+		}
127
+
128
+		$this->themer = new $themer( get_instance() );
129
+
130
+		// Register our paths with the themer
131
+		$paths = config_item('theme.paths');
132
+
133
+		foreach ($paths as $key => $path) {
134
+			$this->themer->addThemePath($key, $path);
135
+		}
136
+
137
+		// Set our default theme.
138
+		$this->themer->setDefaultTheme( config_item('theme.default_theme') );
139
+
140
+		// Register our variants with the engine.
141
+		$variants = config_item('theme.variants');
142
+
143
+		foreach ($variants as $key => $value) {
144
+			$this->themer->addVariant($key, $value);
145
+		}
146
+
147
+		$this->detectVariant();
148
+
149
+		// Ensure that our UIKit is loaded up if we're using one.
150
+		$uikit = config_item('theme.uikit');
151
+
152
+		if ($uikit)
153
+		{
154
+			$this->uikit = new $uikit();
155
+		}
156
+
157
+		// Load up our meta collection
158
+		$this->meta = new MetaCollection( get_instance() );
159
+
160
+		// Should we autoescape vars?
161
+		if (is_null($this->auto_escape))
162
+		{
163
+			$this->auto_escape = config_item( 'theme.auto_escape' );
164
+		}
165
+	}
166
+
167
+	//--------------------------------------------------------------------
168
+
169
+	/**
170
+	 * Provides a common interface with the other rendering methods to
171
+	 * set the output of the method. Uses the current instance of $this->template.
172
+	 * Ensures that any data we've stored through $this->setVar() are present
173
+	 * and includes the status messages into the data.
174
+	 *
175
+	 * @param array $data
176
+	 * @param int   $cache_time
177
+	 */
178
+	public function render($data = array(), $cache_time=0)
179
+	{
180
+		if ($cache_time > 0)
181
+		{
182
+			$this->output->cache( (int)$cache_time );
183
+		}
184
+
185
+		// Determine the correct theme to use
186
+		$theme = ! empty($this->theme) ? $this->theme : config_item('theme.default_theme');
187
+		$this->themer->setTheme($theme);
188
+
189
+		// Determine the correct layout to use
190
+		$layout = !empty($this->layout) ? $this->layout : null;
191
+		$this->themer->setLayout($layout);
192
+
193
+		// Merge any saved vars into the data
194
+		// But first, escape the data if needed
195
+		if ($this->auto_escape)
196
+		{
197
+			$data = esc($data, 'html');
198
+		}
199
+		$data = array_merge($data, $this->vars);
200
+
201
+		// Make sure the MetaCollection is available in the view.
202
+		$data['html_meta'] = $this->meta;
203
+
204
+		// Include our UIKit so views can use it
205
+		if (! empty($this->uikit)) {
206
+			$data['uikit'] = $this->uikit;
207
+		}
208
+
209
+		// Build our notices from the theme's view file.
210
+		$data['notice'] = $this->themer->display($this->themer->theme() . ':notice', ["notice" => $this->message()]);
211
+
212
+		// Make sure any scripts/stylesheets are available to the view
213
+		$data['external_scripts'] = $this->external_scripts;
214
+		$data['stylesheets'] = $this->stylesheets;
215
+
216
+		$this->themer->set($data);
217
+
218
+		$this->output->set_content_type('html')
219
+					 ->set_output($this->themer->render());
220
+	}
221
+
222
+	//--------------------------------------------------------------------
223
+
224
+	/**
225
+	 * Sets a data variable to be sent to the view during the render() method.
226
+	 * Will auto-escape data on the way in, unless specifically told not to.
227
+	 *
228
+	 * Uses ZendFramework's Escaper to handle the data escaping,
229
+	 * based on context. Valid contexts are:
230
+	 *      - html
231
+	 *      - htmlAttr
232
+	 *      - js
233
+	 *      - css
234
+	 *      - url
235
+	 *
236
+	 * @param string $name
237
+	 * @param mixed $value
238
+	 * @param string $context
239
+	 * @param bool $do_escape
240
+	 */
241
+	public function setVar($name, $value = null, $context='html', $do_escape=null)
242
+	{
243
+		$escape = $do_escape == true ? true : $this->auto_escape;
244
+
245
+		if (is_null($this->escaper))
246
+		{
247
+			$this->escaper = new Escaper(config_item('charset'));
248
+		}
249
+
250
+		if (is_array($name))
251
+		{
252
+			foreach ($name as $k => $v)
253
+			{
254
+				$this->vars[$k] = $escape ? esc($v, $context, $this->escaper) : $v;
255
+			}
256
+		}
257
+		else
258
+		{
259
+			$this->vars[$name] = $escape ? esc($value, $context, $this->escaper) : $value;
260
+		}
261
+	}
262
+
263
+	//--------------------------------------------------------------------
264
+
265
+	//--------------------------------------------------------------------
266
+	// Status Messages
267
+	//--------------------------------------------------------------------
268
+
269
+	/**
270
+	 * Sets a status message (for displaying small success/error messages).
271
+	 * This is used in place of the session->flashdata functions since you
272
+	 * don't always want to have to refresh the page to show the message.
273
+	 *
274
+	 * @param string $message The message to save.
275
+	 * @param string $type The string to be included as the CSS class of the containing div.
276
+	 */
277
+	public function setMessage($message = '', $type = 'info')
278
+	{
279
+		if (! empty($message)) {
280
+			if (isset($this->session)) {
281
+				$this->session->set_flashdata('message', $type . '::' . $message);
282
+			}
283
+
284
+			$this->message = array(
285
+				'type' => $type,
286
+				'message' => $message
287
+			);
288
+		}
289
+	}
290
+
291
+	//--------------------------------------------------------------------
292
+
293
+	/**
294
+	 * Retrieves the status message to display (if any).
295
+	 *
296
+	 * @param  string $message [description]
297
+	 * @param  string $type [description]
298
+	 * @return array
299
+	 */
300
+	public function message($message = '', $type = 'info')
301
+	{
302
+		$return = array(
303
+			'message' => $message,
304
+			'type' => $type
305
+		);
306
+
307
+		// Does session data exist?
308
+		if (empty($message) && class_exists('CI_Session')) {
309
+			$message = $this->session->flashdata('message');
310
+
311
+			if (! empty($message)) {
312
+				// Split out our message parts
313
+				$temp_message = explode('::', $message);
314
+				$return['type'] = $temp_message[0];
315
+				$return['message'] = $temp_message[1];
316
+
317
+				unset($temp_message);
318
+			}
319
+		}
320
+
321
+		// If message is empty, we need to check our own storage.
322
+		if (empty($message)) {
323
+			if (empty($this->message['message'])) {
324
+				return '';
325
+			}
326
+
327
+			$return = $this->message;
328
+		}
329
+
330
+		// Clear our session data so we don't get extra messages on rare occasions.
331
+		if (class_exists('CI_Session')) {
332
+			$this->session->set_flashdata('message', '');
333
+		}
334
+
335
+		return $return;
336
+	}
337
+
338
+	//--------------------------------------------------------------------
339
+
340
+	//--------------------------------------------------------------------
341
+	// Utility Methods
342
+	//--------------------------------------------------------------------
343
+
344
+	/**
345
+	 * Detects whether the item is being displayed on a desktop, phone,
346
+	 * or tablet device.
347
+	 */
348
+	protected function detectVariant()
349
+	{
350
+		// Variant Detection and setup
351
+		if (config_item('autodetect_variant') === true) {
352
+			$detect = new \Mobile_Detect();
353
+
354
+			if ($detect->isMobile()) {
355
+				$this->template->setVariant('phone');
356
+			} else if ($detect->isTablet()) {
357
+				$this->template->setVariant('tablet');
358
+			}
359
+		}
360
+	}
361
+
362
+	//--------------------------------------------------------------------
363
+
364
+	//--------------------------------------------------------------------
365
+	// 'Asset' functions
366
+	//--------------------------------------------------------------------
367
+
368
+	/**
369
+	 * Adds an external javascript file to the 'external_scripts' array.
370
+	 *
371
+	 * @param [type] $filename [description]
372
+	 */
373
+	public function addScript($filename)
374
+	{
375
+		if (strpos($filename, 'http') === FALSE) {
376
+			$filename = base_url() . 'assets/js/' . $filename;
377
+		}
378
+
379
+		$this->external_scripts[] = $filename;
380
+	}
381
+
382
+	//--------------------------------------------------------------------
383
+
384
+	/**
385
+	 * Adds an external stylesheet file to the 'stylesheets' array.
386
+	 */
387
+	public function addStyle($filename)
388
+	{
389
+		if (strpos($filename, 'http') === FALSE) {
390
+			$filename = base_url() . 'assets/css/' . $filename;
391
+		}
392
+
393
+		$this->stylesheets[] = $filename;
394
+	}
395
+
396
+	//--------------------------------------------------------------------
397 397
 }
398 398
 
Please login to merge, or discard this patch.
myth/Cron/CronTask.php 1 patch
Indentation   +291 added lines, -291 removed lines patch added patch discarded remove patch
@@ -45,301 +45,301 @@
 block discarded – undo
45 45
  */
46 46
 class CronTask {
47 47
 
48
-    /**
49
-     * The original scheduled string.
50
-     * Any valid relative time string.
51
-     * http://php.net/manual/en/datetime.formats.relative.php
52
-     *
53
-     * @var
54
-     */
55
-    protected $schedule;
56
-
57
-    /**
58
-     * Stores the callable or library name:method to run.
59
-     *
60
-     * @var
61
-     */
62
-    protected $task;
63
-
64
-    //--------------------------------------------------------------------
65
-
66
-    /**
67
-     * Stores our scheduled string and actual task.
68
-     *
69
-     * @param $schedule
70
-     * @param callable $task
71
-     */
72
-    public function __construct($schedule, $task)
73
-    {
74
-        $this->schedule = $schedule;
75
-
76
-        // If $task is not callable, it should be a library:method
77
-        // string that we can parse. But it must have the colon in the string.
78
-        if (! is_callable($task) && strpos($task, ':') === false)
79
-        {
80
-            throw new \RuntimeException( lang('cron.invalid_task') );
81
-        }
82
-
83
-        $this->task = $task;
84
-    }
85
-
86
-    //--------------------------------------------------------------------
87
-
88
-    /**
89
-     * Calculates the next date this task is supposed to run.
90
-     *
91
-     * @param int|'now' $current_time
92
-     *
93
-     * @return timestamp|null
94
-     */
95
-    public function nextRunDate($current_time='now')
96
-    {
97
-        $current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
98
-
99
-        $scheduleType = $this->determineScheduleType($this->schedule);
100
-
101
-        switch ($scheduleType)
102
-        {
103
-            case 'time':
104
-                return $this->findDateInterval($this->schedule, 'next', $current_time);
105
-                break;
106
-            case 'ordinal':
107
-                return strtotime($this->schedule, $current_time);
108
-                break;
109
-            case 'increment':
110
-                return strtotime($this->schedule, $current_time);
111
-                break;
112
-        }
113
-
114
-        return null;
115
-    }
48
+	/**
49
+	 * The original scheduled string.
50
+	 * Any valid relative time string.
51
+	 * http://php.net/manual/en/datetime.formats.relative.php
52
+	 *
53
+	 * @var
54
+	 */
55
+	protected $schedule;
56
+
57
+	/**
58
+	 * Stores the callable or library name:method to run.
59
+	 *
60
+	 * @var
61
+	 */
62
+	protected $task;
63
+
64
+	//--------------------------------------------------------------------
65
+
66
+	/**
67
+	 * Stores our scheduled string and actual task.
68
+	 *
69
+	 * @param $schedule
70
+	 * @param callable $task
71
+	 */
72
+	public function __construct($schedule, $task)
73
+	{
74
+		$this->schedule = $schedule;
75
+
76
+		// If $task is not callable, it should be a library:method
77
+		// string that we can parse. But it must have the colon in the string.
78
+		if (! is_callable($task) && strpos($task, ':') === false)
79
+		{
80
+			throw new \RuntimeException( lang('cron.invalid_task') );
81
+		}
82
+
83
+		$this->task = $task;
84
+	}
85
+
86
+	//--------------------------------------------------------------------
87
+
88
+	/**
89
+	 * Calculates the next date this task is supposed to run.
90
+	 *
91
+	 * @param int|'now' $current_time
92
+	 *
93
+	 * @return timestamp|null
94
+	 */
95
+	public function nextRunDate($current_time='now')
96
+	{
97
+		$current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
98
+
99
+		$scheduleType = $this->determineScheduleType($this->schedule);
100
+
101
+		switch ($scheduleType)
102
+		{
103
+			case 'time':
104
+				return $this->findDateInterval($this->schedule, 'next', $current_time);
105
+				break;
106
+			case 'ordinal':
107
+				return strtotime($this->schedule, $current_time);
108
+				break;
109
+			case 'increment':
110
+				return strtotime($this->schedule, $current_time);
111
+				break;
112
+		}
113
+
114
+		return null;
115
+	}
116 116
     
117
-    //--------------------------------------------------------------------
118
-
119
-    /**
120
-     * Calculates the last time the task should have ran.
121
-     *
122
-     * @param int|'now' $current_time
123
-     *
124
-     * @return timestamp|null
125
-     */
126
-    public function previousRunDate($current_time='now')
127
-    {
128
-        $current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
129
-
130
-        $scheduleType = $this->determineScheduleType($this->schedule);
131
-
132
-        switch ($scheduleType)
133
-        {
134
-            case 'time':
135
-                return $this->findDateInterval($this->schedule, 'prev', $current_time);
136
-                break;
137
-            case 'ordinal':
138
-                return $this->findPreviousOrdinal($this->schedule, $current_time);
139
-                break;
140
-            case 'increment':
141
-                return strtotime('-1 '. $this->schedule, $current_time);
142
-                break;
143
-        }
144
-
145
-        return null;
146
-    }
147
-
148
-    //--------------------------------------------------------------------
149
-
150
-    /**
151
-     * Determines if the task is due to be run now.
152
-     *
153
-     * @param string $current_time
154
-     * @internal param $ int|'now' $current_time
155
-     *
156
-     * @return bool
157
-     */
158
-    public function isDue($current_time='now')
159
-    {
160
-        $current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
161
-
162
-        // For easier matching, and I can't imagine people needing cronjob
163
-        // accuracy to the seconds, we'll just take the current minute.
164
-        return date('Y-m-d H:i', $current_time) == date('Y-m-d H:i', $this->nextRunDate($current_time) );
165
-    }
117
+	//--------------------------------------------------------------------
118
+
119
+	/**
120
+	 * Calculates the last time the task should have ran.
121
+	 *
122
+	 * @param int|'now' $current_time
123
+	 *
124
+	 * @return timestamp|null
125
+	 */
126
+	public function previousRunDate($current_time='now')
127
+	{
128
+		$current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
129
+
130
+		$scheduleType = $this->determineScheduleType($this->schedule);
131
+
132
+		switch ($scheduleType)
133
+		{
134
+			case 'time':
135
+				return $this->findDateInterval($this->schedule, 'prev', $current_time);
136
+				break;
137
+			case 'ordinal':
138
+				return $this->findPreviousOrdinal($this->schedule, $current_time);
139
+				break;
140
+			case 'increment':
141
+				return strtotime('-1 '. $this->schedule, $current_time);
142
+				break;
143
+		}
144
+
145
+		return null;
146
+	}
147
+
148
+	//--------------------------------------------------------------------
149
+
150
+	/**
151
+	 * Determines if the task is due to be run now.
152
+	 *
153
+	 * @param string $current_time
154
+	 * @internal param $ int|'now' $current_time
155
+	 *
156
+	 * @return bool
157
+	 */
158
+	public function isDue($current_time='now')
159
+	{
160
+		$current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
161
+
162
+		// For easier matching, and I can't imagine people needing cronjob
163
+		// accuracy to the seconds, we'll just take the current minute.
164
+		return date('Y-m-d H:i', $current_time) == date('Y-m-d H:i', $this->nextRunDate($current_time) );
165
+	}
166 166
     
167
-    //--------------------------------------------------------------------
168
-
169
-    /**
170
-     * Formats the timestamp produced by nextRunDate and previousRunDate
171
-     * into any format available to date.
172
-     *
173
-     * @param $format_string
174
-     * @return bool|string
175
-     */
176
-    public function format($format_string)
177
-    {
178
-        return date($format_string, strtotime($this->schedule));
179
-    }
180
-
181
-    //--------------------------------------------------------------------
182
-
183
-    /**
184
-     * Gets the associated task.
185
-     *
186
-     * return callable|string
187
-     */
188
-    public function task()
189
-    {
190
-        return $this->task;
191
-    }
192
-
193
-    //--------------------------------------------------------------------
194
-
195
-    /**
196
-     * Gets the original schedule string.
197
-     */
198
-    public function schedule()
199
-    {
200
-        return $this->schedule;
201
-    }
202
-
203
-    //--------------------------------------------------------------------
204
-
205
-    /**
206
-     * Checks the schedule text and determines how we have to treat
207
-     * the schedule when determining next and previous values.
208
-     *
209
-     * Potential Types are:
210
-     *
211
-     *  - increment         Can simply add a +x/-x to the front to get the value.
212
-     *  - time              Something like "every 5 minutes"
213
-     *  - ordinal           Like "first", "second", etc.
214
-     *
215
-     * @param $schedule
216
-     * @return null|string
217
-     */
218
-    public function determineScheduleType($schedule)
219
-    {
220
-        $incs = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sun', 'mon', 'tue',
221
-                'wed', 'thu', 'fri', 'sat', 'weekday', 'weekdays', 'midnight', 'noon'];
222
-        $bigger_incs = [ 'back of', 'front of', 'first day of', 'last day of'];
223
-        $ordinals = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth'];
224
-        $schedule = trim( strtolower($schedule) );
225
-
226
-        $multiple_words = strpos($schedule, ' ');
227
-        $first_word = substr($schedule, 0, $multiple_words ? $multiple_words : strlen($schedule));
228
-
229
-        // Is the first character a number? Then it's a time
230
-        if ( is_numeric( $first_word ) )
231
-        {
232
-            return 'time';
233
-        }
234
-
235
-
236
-        // First, try the shorter increments. We do increments in
237
-        // two passes becuase this should be faster than the loop.
238
-        if (in_array($first_word, $incs))
239
-        {
240
-            return 'increment';
241
-        }
242
-
243
-        // But we have to loop before checking ordinals since
244
-        // ordinals may have same first word as these phrases.
245
-        foreach ($bigger_incs as $test)
246
-        {
247
-            if (strpos($schedule, $test) === 0)
248
-            {
249
-                return 'increment';
250
-            }
251
-        }
252
-
253
-        if (in_array($first_word, $ordinals))
254
-        {
255
-            return 'ordinal';
256
-        }
257
-
258
-        return null;
259
-    }
260
-
261
-    //--------------------------------------------------------------------
262
-
263
-    /**
264
-     * Determines the correct time for 'time' type intervals where
265
-     * the timestamp is expected to happen every 'x period', like
266
-     * 'every 5 minutes', every 3 days, etc.
267
-     *
268
-     * @param $schedule
269
-     * @param $type
270
-     * @return float|int|null
271
-     */
272
-    public function findDateInterval($schedule, $type, $current_time='now')
273
-    {
274
-        $current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
167
+	//--------------------------------------------------------------------
168
+
169
+	/**
170
+	 * Formats the timestamp produced by nextRunDate and previousRunDate
171
+	 * into any format available to date.
172
+	 *
173
+	 * @param $format_string
174
+	 * @return bool|string
175
+	 */
176
+	public function format($format_string)
177
+	{
178
+		return date($format_string, strtotime($this->schedule));
179
+	}
180
+
181
+	//--------------------------------------------------------------------
182
+
183
+	/**
184
+	 * Gets the associated task.
185
+	 *
186
+	 * return callable|string
187
+	 */
188
+	public function task()
189
+	{
190
+		return $this->task;
191
+	}
192
+
193
+	//--------------------------------------------------------------------
194
+
195
+	/**
196
+	 * Gets the original schedule string.
197
+	 */
198
+	public function schedule()
199
+	{
200
+		return $this->schedule;
201
+	}
202
+
203
+	//--------------------------------------------------------------------
204
+
205
+	/**
206
+	 * Checks the schedule text and determines how we have to treat
207
+	 * the schedule when determining next and previous values.
208
+	 *
209
+	 * Potential Types are:
210
+	 *
211
+	 *  - increment         Can simply add a +x/-x to the front to get the value.
212
+	 *  - time              Something like "every 5 minutes"
213
+	 *  - ordinal           Like "first", "second", etc.
214
+	 *
215
+	 * @param $schedule
216
+	 * @return null|string
217
+	 */
218
+	public function determineScheduleType($schedule)
219
+	{
220
+		$incs = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sun', 'mon', 'tue',
221
+				'wed', 'thu', 'fri', 'sat', 'weekday', 'weekdays', 'midnight', 'noon'];
222
+		$bigger_incs = [ 'back of', 'front of', 'first day of', 'last day of'];
223
+		$ordinals = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth'];
224
+		$schedule = trim( strtolower($schedule) );
225
+
226
+		$multiple_words = strpos($schedule, ' ');
227
+		$first_word = substr($schedule, 0, $multiple_words ? $multiple_words : strlen($schedule));
228
+
229
+		// Is the first character a number? Then it's a time
230
+		if ( is_numeric( $first_word ) )
231
+		{
232
+			return 'time';
233
+		}
234
+
235
+
236
+		// First, try the shorter increments. We do increments in
237
+		// two passes becuase this should be faster than the loop.
238
+		if (in_array($first_word, $incs))
239
+		{
240
+			return 'increment';
241
+		}
242
+
243
+		// But we have to loop before checking ordinals since
244
+		// ordinals may have same first word as these phrases.
245
+		foreach ($bigger_incs as $test)
246
+		{
247
+			if (strpos($schedule, $test) === 0)
248
+			{
249
+				return 'increment';
250
+			}
251
+		}
252
+
253
+		if (in_array($first_word, $ordinals))
254
+		{
255
+			return 'ordinal';
256
+		}
257
+
258
+		return null;
259
+	}
260
+
261
+	//--------------------------------------------------------------------
262
+
263
+	/**
264
+	 * Determines the correct time for 'time' type intervals where
265
+	 * the timestamp is expected to happen every 'x period', like
266
+	 * 'every 5 minutes', every 3 days, etc.
267
+	 *
268
+	 * @param $schedule
269
+	 * @param $type
270
+	 * @return float|int|null
271
+	 */
272
+	public function findDateInterval($schedule, $type, $current_time='now')
273
+	{
274
+		$current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
275 275
 
276 276
 //        list($int, $period) = explode(' ', $schedule);
277 277
 
278
-        $diff = strtotime($schedule, $current_time) - $current_time;
279
-
280
-        $return = null;
281
-
282
-        switch ($type)
283
-        {
284
-            case 'next':
285
-                $next = floor($current_time / $diff) * $diff;
286
-
287
-                // Does next already match the current time?
288
-                if (date('Y-m-d H:i', $next) == date('Y-m-d H:i', $current_time))
289
-                {
290
-                    $return = $next;
291
-                }
292
-                else {
293
-                    $return = $next + $diff;
294
-                }
295
-                break;
296
-            case 'prev':
297
-                $next = ceil($current_time / $diff) * $diff;
298
-                $return = $next - $diff;
299
-                break;
300
-        }
301
-
302
-        if (is_numeric($return))
303
-        {
304
-            $return = (int)$return;
305
-        }
306
-
307
-        return $return;
308
-    }
309
-
310
-    //--------------------------------------------------------------------
311
-
312
-    /**
313
-     * Determines the timestamp of the previous ordinal-based time, like
314
-     * 'second Monday'.
315
-     *
316
-     * @param $schedule
317
-     * @param string $current_time
318
-     * @return int|null
319
-     */
320
-    public function findPreviousOrdinal($schedule, $current_time='now')
321
-    {
322
-        $current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
323
-
324
-        if (empty($schedule)) return null;
325
-
326
-        // Loop through months in reverse, checking each one to
327
-        // see if the ordinal is in the past. If so - wer'e done.
328
-        foreach ([0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12] as $i)
329
-        {
330
-            $lastmonth = strtotime("last day of {$i} month", $current_time);
331
-
332
-            $test = strtotime($schedule, $lastmonth);
333
-
334
-            if ($test <= $current_time)
335
-            {
336
-                return $test;
337
-            }
338
-        }
339
-
340
-        return null;
341
-    }
342
-
343
-    //--------------------------------------------------------------------
278
+		$diff = strtotime($schedule, $current_time) - $current_time;
279
+
280
+		$return = null;
281
+
282
+		switch ($type)
283
+		{
284
+			case 'next':
285
+				$next = floor($current_time / $diff) * $diff;
286
+
287
+				// Does next already match the current time?
288
+				if (date('Y-m-d H:i', $next) == date('Y-m-d H:i', $current_time))
289
+				{
290
+					$return = $next;
291
+				}
292
+				else {
293
+					$return = $next + $diff;
294
+				}
295
+				break;
296
+			case 'prev':
297
+				$next = ceil($current_time / $diff) * $diff;
298
+				$return = $next - $diff;
299
+				break;
300
+		}
301
+
302
+		if (is_numeric($return))
303
+		{
304
+			$return = (int)$return;
305
+		}
306
+
307
+		return $return;
308
+	}
309
+
310
+	//--------------------------------------------------------------------
311
+
312
+	/**
313
+	 * Determines the timestamp of the previous ordinal-based time, like
314
+	 * 'second Monday'.
315
+	 *
316
+	 * @param $schedule
317
+	 * @param string $current_time
318
+	 * @return int|null
319
+	 */
320
+	public function findPreviousOrdinal($schedule, $current_time='now')
321
+	{
322
+		$current_time = is_numeric($current_time) ? (int)$current_time : strtotime($current_time);
323
+
324
+		if (empty($schedule)) return null;
325
+
326
+		// Loop through months in reverse, checking each one to
327
+		// see if the ordinal is in the past. If so - wer'e done.
328
+		foreach ([0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12] as $i)
329
+		{
330
+			$lastmonth = strtotime("last day of {$i} month", $current_time);
331
+
332
+			$test = strtotime($schedule, $lastmonth);
333
+
334
+			if ($test <= $current_time)
335
+			{
336
+				return $test;
337
+			}
338
+		}
339
+
340
+		return null;
341
+	}
342
+
343
+	//--------------------------------------------------------------------
344 344
 
345 345
 }
Please login to merge, or discard this patch.
myth/Docs/Builder.php 1 patch
Indentation   +718 added lines, -718 removed lines patch added patch discarded remove patch
@@ -60,725 +60,725 @@
 block discarded – undo
60 60
 class Builder implements DocBuilderInterface
61 61
 {
62 62
 
63
-    protected $docs_ext = '.md';
64
-
65
-    protected $ignore_files = ['_404.md'];
66
-
67
-    protected $doc_folders = [];
68
-
69
-    /**
70
-     * Stores the current folder alias,
71
-     * once the file has been found.
72
-     *
73
-     * @var null
74
-     */
75
-    protected $current_folder = null;
76
-
77
-    protected $table_classes = 'table table-hover';
78
-
79
-    protected $apppath = '';
80
-
81
-    protected $formatters = [];
82
-
83
-    protected $page_title = null;
84
-
85
-    //--------------------------------------------------------------------
86
-
87
-    public function __construct($config = array())
88
-    {
89
-        $this->apppath = ! empty($config['apppath']) ? rtrim($config['apppath'], '/') . '/' : '';
90
-    }
91
-
92
-    //--------------------------------------------------------------------
93
-
94
-    public function pageTitle()
95
-    {
96
-        return $this->page_title;
97
-    }
98
-
99
-    //--------------------------------------------------------------------
100
-
101
-
102
-
103
-    /**
104
-     * Does the actual work of reading in and parsing the help file.
105
-     * If a folder Nickname (see addDocFolder() ) is passed as the second parameter,
106
-     * it will limit it's search to that single folder. If nothing is passed, it will
107
-     * search through all of the folders in the order they were given to the library,
108
-     * until it finds the first one.
109
-     *
110
-     * @param string $path The 'path' of the file (relative to the docs
111
-     *                                 folder. Usually from the URI)
112
-     * @param string $restrictToFolder (Optional) The folder nickname
113
-     *
114
-     * @return string
115
-     */
116
-    public function readPage($path, $restrictToFolder = null)
117
-    {
118
-        // Clean up our path
119
-        $path = trim($path, '/ ');
120
-
121
-        $content = $this->locateAndReadFile($path, $restrictToFolder);
122
-
123
-        $content = $this->parse($content);
124
-
125
-        return $content;
126
-    }
127
-
128
-    //--------------------------------------------------------------------
129
-
130
-    /**
131
-     * Parses the contents. Currently runs through the Markdown Extended
132
-     * parser to convert to HTML.
133
-     *
134
-     * @param $str
135
-     * @return mixed
136
-     */
137
-    public function parse($str)
138
-    {
139
-        return $this->format($str);
140
-    }
141
-
142
-    //--------------------------------------------------------------------
143
-
144
-    /**
145
-     * Perform a few housekeeping tasks on a page, like rewriting URLs to full
146
-     * URLs, not relative, ensuring they link correctly, etc.
147
-     *
148
-     * @param      $content
149
-     * @param null $site_url
150
-     * @param null $current_url
151
-     * @return string   The post-processed HTML.
152
-     */
153
-    public function postProcess($content, $site_url = null, $current_url = null)
154
-    {
155
-        if (empty($content)) {
156
-            return $content;
157
-        }
158
-
159
-        try {
160
-            $xml = new \SimpleXMLElement('<?xml version="1.0" standalone="yes"?><div>' . $content . '</div>');
161
-        } catch (\Exception $e) {
162
-            // SimpleXML barfed on us, so send back the un-modified content
163
-            return $content;
164
-        }
165
-
166
-        // Prepare some things and cleanup others
167
-        $groups = array_keys($this->doc_folders);
168
-        $site_url = rtrim($site_url, '/') . '/';
169
-        $current_url = rtrim($current_url, '#/');
170
-
171
-        // Try to determine the current_url if one isn't set.
172
-        if (empty($this->current_folder)) {
173
-            $this->current_folder = $this->detectCurrentFolder($current_url, $groups);
174
-        }
175
-
176
-        /*
63
+	protected $docs_ext = '.md';
64
+
65
+	protected $ignore_files = ['_404.md'];
66
+
67
+	protected $doc_folders = [];
68
+
69
+	/**
70
+	 * Stores the current folder alias,
71
+	 * once the file has been found.
72
+	 *
73
+	 * @var null
74
+	 */
75
+	protected $current_folder = null;
76
+
77
+	protected $table_classes = 'table table-hover';
78
+
79
+	protected $apppath = '';
80
+
81
+	protected $formatters = [];
82
+
83
+	protected $page_title = null;
84
+
85
+	//--------------------------------------------------------------------
86
+
87
+	public function __construct($config = array())
88
+	{
89
+		$this->apppath = ! empty($config['apppath']) ? rtrim($config['apppath'], '/') . '/' : '';
90
+	}
91
+
92
+	//--------------------------------------------------------------------
93
+
94
+	public function pageTitle()
95
+	{
96
+		return $this->page_title;
97
+	}
98
+
99
+	//--------------------------------------------------------------------
100
+
101
+
102
+
103
+	/**
104
+	 * Does the actual work of reading in and parsing the help file.
105
+	 * If a folder Nickname (see addDocFolder() ) is passed as the second parameter,
106
+	 * it will limit it's search to that single folder. If nothing is passed, it will
107
+	 * search through all of the folders in the order they were given to the library,
108
+	 * until it finds the first one.
109
+	 *
110
+	 * @param string $path The 'path' of the file (relative to the docs
111
+	 *                                 folder. Usually from the URI)
112
+	 * @param string $restrictToFolder (Optional) The folder nickname
113
+	 *
114
+	 * @return string
115
+	 */
116
+	public function readPage($path, $restrictToFolder = null)
117
+	{
118
+		// Clean up our path
119
+		$path = trim($path, '/ ');
120
+
121
+		$content = $this->locateAndReadFile($path, $restrictToFolder);
122
+
123
+		$content = $this->parse($content);
124
+
125
+		return $content;
126
+	}
127
+
128
+	//--------------------------------------------------------------------
129
+
130
+	/**
131
+	 * Parses the contents. Currently runs through the Markdown Extended
132
+	 * parser to convert to HTML.
133
+	 *
134
+	 * @param $str
135
+	 * @return mixed
136
+	 */
137
+	public function parse($str)
138
+	{
139
+		return $this->format($str);
140
+	}
141
+
142
+	//--------------------------------------------------------------------
143
+
144
+	/**
145
+	 * Perform a few housekeeping tasks on a page, like rewriting URLs to full
146
+	 * URLs, not relative, ensuring they link correctly, etc.
147
+	 *
148
+	 * @param      $content
149
+	 * @param null $site_url
150
+	 * @param null $current_url
151
+	 * @return string   The post-processed HTML.
152
+	 */
153
+	public function postProcess($content, $site_url = null, $current_url = null)
154
+	{
155
+		if (empty($content)) {
156
+			return $content;
157
+		}
158
+
159
+		try {
160
+			$xml = new \SimpleXMLElement('<?xml version="1.0" standalone="yes"?><div>' . $content . '</div>');
161
+		} catch (\Exception $e) {
162
+			// SimpleXML barfed on us, so send back the un-modified content
163
+			return $content;
164
+		}
165
+
166
+		// Prepare some things and cleanup others
167
+		$groups = array_keys($this->doc_folders);
168
+		$site_url = rtrim($site_url, '/') . '/';
169
+		$current_url = rtrim($current_url, '#/');
170
+
171
+		// Try to determine the current_url if one isn't set.
172
+		if (empty($this->current_folder)) {
173
+			$this->current_folder = $this->detectCurrentFolder($current_url, $groups);
174
+		}
175
+
176
+		/*
177 177
          * Rewrite the URLs
178 178
          */
179
-        foreach ($xml->xpath('//a') as $link) {
180
-            $link = $this->reformatAnchor($link, $groups, $current_url, $site_url);
181
-        }
182
-
183
-        $content = $xml->asXML();
184
-        $content = trim(str_replace('<?xml version="1.0" standalone="yes"?>', '', $content));
185
-
186
-        // Clean up and style the tables
187
-        $content = str_replace('<table>', '<table class="' . $this->table_classes . '">', $content);
188
-
189
-        return $content;
190
-    }
191
-    //--------------------------------------------------------------------
192
-
193
-    /**
194
-     * Allows users to define the classes that are attached to
195
-     * generated tables.
196
-     *
197
-     * @param null $classes
198
-     * @return $this
199
-     */
200
-    public function setTableClasses($classes = null)
201
-    {
202
-        $this->table_classes = $classes;
203
-
204
-        return $this;
205
-    }
206
-
207
-    //--------------------------------------------------------------------
208
-
209
-    /**
210
-     * Given the contents to render, will build a list of links for the sidebar
211
-     * out of the headings in the file.
212
-     *
213
-     * Note: Will ONLY use h2 and h3 to build the links from.
214
-     *
215
-     * Note: The $content passed in WILL be modified by adding named anchors
216
-     * that match up with the locations.
217
-     *
218
-     * @param string $content The HTML to analyse for headings.
219
-     * @return string
220
-     */
221
-    public function buildDocumentMap(&$content)
222
-    {
223
-        if (empty($content)) {
224
-            return $content;
225
-        }
226
-
227
-        // If $content already has a wrapping <div> and </div> tags, remove them,
228
-        // since we'll replace them just below.
229
-        if (strpos($content, '<div>') === 0) {
230
-            $content = substr($content, 5);
231
-
232
-            // Trailing div also?
233
-            if (substr($content, -6) == '</div>') {
234
-                $content = substr($content, 0, -6);
235
-            }
236
-        }
237
-
238
-        try {
239
-            $xml = new \SimpleXMLElement('<?xml version="1.0" standalone="yes"?><div>' . $content . '</div>');
240
-        } catch (\Exception $e) {
241
-            // SimpleXML barfed on us, so send back the un-modified content
242
-            return [];
243
-        }
244
-
245
-        $map = [];
246
-        list($map, $content) = $this->extractDocMapAndAddAnchors($content, $xml, $map);
247
-
248
-        return $map;
249
-    }
250
-
251
-    //--------------------------------------------------------------------
252
-
253
-    /**
254
-     * Stores the name of the callback method to run to convert the source
255
-     * files to viewable files. By default, this should be used to register
256
-     * a Mardown Extended formatter with the system, but could be used to
257
-     * extend the
258
-     *
259
-     * @param string $callback
260
-     * @param bool $cascade // If FALSE the formatting of a component ends here. If TRUE, will be passed to next formatter.
261
-     * @return $this
262
-     */
263
-    public function registerFormatter($callback = null, $cascade = false)
264
-    {
265
-        if (empty($callback)) return;
266
-
267
-        $this->formatters[] = [
268
-            'callable' => $callback,
269
-            'cascade'  => (bool)$cascade
270
-        ];
271
-
272
-        return $this;
273
-    }
274
-
275
-    //--------------------------------------------------------------------
276
-
277
-    /**
278
-     * Runs the text through the registered formatters.
279
-     *
280
-     * @param $str
281
-     * @return mixed
282
-     */
283
-    public function format($str)
284
-    {
285
-        if (! is_array($this->formatters)) return $str;
286
-
287
-        foreach ($this->formatters as $formatter) {
288
-            $method = $formatter['callable'];
289
-            $cascade = $formatter['cascade'];
290
-
291
-            $str = call_user_func($method, $str);
292
-
293
-            if (! $cascade) return $str;
294
-        }
295
-
296
-        return $str;
297
-    }
298
-
299
-    //--------------------------------------------------------------------
300
-
301
-    //--------------------------------------------------------------------
302
-    // Table of Contents methods
303
-    //--------------------------------------------------------------------
304
-
305
-    /**
306
-     * Retrieves the list of files in a folder and preps the name and filename
307
-     * so it's ready for creating the HTML.
308
-     *
309
-     * @param  String $folder The path to the folder to retrieve.
310
-     *
311
-     * @return Array  An associative array @see parse_ini_file for format
312
-     * details.
313
-     */
314
-    public function buildTOC($folder)
315
-    {
316
-        // If the toc file exists in the folder, use it to build the links.
317
-        if (is_file("{$folder}/_toc.ini")) {
318
-            $toc = parse_ini_file("{$folder}/_toc.ini", true);
319
-            return $this->columnizeTOC($toc);
320
-        }
321
-
322
-        // If the toc file does not exist, build the links by listing the files
323
-        // in the directory (and any sub-directories)
324
-        $map = $this->directory_map($folder);
325
-
326
-        // If directory_map can not open the directory or find any files inside
327
-        // the directory, return an empty array.
328
-        if (empty($map)) {
329
-            return [];
330
-        }
331
-
332
-        // If these docs are located in the /application/docs or /bonfire/docs
333
-        // directory, just use $this->current_group for the root.
334
-        // Module docs need $this->current_group and $type.
335
-        $tocRoot = $this->current_folder;
336
-        if ($this->current_folder != strtolower($folder)) {
337
-            $tocRoot .= '/' . strtolower($folder);
338
-        }
339
-
340
-        $toc = [];
341
-        foreach ($map as $files) {
342
-            // If $files isn't an array, then make it one so that all situations
343
-            // may be dealt with cleanly.
344
-            if (! is_array($files)) {
345
-                $files = [$files];
346
-            }
347
-
348
-            foreach ($files as $file) {
349
-                if (in_array($file, $this->ignore_files)) {
350
-                    continue;
351
-                }
352
-
353
-                // The title for the index is the passed $type. Otherwise,
354
-                // build the title from the file's name.
355
-                if (strpos($file, 'index') === false) {
356
-                    $title = str_replace($this->docs_ext, '', $file);
357
-                    $title = str_replace('_', ' ', $title);
358
-                    $title = ucwords($title);
359
-
360
-                    $toc["{$tocRoot}/{$file}"] = $title;
361
-                } else {
362
-                    $toc[$tocRoot] = $type;
363
-                }
364
-            }
365
-        }
366
-
367
-        $toc = $this->columnizeTOC($toc);
368
-
369
-        return $toc;
370
-    }
371
-
372
-    //--------------------------------------------------------------------
373
-
374
-    /**
375
-     * Sorts the passed TOC array into columns of as close to equal length
376
-     * as we can get it.
377
-     *
378
-     * @param $toc
379
-     * @return array
380
-     */
381
-    protected function columnizeTOC($toc)
382
-    {
383
-        $section_count = count($toc);
384
-
385
-        // First - determine the size of each 'section'.
386
-        $sizes = [];
387
-
388
-        foreach ($toc as $section => $chapters) {
389
-            $sizes[] = count($chapters);
390
-        }
391
-
392
-        $column_avg = (int)round(array_sum($sizes) / $section_count);
393
-
394
-        // Split things into 4 columns of approximately equal size.
395
-        // If we only have 4 columns (or less), then make sure to
396
-        // deal with that also.
397
-        $columns = [];
398
-
399
-        $current_column = 0;
400
-        $current_column_count = 0;
401
-        $keys = array_keys($toc);
402
-
403
-        for ($i = 0; $i <= $section_count; $i++) {
404
-            if (! isset($keys[$i])) {
405
-                continue;
406
-            }
407
-
408
-            $section = array_shift($toc);
409
-
410
-            // Can we stay in this column?
411
-            if ($current_column_count <= $column_avg && $section_count > 4) {
412
-                // Don't forget to account for the heading also.
413
-                $current_column_count += count($section) + 1;
414
-            } else {
415
-                $current_column_count = 0;
416
-                $current_column++;
417
-            }
418
-
419
-            $columns[$current_column][$keys[$i]] = $section;
420
-        }
421
-
422
-        return $columns;
423
-    }
424
-
425
-    //--------------------------------------------------------------------
426
-
427
-    //--------------------------------------------------------------------
428
-    // Folder Methods
429
-    //--------------------------------------------------------------------
430
-
431
-    /**
432
-     * Returns the current docFolders array.
433
-     *
434
-     * @return array
435
-     */
436
-    public function docFolders()
437
-    {
438
-        return $this->doc_folders;
439
-    }
440
-
441
-    //--------------------------------------------------------------------
442
-
443
-    /**
444
-     * Registers a path to be used when searching for documentation files.
445
-     *
446
-     * @param $name     A nickname to reference it by later.
447
-     * @param $path     The server path to the folder.
448
-     * @return $this
449
-     */
450
-    public function addDocFolder($name, $path)
451
-    {
452
-        // Standardize the path
453
-        $path = realpath($path) . '/';
454
-
455
-        // realpath will return FALSE if the path doesn't exist
456
-        // or the script doesn't have access to it.
457
-        if (! $path || $path == '/') {
458
-            return $this;
459
-        }
460
-
461
-        $name = strtolower($name);
462
-
463
-        $this->doc_folders[$name] = $path;
464
-
465
-        return $this;
466
-    }
467
-
468
-    //--------------------------------------------------------------------
469
-
470
-    /**
471
-     * Removes a folder from the folders we scan for documentation files
472
-     * within.
473
-     *
474
-     * @param $name
475
-     * @return $this
476
-     */
477
-    public function removeDocFolder($name)
478
-    {
479
-        $name = strtolower($name);
480
-
481
-        if (isset($this->doc_folders[$name])) {
482
-            unset($this->doc_folders[$name]);
483
-        }
484
-
485
-        return $this;
486
-    }
487
-
488
-    //--------------------------------------------------------------------
489
-
490
-    //--------------------------------------------------------------------
491
-    // Private Methods
492
-    //--------------------------------------------------------------------
493
-
494
-    /**
495
-     * Analyzes the passed in current url string and checks against
496
-     * a list of groups to determine what the current group is.
497
-     *
498
-     * @param $current_url
499
-     * @param $groups
500
-     * @return string
501
-     */
502
-    protected function detectCurrentFolder($current_url, $groups = [])
503
-    {
504
-        if (! is_array($groups)) {
505
-            return null;
506
-        }
507
-
508
-        $segments = explode('/', $current_url);
509
-
510
-        // We start from the back of the array since
511
-        // that's most likely to be close to the end.
512
-        $segments = array_reverse($segments);
513
-
514
-        foreach ($segments as $segment) {
515
-            foreach ($groups as $group) {
516
-                if (strtolower($group) == strtolower($segment)) {
517
-                    return $group;
518
-                }
519
-            }
520
-        }
521
-
522
-        // Nothing found?
523
-        return null;
524
-    }
525
-
526
-    //--------------------------------------------------------------------
527
-
528
-    //--------------------------------------------------------------------
529
-    // Private Methods
530
-    //--------------------------------------------------------------------
531
-
532
-    /**
533
-     * Locates the file on disk and reads the contents into a single string.
534
-     *
535
-     * If a folder Nickname (see addDocFolder() ) is passed as the second parameter,
536
-     * it will limit it's search to that single folder. If nothing is passed, it will
537
-     * search through all of the folders in the order they were given to the library,
538
-     * until it finds the first one.
539
-     *
540
-     * @param string $path The 'path' of the file (relative to the docs
541
-     *                                 folder. Usually from the URI)
542
-     * @param string $restrictToFolder (Optional) The nickname of one of the
543
-     *                                 folders to restrict the search to.
544
-     *
545
-     * @throws RuntimeException
546
-     * @return null|string
547
-     */
548
-    private function locateAndReadFile($path, $restrictToFolder = null)
549
-    {
550
-        $folders = $this->doc_folders;
551
-
552
-        if (! is_null($restrictToFolder)) {
553
-            // Make sure the folder exists
554
-            if (! is_null($restrictToFolder) && ! isset($this->doc_folders[$restrictToFolder])) {
555
-                throw new \RuntimeException('You must add the docs folder that you wish to find docs from.');
556
-            }
557
-
558
-            $folders = [$this->doc_folders[$restrictToFolder]];
559
-        }
560
-
561
-        foreach ($folders as $alias => $folder) {
562
-            if (file_exists($folder . $path . $this->docs_ext)) {
563
-                // Store the alias so we know which folder we're in.
564
-                $this->current_folder = $alias;
565
-
566
-                return file_get_contents($folder . $path . $this->docs_ext);
567
-            }
568
-        }
569
-
570
-        return null;
571
-    }
572
-
573
-    //--------------------------------------------------------------------
574
-
575
-    /**
576
-     * Re-formats the passed in link.
577
-     *
578
-     * @param $link
579
-     * @param $current_url
580
-     * @param $site_url
581
-     * @return mixed
582
-     */
583
-    private function reformatAnchor($link, $groups, $current_url, $site_url)
584
-    {
585
-        // Grab the href value.
586
-        $href = $link->attributes()->href;
587
-
588
-        // If the href is null, it's probably a named anchor with no content.
589
-        if (! $href) {
590
-            // Make sure it has an href, else the XML will not close this
591
-            // tag correctly.
592
-            $link['href'] = ' ';
593
-
594
-            return $link;
595
-        }
596
-
597
-        // Remove any trailing # signs
598
-        $href = rtrim($href, '# ');
599
-
600
-        // If the href starts with #, then attach the current_url to it
601
-        if ($href != '' && substr_compare($href, '#', 0, 1) === 0) {
602
-            $link['href'] = $current_url . $href;
603
-
604
-            return $link;
605
-        }
606
-
607
-        // If it's a full external path, go on...
608
-        if ((strpos($href, 'http://') !== false || strpos($href, 'https://') !== false) &&
609
-            strpos($href, $site_url) === false
610
-        ) {
611
-            $link['target'] = "_blank";
612
-            return $link;
613
-        }
614
-
615
-        // If it's a full local path, get rid of it.
616
-        if (strpos($href, $site_url) !== false) {
617
-            $href = str_replace($site_url, '', $href);
618
-        }
619
-
620
-        // Strip out some unnecessary items, just in case they're there.
621
-        if (substr($href, 0, strlen('docs/')) == 'docs/') {
622
-            $href = substr($href, strlen('docs/'));
623
-        }
624
-
625
-        // This includes 'bonfire/' if it was missed during the conversion.
626
-        if (substr($href, 0, strlen('bonfire/')) == 'bonfire/') {
627
-            $href = substr($href, strlen('bonfire/'));
628
-        }
629
-
630
-        // If another 'group' is not already defined at the head of the link
631
-        // then add the current group to it.
632
-        $group_found = false;
633
-
634
-        foreach ($groups as $group) {
635
-            if (strpos($href, $group) === 0) {
636
-                $group_found = true;
637
-            }
638
-        }
639
-
640
-        if (! $group_found) {
641
-            $href = $this->current_folder . '/' . $href;
642
-        }
643
-
644
-        // Convert to full site_url
645
-        if (strpos($href, 'http') !== 0) {
646
-            $href = $site_url . 'docs/' . ltrim($href, '/ ');
647
-        }
648
-
649
-        // Save the corrected href
650
-        $link['href'] = $href;
651
-
652
-        return $link;
653
-    }
654
-
655
-    //--------------------------------------------------------------------
656
-
657
-    /**
658
-     * Creates a Document Map based on <h2> and <h3> tags.
659
-     * Also adds named anchors into the $content so the map
660
-     * can link to the content properly.
661
-     *
662
-     * @param $content
663
-     * @param $xml
664
-     * @param $map
665
-     * @return array
666
-     */
667
-    protected function extractDocMapAndAddAnchors(&$content, $xml, $map)
668
-    {
669
-        // Holds the current h2 we're processing
670
-        $current_obj = [];
671
-
672
-        $currentChild = 0;
673
-
674
-        foreach ($xml->children() as $childType => $line) {
675
-            $currentChild++;
676
-
677
-            // If it's an h1 - take the first and make it
678
-            // our page title.
679
-            if ($childType == 'h1' && empty($this->page_title))
680
-            {
681
-                $this->page_title = (string)$line;
682
-            }
683
-
684
-            // Make sure that our current object is
685
-            // stored and reset.
686
-            if ($childType == 'h1' || $childType == 'h2') {
687
-                if (count($current_obj)) {
688
-                    $map[] = $current_obj;
689
-                    $current_obj = [];
690
-                }
691
-            }
692
-
693
-            if ($childType == 'h2') {
694
-                $name = (string)$line;
695
-                $link = strtolower(str_replace(' ', '_', (string)$line));
696
-
697
-                $current_obj['name'] = $name;
698
-                $current_obj['link'] = '#' . $link;
699
-                $current_obj['items'] = [];
700
-
701
-                // Insert a named anchor into the $content
702
-                $anchor = '<a name="' . $link . '" id="' . $link . '" ></a>';
703
-
704
-                $search = "<h2>{$name}</h2>";
705
-
706
-                $content = str_replace($search, $anchor . $search, $content);
707
-            } elseif ($childType == 'h3') {
708
-                // Make sure we have some place to store the items.
709
-                if (! isset($current_obj['items'])) {
710
-                    $current_obj['items'] = [];
711
-                }
712
-
713
-                $link = strtolower(str_replace(' ', '_', (string)$line));
714
-                $name = (string)$line;
715
-
716
-                $current_obj['items'][] = [
717
-                    'name' => $name,
718
-                    'link' => '#' . $link
719
-                ];
720
-
721
-                // Insert a named anchor into the $content
722
-                $anchor = '<a name="' . $link . '" id="' . $link . '" ></a>';
723
-
724
-                $search = "<h3>{$name}</h3>";
725
-
726
-                $content = str_replace($search, $anchor . $search, $content);
727
-            }
728
-
729
-            // Is this the last element? Then close out our current object.
730
-            if (count($xml) == $currentChild) {
731
-                if (count($current_obj)) {
732
-                    $map[] = $current_obj;
733
-                }
734
-            }
735
-        }
736
-        return [$map, $content];
737
-    }
738
-    //--------------------------------------------------------------------
739
-
740
-    /**
741
-     * Create a Directory Map
742
-     *
743
-     * Reads the specified directory and builds an array
744
-     * representation of it. Sub-folders contained with the
745
-     * directory will be mapped as well.
746
-     *
747
-     * @param    string $source_dir Path to source
748
-     * @param    int $directory_depth Depth of directories to traverse
749
-     *                        (0 = fully recursive, 1 = current dir, etc)
750
-     * @param    bool $hidden Whether to show hidden files
751
-     * @return    array
752
-     */
753
-    protected function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE)
754
-    {
755
-        if ($fp = @opendir($source_dir)) {
756
-            $filedata = array();
757
-            $new_depth = $directory_depth - 1;
758
-            $source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
759
-
760
-            while (FALSE !== ($file = readdir($fp))) {
761
-                // Remove '.', '..', and hidden files [optional]
762
-                if ($file === '.' OR $file === '..' OR ($hidden === FALSE && $file[0] === '.')) {
763
-                    continue;
764
-                }
765
-
766
-                is_dir($source_dir . $file) && $file .= DIRECTORY_SEPARATOR;
767
-
768
-                if (($directory_depth < 1 OR $new_depth > 0) && is_dir($source_dir . $file)) {
769
-                    $filedata[$file] = directory_map($source_dir . $file, $new_depth, $hidden);
770
-                } else {
771
-                    $filedata[] = $file;
772
-                }
773
-            }
774
-
775
-            closedir($fp);
776
-            return $filedata;
777
-        }
778
-
779
-        return FALSE;
780
-    }
781
-
782
-    //--------------------------------------------------------------------
179
+		foreach ($xml->xpath('//a') as $link) {
180
+			$link = $this->reformatAnchor($link, $groups, $current_url, $site_url);
181
+		}
182
+
183
+		$content = $xml->asXML();
184
+		$content = trim(str_replace('<?xml version="1.0" standalone="yes"?>', '', $content));
185
+
186
+		// Clean up and style the tables
187
+		$content = str_replace('<table>', '<table class="' . $this->table_classes . '">', $content);
188
+
189
+		return $content;
190
+	}
191
+	//--------------------------------------------------------------------
192
+
193
+	/**
194
+	 * Allows users to define the classes that are attached to
195
+	 * generated tables.
196
+	 *
197
+	 * @param null $classes
198
+	 * @return $this
199
+	 */
200
+	public function setTableClasses($classes = null)
201
+	{
202
+		$this->table_classes = $classes;
203
+
204
+		return $this;
205
+	}
206
+
207
+	//--------------------------------------------------------------------
208
+
209
+	/**
210
+	 * Given the contents to render, will build a list of links for the sidebar
211
+	 * out of the headings in the file.
212
+	 *
213
+	 * Note: Will ONLY use h2 and h3 to build the links from.
214
+	 *
215
+	 * Note: The $content passed in WILL be modified by adding named anchors
216
+	 * that match up with the locations.
217
+	 *
218
+	 * @param string $content The HTML to analyse for headings.
219
+	 * @return string
220
+	 */
221
+	public function buildDocumentMap(&$content)
222
+	{
223
+		if (empty($content)) {
224
+			return $content;
225
+		}
226
+
227
+		// If $content already has a wrapping <div> and </div> tags, remove them,
228
+		// since we'll replace them just below.
229
+		if (strpos($content, '<div>') === 0) {
230
+			$content = substr($content, 5);
231
+
232
+			// Trailing div also?
233
+			if (substr($content, -6) == '</div>') {
234
+				$content = substr($content, 0, -6);
235
+			}
236
+		}
237
+
238
+		try {
239
+			$xml = new \SimpleXMLElement('<?xml version="1.0" standalone="yes"?><div>' . $content . '</div>');
240
+		} catch (\Exception $e) {
241
+			// SimpleXML barfed on us, so send back the un-modified content
242
+			return [];
243
+		}
244
+
245
+		$map = [];
246
+		list($map, $content) = $this->extractDocMapAndAddAnchors($content, $xml, $map);
247
+
248
+		return $map;
249
+	}
250
+
251
+	//--------------------------------------------------------------------
252
+
253
+	/**
254
+	 * Stores the name of the callback method to run to convert the source
255
+	 * files to viewable files. By default, this should be used to register
256
+	 * a Mardown Extended formatter with the system, but could be used to
257
+	 * extend the
258
+	 *
259
+	 * @param string $callback
260
+	 * @param bool $cascade // If FALSE the formatting of a component ends here. If TRUE, will be passed to next formatter.
261
+	 * @return $this
262
+	 */
263
+	public function registerFormatter($callback = null, $cascade = false)
264
+	{
265
+		if (empty($callback)) return;
266
+
267
+		$this->formatters[] = [
268
+			'callable' => $callback,
269
+			'cascade'  => (bool)$cascade
270
+		];
271
+
272
+		return $this;
273
+	}
274
+
275
+	//--------------------------------------------------------------------
276
+
277
+	/**
278
+	 * Runs the text through the registered formatters.
279
+	 *
280
+	 * @param $str
281
+	 * @return mixed
282
+	 */
283
+	public function format($str)
284
+	{
285
+		if (! is_array($this->formatters)) return $str;
286
+
287
+		foreach ($this->formatters as $formatter) {
288
+			$method = $formatter['callable'];
289
+			$cascade = $formatter['cascade'];
290
+
291
+			$str = call_user_func($method, $str);
292
+
293
+			if (! $cascade) return $str;
294
+		}
295
+
296
+		return $str;
297
+	}
298
+
299
+	//--------------------------------------------------------------------
300
+
301
+	//--------------------------------------------------------------------
302
+	// Table of Contents methods
303
+	//--------------------------------------------------------------------
304
+
305
+	/**
306
+	 * Retrieves the list of files in a folder and preps the name and filename
307
+	 * so it's ready for creating the HTML.
308
+	 *
309
+	 * @param  String $folder The path to the folder to retrieve.
310
+	 *
311
+	 * @return Array  An associative array @see parse_ini_file for format
312
+	 * details.
313
+	 */
314
+	public function buildTOC($folder)
315
+	{
316
+		// If the toc file exists in the folder, use it to build the links.
317
+		if (is_file("{$folder}/_toc.ini")) {
318
+			$toc = parse_ini_file("{$folder}/_toc.ini", true);
319
+			return $this->columnizeTOC($toc);
320
+		}
321
+
322
+		// If the toc file does not exist, build the links by listing the files
323
+		// in the directory (and any sub-directories)
324
+		$map = $this->directory_map($folder);
325
+
326
+		// If directory_map can not open the directory or find any files inside
327
+		// the directory, return an empty array.
328
+		if (empty($map)) {
329
+			return [];
330
+		}
331
+
332
+		// If these docs are located in the /application/docs or /bonfire/docs
333
+		// directory, just use $this->current_group for the root.
334
+		// Module docs need $this->current_group and $type.
335
+		$tocRoot = $this->current_folder;
336
+		if ($this->current_folder != strtolower($folder)) {
337
+			$tocRoot .= '/' . strtolower($folder);
338
+		}
339
+
340
+		$toc = [];
341
+		foreach ($map as $files) {
342
+			// If $files isn't an array, then make it one so that all situations
343
+			// may be dealt with cleanly.
344
+			if (! is_array($files)) {
345
+				$files = [$files];
346
+			}
347
+
348
+			foreach ($files as $file) {
349
+				if (in_array($file, $this->ignore_files)) {
350
+					continue;
351
+				}
352
+
353
+				// The title for the index is the passed $type. Otherwise,
354
+				// build the title from the file's name.
355
+				if (strpos($file, 'index') === false) {
356
+					$title = str_replace($this->docs_ext, '', $file);
357
+					$title = str_replace('_', ' ', $title);
358
+					$title = ucwords($title);
359
+
360
+					$toc["{$tocRoot}/{$file}"] = $title;
361
+				} else {
362
+					$toc[$tocRoot] = $type;
363
+				}
364
+			}
365
+		}
366
+
367
+		$toc = $this->columnizeTOC($toc);
368
+
369
+		return $toc;
370
+	}
371
+
372
+	//--------------------------------------------------------------------
373
+
374
+	/**
375
+	 * Sorts the passed TOC array into columns of as close to equal length
376
+	 * as we can get it.
377
+	 *
378
+	 * @param $toc
379
+	 * @return array
380
+	 */
381
+	protected function columnizeTOC($toc)
382
+	{
383
+		$section_count = count($toc);
384
+
385
+		// First - determine the size of each 'section'.
386
+		$sizes = [];
387
+
388
+		foreach ($toc as $section => $chapters) {
389
+			$sizes[] = count($chapters);
390
+		}
391
+
392
+		$column_avg = (int)round(array_sum($sizes) / $section_count);
393
+
394
+		// Split things into 4 columns of approximately equal size.
395
+		// If we only have 4 columns (or less), then make sure to
396
+		// deal with that also.
397
+		$columns = [];
398
+
399
+		$current_column = 0;
400
+		$current_column_count = 0;
401
+		$keys = array_keys($toc);
402
+
403
+		for ($i = 0; $i <= $section_count; $i++) {
404
+			if (! isset($keys[$i])) {
405
+				continue;
406
+			}
407
+
408
+			$section = array_shift($toc);
409
+
410
+			// Can we stay in this column?
411
+			if ($current_column_count <= $column_avg && $section_count > 4) {
412
+				// Don't forget to account for the heading also.
413
+				$current_column_count += count($section) + 1;
414
+			} else {
415
+				$current_column_count = 0;
416
+				$current_column++;
417
+			}
418
+
419
+			$columns[$current_column][$keys[$i]] = $section;
420
+		}
421
+
422
+		return $columns;
423
+	}
424
+
425
+	//--------------------------------------------------------------------
426
+
427
+	//--------------------------------------------------------------------
428
+	// Folder Methods
429
+	//--------------------------------------------------------------------
430
+
431
+	/**
432
+	 * Returns the current docFolders array.
433
+	 *
434
+	 * @return array
435
+	 */
436
+	public function docFolders()
437
+	{
438
+		return $this->doc_folders;
439
+	}
440
+
441
+	//--------------------------------------------------------------------
442
+
443
+	/**
444
+	 * Registers a path to be used when searching for documentation files.
445
+	 *
446
+	 * @param $name     A nickname to reference it by later.
447
+	 * @param $path     The server path to the folder.
448
+	 * @return $this
449
+	 */
450
+	public function addDocFolder($name, $path)
451
+	{
452
+		// Standardize the path
453
+		$path = realpath($path) . '/';
454
+
455
+		// realpath will return FALSE if the path doesn't exist
456
+		// or the script doesn't have access to it.
457
+		if (! $path || $path == '/') {
458
+			return $this;
459
+		}
460
+
461
+		$name = strtolower($name);
462
+
463
+		$this->doc_folders[$name] = $path;
464
+
465
+		return $this;
466
+	}
467
+
468
+	//--------------------------------------------------------------------
469
+
470
+	/**
471
+	 * Removes a folder from the folders we scan for documentation files
472
+	 * within.
473
+	 *
474
+	 * @param $name
475
+	 * @return $this
476
+	 */
477
+	public function removeDocFolder($name)
478
+	{
479
+		$name = strtolower($name);
480
+
481
+		if (isset($this->doc_folders[$name])) {
482
+			unset($this->doc_folders[$name]);
483
+		}
484
+
485
+		return $this;
486
+	}
487
+
488
+	//--------------------------------------------------------------------
489
+
490
+	//--------------------------------------------------------------------
491
+	// Private Methods
492
+	//--------------------------------------------------------------------
493
+
494
+	/**
495
+	 * Analyzes the passed in current url string and checks against
496
+	 * a list of groups to determine what the current group is.
497
+	 *
498
+	 * @param $current_url
499
+	 * @param $groups
500
+	 * @return string
501
+	 */
502
+	protected function detectCurrentFolder($current_url, $groups = [])
503
+	{
504
+		if (! is_array($groups)) {
505
+			return null;
506
+		}
507
+
508
+		$segments = explode('/', $current_url);
509
+
510
+		// We start from the back of the array since
511
+		// that's most likely to be close to the end.
512
+		$segments = array_reverse($segments);
513
+
514
+		foreach ($segments as $segment) {
515
+			foreach ($groups as $group) {
516
+				if (strtolower($group) == strtolower($segment)) {
517
+					return $group;
518
+				}
519
+			}
520
+		}
521
+
522
+		// Nothing found?
523
+		return null;
524
+	}
525
+
526
+	//--------------------------------------------------------------------
527
+
528
+	//--------------------------------------------------------------------
529
+	// Private Methods
530
+	//--------------------------------------------------------------------
531
+
532
+	/**
533
+	 * Locates the file on disk and reads the contents into a single string.
534
+	 *
535
+	 * If a folder Nickname (see addDocFolder() ) is passed as the second parameter,
536
+	 * it will limit it's search to that single folder. If nothing is passed, it will
537
+	 * search through all of the folders in the order they were given to the library,
538
+	 * until it finds the first one.
539
+	 *
540
+	 * @param string $path The 'path' of the file (relative to the docs
541
+	 *                                 folder. Usually from the URI)
542
+	 * @param string $restrictToFolder (Optional) The nickname of one of the
543
+	 *                                 folders to restrict the search to.
544
+	 *
545
+	 * @throws RuntimeException
546
+	 * @return null|string
547
+	 */
548
+	private function locateAndReadFile($path, $restrictToFolder = null)
549
+	{
550
+		$folders = $this->doc_folders;
551
+
552
+		if (! is_null($restrictToFolder)) {
553
+			// Make sure the folder exists
554
+			if (! is_null($restrictToFolder) && ! isset($this->doc_folders[$restrictToFolder])) {
555
+				throw new \RuntimeException('You must add the docs folder that you wish to find docs from.');
556
+			}
557
+
558
+			$folders = [$this->doc_folders[$restrictToFolder]];
559
+		}
560
+
561
+		foreach ($folders as $alias => $folder) {
562
+			if (file_exists($folder . $path . $this->docs_ext)) {
563
+				// Store the alias so we know which folder we're in.
564
+				$this->current_folder = $alias;
565
+
566
+				return file_get_contents($folder . $path . $this->docs_ext);
567
+			}
568
+		}
569
+
570
+		return null;
571
+	}
572
+
573
+	//--------------------------------------------------------------------
574
+
575
+	/**
576
+	 * Re-formats the passed in link.
577
+	 *
578
+	 * @param $link
579
+	 * @param $current_url
580
+	 * @param $site_url
581
+	 * @return mixed
582
+	 */
583
+	private function reformatAnchor($link, $groups, $current_url, $site_url)
584
+	{
585
+		// Grab the href value.
586
+		$href = $link->attributes()->href;
587
+
588
+		// If the href is null, it's probably a named anchor with no content.
589
+		if (! $href) {
590
+			// Make sure it has an href, else the XML will not close this
591
+			// tag correctly.
592
+			$link['href'] = ' ';
593
+
594
+			return $link;
595
+		}
596
+
597
+		// Remove any trailing # signs
598
+		$href = rtrim($href, '# ');
599
+
600
+		// If the href starts with #, then attach the current_url to it
601
+		if ($href != '' && substr_compare($href, '#', 0, 1) === 0) {
602
+			$link['href'] = $current_url . $href;
603
+
604
+			return $link;
605
+		}
606
+
607
+		// If it's a full external path, go on...
608
+		if ((strpos($href, 'http://') !== false || strpos($href, 'https://') !== false) &&
609
+			strpos($href, $site_url) === false
610
+		) {
611
+			$link['target'] = "_blank";
612
+			return $link;
613
+		}
614
+
615
+		// If it's a full local path, get rid of it.
616
+		if (strpos($href, $site_url) !== false) {
617
+			$href = str_replace($site_url, '', $href);
618
+		}
619
+
620
+		// Strip out some unnecessary items, just in case they're there.
621
+		if (substr($href, 0, strlen('docs/')) == 'docs/') {
622
+			$href = substr($href, strlen('docs/'));
623
+		}
624
+
625
+		// This includes 'bonfire/' if it was missed during the conversion.
626
+		if (substr($href, 0, strlen('bonfire/')) == 'bonfire/') {
627
+			$href = substr($href, strlen('bonfire/'));
628
+		}
629
+
630
+		// If another 'group' is not already defined at the head of the link
631
+		// then add the current group to it.
632
+		$group_found = false;
633
+
634
+		foreach ($groups as $group) {
635
+			if (strpos($href, $group) === 0) {
636
+				$group_found = true;
637
+			}
638
+		}
639
+
640
+		if (! $group_found) {
641
+			$href = $this->current_folder . '/' . $href;
642
+		}
643
+
644
+		// Convert to full site_url
645
+		if (strpos($href, 'http') !== 0) {
646
+			$href = $site_url . 'docs/' . ltrim($href, '/ ');
647
+		}
648
+
649
+		// Save the corrected href
650
+		$link['href'] = $href;
651
+
652
+		return $link;
653
+	}
654
+
655
+	//--------------------------------------------------------------------
656
+
657
+	/**
658
+	 * Creates a Document Map based on <h2> and <h3> tags.
659
+	 * Also adds named anchors into the $content so the map
660
+	 * can link to the content properly.
661
+	 *
662
+	 * @param $content
663
+	 * @param $xml
664
+	 * @param $map
665
+	 * @return array
666
+	 */
667
+	protected function extractDocMapAndAddAnchors(&$content, $xml, $map)
668
+	{
669
+		// Holds the current h2 we're processing
670
+		$current_obj = [];
671
+
672
+		$currentChild = 0;
673
+
674
+		foreach ($xml->children() as $childType => $line) {
675
+			$currentChild++;
676
+
677
+			// If it's an h1 - take the first and make it
678
+			// our page title.
679
+			if ($childType == 'h1' && empty($this->page_title))
680
+			{
681
+				$this->page_title = (string)$line;
682
+			}
683
+
684
+			// Make sure that our current object is
685
+			// stored and reset.
686
+			if ($childType == 'h1' || $childType == 'h2') {
687
+				if (count($current_obj)) {
688
+					$map[] = $current_obj;
689
+					$current_obj = [];
690
+				}
691
+			}
692
+
693
+			if ($childType == 'h2') {
694
+				$name = (string)$line;
695
+				$link = strtolower(str_replace(' ', '_', (string)$line));
696
+
697
+				$current_obj['name'] = $name;
698
+				$current_obj['link'] = '#' . $link;
699
+				$current_obj['items'] = [];
700
+
701
+				// Insert a named anchor into the $content
702
+				$anchor = '<a name="' . $link . '" id="' . $link . '" ></a>';
703
+
704
+				$search = "<h2>{$name}</h2>";
705
+
706
+				$content = str_replace($search, $anchor . $search, $content);
707
+			} elseif ($childType == 'h3') {
708
+				// Make sure we have some place to store the items.
709
+				if (! isset($current_obj['items'])) {
710
+					$current_obj['items'] = [];
711
+				}
712
+
713
+				$link = strtolower(str_replace(' ', '_', (string)$line));
714
+				$name = (string)$line;
715
+
716
+				$current_obj['items'][] = [
717
+					'name' => $name,
718
+					'link' => '#' . $link
719
+				];
720
+
721
+				// Insert a named anchor into the $content
722
+				$anchor = '<a name="' . $link . '" id="' . $link . '" ></a>';
723
+
724
+				$search = "<h3>{$name}</h3>";
725
+
726
+				$content = str_replace($search, $anchor . $search, $content);
727
+			}
728
+
729
+			// Is this the last element? Then close out our current object.
730
+			if (count($xml) == $currentChild) {
731
+				if (count($current_obj)) {
732
+					$map[] = $current_obj;
733
+				}
734
+			}
735
+		}
736
+		return [$map, $content];
737
+	}
738
+	//--------------------------------------------------------------------
739
+
740
+	/**
741
+	 * Create a Directory Map
742
+	 *
743
+	 * Reads the specified directory and builds an array
744
+	 * representation of it. Sub-folders contained with the
745
+	 * directory will be mapped as well.
746
+	 *
747
+	 * @param    string $source_dir Path to source
748
+	 * @param    int $directory_depth Depth of directories to traverse
749
+	 *                        (0 = fully recursive, 1 = current dir, etc)
750
+	 * @param    bool $hidden Whether to show hidden files
751
+	 * @return    array
752
+	 */
753
+	protected function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE)
754
+	{
755
+		if ($fp = @opendir($source_dir)) {
756
+			$filedata = array();
757
+			$new_depth = $directory_depth - 1;
758
+			$source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
759
+
760
+			while (FALSE !== ($file = readdir($fp))) {
761
+				// Remove '.', '..', and hidden files [optional]
762
+				if ($file === '.' OR $file === '..' OR ($hidden === FALSE && $file[0] === '.')) {
763
+					continue;
764
+				}
765
+
766
+				is_dir($source_dir . $file) && $file .= DIRECTORY_SEPARATOR;
767
+
768
+				if (($directory_depth < 1 OR $new_depth > 0) && is_dir($source_dir . $file)) {
769
+					$filedata[$file] = directory_map($source_dir . $file, $new_depth, $hidden);
770
+				} else {
771
+					$filedata[] = $file;
772
+				}
773
+			}
774
+
775
+			closedir($fp);
776
+			return $filedata;
777
+		}
778
+
779
+		return FALSE;
780
+	}
781
+
782
+	//--------------------------------------------------------------------
783 783
 
784 784
 }
Please login to merge, or discard this patch.
myth/Docs/DocBuilderInterface.php 1 patch
Indentation   +103 added lines, -103 removed lines patch added patch discarded remove patch
@@ -40,117 +40,117 @@
 block discarded – undo
40 40
  */
41 41
 interface DocBuilderInterface
42 42
 {
43
-    /**
44
-     * Does the actual work of reading in and parsing the help file.
45
-     * If a folder Nickname (see addDocFolder() ) is passed as the second parameter,
46
-     * it will limit it's search to that single folder. If nothing is passed, it will
47
-     * search through all of the folders in the order they were given to the library,
48
-     * until it finds the first one.
49
-     *
50
-     * @param string $path The 'path' of the file (relative to the docs
51
-     *                                 folder. Usually from the URI)
52
-     * @param string $restrictToFolder (Optional) The folder nickname
53
-     *
54
-     * @return string
55
-     */
56
-    public function readPage($path, $restrictToFolder = null);
43
+	/**
44
+	 * Does the actual work of reading in and parsing the help file.
45
+	 * If a folder Nickname (see addDocFolder() ) is passed as the second parameter,
46
+	 * it will limit it's search to that single folder. If nothing is passed, it will
47
+	 * search through all of the folders in the order they were given to the library,
48
+	 * until it finds the first one.
49
+	 *
50
+	 * @param string $path The 'path' of the file (relative to the docs
51
+	 *                                 folder. Usually from the URI)
52
+	 * @param string $restrictToFolder (Optional) The folder nickname
53
+	 *
54
+	 * @return string
55
+	 */
56
+	public function readPage($path, $restrictToFolder = null);
57 57
 
58
-    /**
59
-     * Parses the contents. Currently runs through the Markdown Extended
60
-     * parser to convert to HTML.
61
-     *
62
-     * @param $str
63
-     * @return mixed
64
-     */
65
-    public function parse($str);
58
+	/**
59
+	 * Parses the contents. Currently runs through the Markdown Extended
60
+	 * parser to convert to HTML.
61
+	 *
62
+	 * @param $str
63
+	 * @return mixed
64
+	 */
65
+	public function parse($str);
66 66
 
67
-    /**
68
-     * Perform a few housekeeping tasks on a page, like rewriting URLs to full
69
-     * URLs, not relative, ensuring they link correctly, etc.
70
-     *
71
-     * @param      $content
72
-     * @param null $site_url
73
-     * @param null $current_url
74
-     * @return string   The post-processed HTML.
75
-     */
76
-    public function postProcess($content, $site_url = null, $current_url = null);
67
+	/**
68
+	 * Perform a few housekeeping tasks on a page, like rewriting URLs to full
69
+	 * URLs, not relative, ensuring they link correctly, etc.
70
+	 *
71
+	 * @param      $content
72
+	 * @param null $site_url
73
+	 * @param null $current_url
74
+	 * @return string   The post-processed HTML.
75
+	 */
76
+	public function postProcess($content, $site_url = null, $current_url = null);
77 77
 
78
-    /**
79
-     * Allows users to define the classes that are attached to
80
-     * generated tables.
81
-     *
82
-     * @param null $classes
83
-     * @return $this
84
-     */
85
-    public function setTableClasses($classes = null);
78
+	/**
79
+	 * Allows users to define the classes that are attached to
80
+	 * generated tables.
81
+	 *
82
+	 * @param null $classes
83
+	 * @return $this
84
+	 */
85
+	public function setTableClasses($classes = null);
86 86
 
87
-    /**
88
-     * Given the contents to render, will build a list of links for the sidebar
89
-     * out of the headings in the file.
90
-     *
91
-     * Note: Will ONLY use h2 and h3 to build the links from.
92
-     *
93
-     * Note: The $content passed in WILL be modified by adding named anchors
94
-     * that match up with the locations.
95
-     *
96
-     * @param string $content The HTML to analyse for headings.
97
-     * @return string
98
-     */
99
-    public function buildDocumentMap(&$content);
87
+	/**
88
+	 * Given the contents to render, will build a list of links for the sidebar
89
+	 * out of the headings in the file.
90
+	 *
91
+	 * Note: Will ONLY use h2 and h3 to build the links from.
92
+	 *
93
+	 * Note: The $content passed in WILL be modified by adding named anchors
94
+	 * that match up with the locations.
95
+	 *
96
+	 * @param string $content The HTML to analyse for headings.
97
+	 * @return string
98
+	 */
99
+	public function buildDocumentMap(&$content);
100 100
 
101
-    /**
102
-     * Stores the name of the callback method to run to convert the source
103
-     * files to viewable files. By default, this should be used to register
104
-     * a Mardown Extended formatter with the system, but could be used to
105
-     * extend the
106
-     *
107
-     * @param string $callback_name
108
-     * @param bool $cascade // If FALSE the formatting of a component ends here. If TRUE, will be passed to next formatter.
109
-     * @return $this
110
-     */
111
-    public function registerFormatter($callback_name = '', $cascade = false);
101
+	/**
102
+	 * Stores the name of the callback method to run to convert the source
103
+	 * files to viewable files. By default, this should be used to register
104
+	 * a Mardown Extended formatter with the system, but could be used to
105
+	 * extend the
106
+	 *
107
+	 * @param string $callback_name
108
+	 * @param bool $cascade // If FALSE the formatting of a component ends here. If TRUE, will be passed to next formatter.
109
+	 * @return $this
110
+	 */
111
+	public function registerFormatter($callback_name = '', $cascade = false);
112 112
 
113
-    /**
114
-     * Runs the text through the registered formatters.
115
-     *
116
-     * @param $str
117
-     * @return mixed
118
-     */
119
-    public function format($str);
113
+	/**
114
+	 * Runs the text through the registered formatters.
115
+	 *
116
+	 * @param $str
117
+	 * @return mixed
118
+	 */
119
+	public function format($str);
120 120
 
121
-    /**
122
-     * Retrieves the list of files in a folder and preps the name and filename
123
-     * so it's ready for creating the HTML.
124
-     *
125
-     * @param  String $folder The path to the folder to retrieve.
126
-     *
127
-     * @return Array  An associative array @see parse_ini_file for format
128
-     * details.
129
-     */
130
-    public function buildTOC($folder);
121
+	/**
122
+	 * Retrieves the list of files in a folder and preps the name and filename
123
+	 * so it's ready for creating the HTML.
124
+	 *
125
+	 * @param  String $folder The path to the folder to retrieve.
126
+	 *
127
+	 * @return Array  An associative array @see parse_ini_file for format
128
+	 * details.
129
+	 */
130
+	public function buildTOC($folder);
131 131
 
132
-    /**
133
-     * Returns the current docFolders array.
134
-     *
135
-     * @return array
136
-     */
137
-    public function docFolders();
132
+	/**
133
+	 * Returns the current docFolders array.
134
+	 *
135
+	 * @return array
136
+	 */
137
+	public function docFolders();
138 138
 
139
-    /**
140
-     * Registers a path to be used when searching for documentation files.
141
-     *
142
-     * @param $name     A nickname to reference it by later.
143
-     * @param $path     The server path to the folder.
144
-     * @return $this
145
-     */
146
-    public function addDocFolder($name, $path);
139
+	/**
140
+	 * Registers a path to be used when searching for documentation files.
141
+	 *
142
+	 * @param $name     A nickname to reference it by later.
143
+	 * @param $path     The server path to the folder.
144
+	 * @return $this
145
+	 */
146
+	public function addDocFolder($name, $path);
147 147
 
148
-    /**
149
-     * Removes a folder from the folders we scan for documentation files
150
-     * within.
151
-     *
152
-     * @param $name
153
-     * @return $this
154
-     */
155
-    public function removeDocFolder($name);
148
+	/**
149
+	 * Removes a folder from the folders we scan for documentation files
150
+	 * within.
151
+	 *
152
+	 * @param $name
153
+	 * @return $this
154
+	 */
155
+	public function removeDocFolder($name);
156 156
 }
Please login to merge, or discard this patch.
myth/Forensics/Profiler.php 1 patch
Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -531,16 +531,16 @@
 block discarded – undo
531 531
 
532 532
 
533 533
 	public static function get_file_size($size, $retstring = null) {
534
-        // adapted from code at http://aidanlister.com/repos/v/function.size_readable.php
535
-	    $sizes = array('bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
534
+		// adapted from code at http://aidanlister.com/repos/v/function.size_readable.php
535
+		$sizes = array('bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
536 536
 
537
-	    if ($retstring === null) { $retstring = '%01.2f %s'; }
537
+		if ($retstring === null) { $retstring = '%01.2f %s'; }
538 538
 
539 539
 		$lastsizestring = end($sizes);
540 540
 
541 541
 		foreach ($sizes as $sizestring) {
542
-	       	if ($size < 1024) { break; }
543
-	           if ($sizestring != $lastsizestring) { $size /= 1024; }
542
+		   	if ($size < 1024) { break; }
543
+			   if ($sizestring != $lastsizestring) { $size /= 1024; }
544 544
 		}
545 545
 
546 546
 		if ($sizestring == $sizes[0]) { $retstring = '%01d %s'; } // Bytes aren't normally fractional
Please login to merge, or discard this patch.