This file is indexed.

/usr/share/php/kohana3.2/modules/userguide/classes/kohana/controller/userguide.php is in libkohana3.2-mod-userguide-php 3.2.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
<?php defined('SYSPATH') or die('No direct script access.');
/**
 * Kohana user guide and api browser.
 *
 * @package    Kohana/Userguide
 * @category   Controllers
 * @author     Kohana Team
 */
abstract class Kohana_Controller_Userguide extends Controller_Template {

	public $template = 'userguide/template';

	// Routes
	protected $media;
	protected $api;
	protected $guide;

	public function before()
	{
		parent::before();

		if ($this->request->action() === 'media')
		{
			// Do not template media files
			$this->auto_render = FALSE;
		}
		else
		{
			// Grab the necessary routes
			$this->media = Route::get('docs/media');
			$this->guide = Route::get('docs/guide');

			// Set the base URL for links and images
			Kodoc_Markdown::$base_url  = URL::site($this->guide->uri()).'/';
			Kodoc_Markdown::$image_url = URL::site($this->media->uri()).'/';
		}

		// Default show_comments to config value
		$this->template->show_comments = Kohana::$config->load('userguide.show_comments');
	}
	
	// List all modules that have userguides
	public function index()
	{
		$this->template->title = "Userguide";
		$this->template->breadcrumb = array('User Guide');
		$this->template->content = View::factory('userguide/index', array('modules' => $this->_modules()));
		$this->template->menu = View::factory('userguide/menu', array('modules' => $this->_modules()));
		
		// Don't show disqus on the index page
		$this->template->show_comments = FALSE;
	}
	
	// Display an error if a page isn't found
	public function error($message)
	{
		$this->response->status(404);
		$this->template->title = "Userguide - Error";
		$this->template->content = View::factory('userguide/error',array('message' => $message));
		
		// Don't show disqus on error pages
		$this->template->show_comments = FALSE;

		// If we are in a module and that module has a menu, show that
		if ($module = $this->request->param('module') AND $menu = $this->file($module.'/menu') AND Kohana::$config->load('userguide.modules.'.$module.'.enabled'))
		{
			// Namespace the markdown parser
			Kodoc_Markdown::$base_url  = URL::site($this->guide->uri()).'/'.$module.'/';
			Kodoc_Markdown::$image_url = URL::site($this->media->uri()).'/'.$module.'/';

			$this->template->menu = Kodoc_Markdown::markdown($this->_get_all_menu_markdown());
			$this->template->breadcrumb = array(
				$this->guide->uri() => 'User Guide',
				$this->guide->uri(array('module' => $module)) => Kohana::$config->load('userguide.modules.'.$module.'.name'),
				'Error'
			);
		}
		// If we are in the api browser, show the menu and show the api browser in the breadcrumbs
		else if (Route::name($this->request->route()) == 'docs/api')
		{
			$this->template->menu = Kodoc::menu();

			// Bind the breadcrumb
			$this->template->breadcrumb = array(
				$this->guide->uri(array('page' => NULL)) => 'User Guide',
				$this->request->route()->uri() => 'API Browser',
				'Error'
			);
		}
		// Otherwise, show the userguide module menu on the side
		else
		{
			$this->template->menu = View::factory('userguide/menu',array('modules' => $this->_modules()));
			$this->template->breadcrumb = array($this->request->route()->uri() => 'User Guide','Error');
		}
	}

