1<?php
2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
3//
4// All Rights Reserved. See copyright.txt for details and a complete list of authors.
5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
6// $Id$
7
8class BOMChecker_Scanner
9{
10
11	// Tiki source folder
12	protected $sourceDir = __DIR__ . '/../../../';
13
14	protected $scanExtensions = [
15		'php',
16		'tpl'
17	];
18
19	// The number of files scanned.
20	protected $scannedFiles = 0;
21
22	// The list of files detected with BOM
23	protected $bomFiles = [];
24
25	/**
26	 * @param string $scanDir The file directory to scan.
27	 * @param array $scanExtensions An array with the file extensions to scan for BOM.
28	 */
29	public function __construct($scanDir = null, $scanExtensions = [])
30	{
31		if (! empty($scanDir) && is_dir($scanDir)) {
32			$this->sourceDir = $scanDir;
33		}
34
35		if (is_array($scanExtensions)&&count($scanExtensions)) {
36			$this->scanExtensions = $scanExtensions;
37		}
38	}
39
40	/**
41	 * Scan the folder for BOM files
42	 * @return array
43	 *  An array with the path to the BOM detected files.
44	 */
45	public function scan()
46	{
47		$this->checkDir($this->sourceDir);
48		return $this->bomFiles;
49	}
50
51	/**
52	 * Check directory path
53	 *
54	 * @param string $sourceDir
55	 * @return void
56	 */
57	protected function checkDir($sourceDir)
58	{
59		$sourceDir = $this->fixDirSlash($sourceDir);
60
61		// Copy files and directories.
62		$sourceDirHandler = opendir($sourceDir);
63
64		while ($file = readdir($sourceDirHandler)) {
65			// Skip ".", ".." and hidden fields (Unix).
66			if (substr($file, 0, 1) == '.') {
67				continue;
68			}
69
70			$sourcefilePath = $sourceDir . $file;
71
72			if (is_dir($sourcefilePath)) {
73				$this->checkDir($sourcefilePath);
74			}
75
76			if (! is_file($sourcefilePath)
77				|| ! in_array($this->getFileExtension($sourcefilePath), $this->scanExtensions)
78				|| ! $this->checkUtf8Bom($sourcefilePath)
79			) {
80				continue;
81			}
82			$this->bomFiles[] = str_replace($this->sourceDir, '', $sourcefilePath);
83		}
84	}
85
86	/**
87	 * Check and change slash directory path
88	 *
89	 * @param string $dirPath
90	 * @return string
91	 */
92	protected function fixDirSlash($dirPath)
93	{
94		$dirPath = str_replace('\\', '/', $dirPath);
95
96		if (substr($dirPath, -1, 1) != '/') {
97			$dirPath .= '/';
98		}
99
100		return $dirPath;
101	}
102
103	/**
104	 * Get file extension
105	 *
106	 * @param string $filePath
107	 * @return string
108	 */
109	protected function getFileExtension($filePath)
110	{
111		$info = pathinfo($filePath);
112		return isset($info['extension']) ? $info['extension'] : '';
113	}
114
115	/**
116	 * Check if UTF-8 BOM codification file
117	 *
118	 * @param string $filePath
119	 * @return bool
120	 */
121	protected function checkUtf8Bom($filePath)
122	{
123		$file = fopen($filePath, 'r');
124		$data = fgets($file, 10);
125		fclose($file);
126
127		$this->scannedFiles++;
128
129		return (substr($data, 0, 3) == "\xEF\xBB\xBF");
130	}
131
132	/**
133	 * Get the number of files scanned.
134	 *
135	 * @return int
136	 */
137	public function getScannedFiles()
138	{
139		return $this->scannedFiles;
140	}
141
142	/**
143	 * Get the list of files detected with BOM.
144	 *
145	 * @return array
146	 */
147	public function getBomFiles()
148	{
149		return $this->bomFiles;
150	}
151}
152