	public function action_docs()
	{
		$module = $this->request->param('module');
		$page = $this->request->param('page');

		// Trim trailing slash
		$page = rtrim($page, '/');

		// If no module provided in the url, show the user guide index page, which lists the modules.
		if ( ! $module)
		{
			return $this->index();
		}
		
		// If this module's userguide pages are disabled, show the error page
		if ( ! Kohana::$config->load('userguide.modules.'.$module.'.enabled'))
		{
			return $this->error('That module doesn\'t exist, or has userguide pages disabled.');
		}
		
		// Prevent "guide/module" and "guide/module/index" from having duplicate content
		if ( $page == 'index')
		{
			return $this->error('Userguide page not found');
		}
		
		// If a module is set, but no page was provided in the url, show the index page
		if ( ! $page )
		{
			$page = 'index';
		}

		// Find the markdown file for this page
		$file = $this->file($module.'/'.$page);

		// If it's not found, show the error page
		if ( ! $file)
		{
			return $this->error('Userguide page not found');
		}
		
		// Namespace the markdown parser
		Kodoc_Markdown::$base_url  = URL::site($this->guide->uri()).'/'.$module.'/';
		Kodoc_Markdown::$image_url = URL::site($this->media->uri()).'/'.$module.'/';

		// Set the page title
		$this->template->title = $page == 'index' ? Kohana::$config->load('userguide.modules.'.$module.'.name') : $this->title($page);

		// Parse the page contents into the template
		Kodoc_Markdown::$show_toc = true;
		$this->template->content = Kodoc_Markdown::markdown(file_get_contents($file));
		Kodoc_Markdown::$show_toc = false;

		// Attach this module's menu to the template
		$this->template->menu = Kodoc_Markdown::markdown($this->_get_all_menu_markdown());

		// Bind the breadcrumb
		$this->template->bind('breadcrumb', $breadcrumb);
		
		// Bind the copyright
		$this->template->copyright = Kohana::$config->load('userguide.modules.'.$module.'.copyright');

		// Add the breadcrumb trail
		$breadcrumb = array();
		$breadcrumb[$this->guide->uri()] = 'User Guide';
		$breadcrumb[$this->guide->uri(array('module' => $module))] = Kohana::$config->load('userguide.modules.'.$module.'.name');
		
		// TODO try and get parent category names (from menu).  Regex magic or javascript dom stuff perhaps?
		
		// Only add the current page title to breadcrumbs if it isn't the index, otherwise we get repeats.
		if ($page != 'index')
		{
			$breadcrumb[] = $this->template->title;
		}
	}

	public function action_api()
	{
		// Enable the missing class autoloader.  If a class cannot be found a
		// fake class will be created that extends Kodoc_Missing
		spl_autoload_register(array('Kodoc_Missing', 'create_class'));

		// Get the class from the request
		$class = $this->request->param('class');

		// If no class was passed to the url, display the API index page
		if ( ! $class)
		{
			$this->template->title = 'Table of Contents';

			$this->template->content = View::factory('userguide/api/toc')
				->set('classes', Kodoc::class_methods())
				->set('route', $this->request->route());
		}
		else
		{
			// Create the Kodoc_Class version of this class.
			$_class = Kodoc_Class::factory($class);
			
			// If the class requested and the actual class name are different
			// (different case, orm vs ORM, auth vs Auth) redirect
			if ($_class->class->name != $class)
			{
				$this->request->redirect($this->request->route()->uri(array('class'=>$_class->class->name)));
			}

			// If this classes immediate parent is Kodoc_Missing, then it should 404
			if ($_class->class->getParentClass() AND $_class->class->getParentClass()->name == 'Kodoc_Missing')
				return $this->error('That class was not found. Check your url and make sure that the module with that class is enabled.');

			// If this classes package has been disabled via the config, 404
			if ( ! Kodoc::show_class($_class))
				return $this->error('That class is in package that is hidden.  Check the <code>api_packages</code> config setting.');
		
			// Everything is fine, display the class.
			$this->template->title = $class;

			$this->template->content = View::factory('userguide/api/class')
				->set('doc', Kodoc::factory($class))
				->set('route', $this->request->route());
		}

		// Attach the menu to the template
		$this->template->menu = Kodoc::menu();

		// Bind the breadcrumb
		$this->template->bind('breadcrumb', $breadcrumb);

		// Get the docs URI
		$guide = Route::get('docs/guide');

		// Add the breadcrumb
		$breadcrumb = array();
		$breadcrumb[$this->guide->uri(array('page' => NULL))] = 'User Guide';
		$breadcrumb[$this->request->route()->uri()] = 'API Browser';
		$breadcrumb[] = $this->template->title;
	}

	public function action_media()
	{
		// Get the file path from the request
		$file = $this->request->param('file');

		// Find the file extension
		$ext = pathinfo($file, PATHINFO_EXTENSION);

		// Remove the extension from the filename
		$file = substr($file, 0, -(strlen($ext) + 1));

		if ($file = Kohana::find_file('media/guide', $file, $ext))
		{
			// Check if the browser sent an "if-none-match: <etag>" header, and tell if the file hasn't changed
			$this->response->check_cache(sha1($this->request->uri()).filemtime($file), $this->request);
			
			// Send the file content as the response
			$this->response->body(file_get_contents($file));

			// Set the proper headers to allow caching
			$this->response->headers('content-type',  File::mime_by_ext($ext));
			$this->response->headers('last-modified', date('r', filemtime($file)));
		}
		else
		{
			// Return a 404 status
			$this->response->status(404);
		}
	}

	public function after()
	{
		if ($this->auto_render)
		{
			// Get the media route
			$media = Route::get('docs/media');

			// Add styles
			$this->template->styles = array(
				$media->uri(array('file' => 'css/print.css'))  => 'print',
				$media->uri(array('file' => 'css/screen.css')) => 'screen',
				$media->uri(array('file' => 'css/kodoc.css'))  => 'screen',
				$media->uri(array('file' => 'css/shCore.css')) => 'screen',
				$media->uri(array('file' => 'css/shThemeKodoc.css')) => 'screen',
			);

			// Add scripts
			$this->template->scripts = array(
				$media->uri(array('file' => 'js/jquery.min.js')),
				$media->uri(array('file' => 'js/jquery.cookie.js')),
				$media->uri(array('file' => 'js/kodoc.js')),
				// Syntax Highlighter
				$media->uri(array('file' => 'js/shCore.js')),
				$media->uri(array('file' => 'js/shBrushPhp.js')),
			);

			// Add languages
			$this->template->translations = Kohana::message('userguide', 'translations');
		}

		return parent::after();
	}

	/**
	 * Locates the appropriate markdown file for a given guide page. Page URLS
	 * can be specified in one of three forms:
	 *
	 *  * userguide/adding
	 *  * userguide/adding.md
	 *  * userguide/adding.markdown
	 *
	 * In every case, the userguide will search the cascading file system paths
	 * for the file guide/userguide/adding.md.
	 *
	 * @param string $page The relative URL of the guide page
	 * @return string
	 */
	public function file($page)
	{

		// Strip optional .md or .markdown suffix from the passed filename
		$info = pathinfo($page);
		if (isset($info['extension'])
			AND (($info['extension'] === 'md') OR ($info['extension'] === 'markdown')))
		{
			$page = $info['dirname'].DIRECTORY_SEPARATOR.$info['filename'];
		}
		return Kohana::find_file('guide', $page, 'md');
	}

	public function section($page)
	{
		$markdown = $this->_get_all_menu_markdown();
		
		if (preg_match('~\*{2}(.+?)\*{2}[^*]+\[[^\]]+\]\('.preg_quote($page).'\)~mu', $markdown, $matches))
		{
			return $matches[1];
		}
		
		return $page;
	}

	public function title($page)
	{
		$markdown = $this->_get_all_menu_markdown();
		
		if (preg_match('~\[([^\]]+)\]\('.preg_quote($page).'\)~mu', $markdown, $matches))
		{
			// Found a title for this link
			return $matches[1];
		}
		
		return $page;
	}
	
	protected function _get_all_menu_markdown()
	{
		// Only do this once per request...
		static $markdown = '';
		
		if (empty($markdown))
		{
			// Get menu items
			$file = $this->file($this->request->param('module').'/menu');
	
			if ($file AND $text = file_get_contents($file))
			{
				// Add spans around non-link categories. This is a terrible hack.
				//echo Debug::vars($text);
				
				//$text = preg_replace('/(\s*[\-\*\+]\s*)(.*)/','$1<span>$2</span>',$text);
				$text = preg_replace('/^(\s*[\-\*\+]\s*)([^\[\]]+)$/m','$1<span>$2</span>',$text);
				//echo Debug::vars($text);
				$markdown .= $text;
			}
			
		}
		
		return $markdown;
	}
	
	// Get the list of modules from the config, and reverses it so it displays in the order the modules are added, but move Kohana to the top.
	protected function _modules()
	{
		$modules = array_reverse(Kohana::$config->load('userguide.modules'));
		
		if (isset($modules['kohana']))
		{
			$kohana = $modules['kohana'];
			unset($modules['kohana']);
			$modules = array_merge(array('kohana' => $kohana), $modules);
		}
		
		// Remove modules that have been disabled via config
		foreach ($modules as $key => $value)
		{
			if ( ! Kohana::$config->load('userguide.modules.'.$key.'.enabled'))
			{
				unset($modules[$key]);
			}
		}
		
		return $modules;
	}

} // End Userguide