1: <?php
2: /**
3: * LICENSE (BSD)
4: *
5: * Copyright (c) 2013, Gerd Christian Kunze
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions are
10: * met:
11: *
12: * * Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: *
15: * * Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * * Neither the name of Gerd Christian Kunze nor the names of the
20: * contributors may be used to endorse or promote products derived from
21: * this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24: * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34: *
35: * Installer
36: * 15.02.2013 14:15
37: */
38: namespace MOC\Module;
39: use MOC\Api;
40: use MOC\Core\Changelog\Entry;
41: use MOC\Generic\Device\Module;
42:
43: /**
44: *
45: */
46: class Installer implements Module {
47: /**
48: * Get Dependencies
49: *
50: * @static
51: * @return \MOC\Core\Depending
52: * @noinspection PhpAbstractStaticMethodInspection
53: */
54: public static function InterfaceDepending() {
55: return Api::Core()->Depending();
56: }
57:
58: /**
59: * Get Singleton/Instance
60: *
61: * @static
62: * @return Installer
63: * @noinspection PhpAbstractStaticMethodInspection
64: */
65: public static function InterfaceInstance() {
66: return new Installer();
67: }
68:
69: /**
70: * Get Changelog
71: *
72: * @static
73: * @return \MOC\Core\Changelog
74: * @noinspection PhpAbstractStaticMethodInspection
75: */
76: public static function InterfaceChangelog() {
77: return Api::Core()->Changelog()->Create( __CLASS__ )
78: ->Build()->Clearance( '18.02.2013 14:28', 'Dev', __CLASS__ )
79: ->Update()->Added( '18.02.2013 14:29', 'Method Client(), Server()' )
80: ;
81: }
82:
83: /** @var array $ClassList */
84: private static $ClassList = array();
85:
86: /** @var array $ClassDirectory */
87: private $ClassDirectory = array(
88: 'Adapter',
89: 'Core', 'Extension', 'Module',
90: 'Plugin', 'Widget'
91: );
92:
93: /**
94: * @return bool
95: */
96: private function createClassList() {
97: if( empty( self::$ClassList ) ) {
98: $BaseDirectory = realpath( __DIR__.'/../' );
99: foreach( (array)$this->ClassDirectory as $ClassDirectory ) {
100: // Read Directory (recursive)
101: $FileList = Api::Module()
102: ->Drive()->Directory()->Open(
103: realpath( __DIR__.'/../'.$ClassDirectory )
104: )->FileList( true );
105: // Read Class-Definition of relevant File
106: array_walk( $FileList, function( &$File, $Index, $BaseDirectory ) {
107: /** @var \MOC\Module\Drive\File $File */
108: if(
109: false !== strpos( $File->GetPath(), '#Trash' )
110: || false !== strpos( $File->GetPath(), '3rdParty' )
111: || $File->GetExtension() !== 'php'
112: ) {
113: $File = false;
114: } else {
115: $File = '\\MOC'.str_replace( $BaseDirectory, '', $File->GetPath() ).'\\'.$File->GetName();
116: }
117: }, $BaseDirectory );
118: // Save to Class-List
119: $FileList = array_filter( $FileList );
120: self::$ClassList = array_merge( self::$ClassList, $FileList );
121: }
122: // Sort Class-List
123: sort( self::$ClassList );
124: return true;
125: } else {
126: return false;
127: }
128: }
129:
130:
131: public function sortLogByTimestamp() {
132: $this->createClassList();
133: $Log = array();
134: /** @var \MOC\Generic\Common $Class */
135: foreach( (array)self::$ClassList as $Class ) {
136: $Log = array_merge( $Log, $Class::InterfaceChangelog()->Log() );
137: }
138:
139: usort( $Log, function( Entry $A, Entry $B ) {
140: if( $A->Timestamp() > $B->Timestamp() ) {
141: return -1;
142: } else if( $A->Timestamp() < $B->Timestamp() ) {
143: return 1;
144: } else {
145: return 0;
146: }
147: });
148:
149: $Table = '<table style="font-family: arial; font-size: 12px; color: gray; text-align: left;"><thead><tr>'
150: .'<th>Timestamp</th><th>Location</th><th>Version</th><th>Type</th><th>Cause</th><th>Description</th>'
151: .'</tr></thead><tbody>';
152:
153: /** @var Entry $Entry */
154: foreach( (array)$Log as $Index => $Entry ) {
155: $Table .= '<tr style="'.(is_integer($Entry->Timestamp())?'':'color: red;').'">'
156: .'<td>'.(!is_integer($Entry->Timestamp())?'-NA-':date( 'd.m.Y H:i', $Entry->Timestamp() )).'</td>'
157: .'<td>'.$Entry->Location().'</td>'
158: .'<td>'.$Entry->Type().'</td>'
159: .'<td>'.$Entry->Cause().'</td>'
160: .'<td>'.$Entry->Version().'</td>'
161: .'<td>'.$Entry->Message().'</td>'
162: .'</tr>';
163: }
164:
165: $Table .= '</tbody></table>';
166:
167: print $Table;
168: }
169:
170:
171:
172: /**
173: * @return \MOC\Module\Drive\File[]
174: */
175: public function Depending() {
176: $this->createClassList();
177:
178: $Table = '<table style="font-family: arial; font-size: 12px; color: gray; text-align: left;"><thead><tr><th>Location</th><th>Version</th><th>Type</th><th>Cause</th><th>Description</th><th>Timestamp</th></tr></thead><tbody>';
179:
180: /** @var \MOC\Generic\Common $Class */
181: foreach( (array)self::$ClassList as $Class ) {
182: $rClass = new \ReflectionClass( $Class );
183: if( $rClass->hasMethod( 'InterfaceChangelog' ) ) {
184: $Log = $Class::InterfaceChangelog()->Log();
185: /** @var Entry $Entry */
186: foreach( (array)$Log as $Index => $Entry ) {
187: if( $Index ) {
188: $Table .= '<tr style="font-size: 9px; color: silver;">'
189: .'<td>'.$Entry->Location().'</td>'
190: .'<td>'.$Entry->Type().'</td>'
191: .'<td>'.$Entry->Cause().'</td>'
192: .'<td>'.$Entry->Version().'</td>'
193: .'<td>'.$Entry->Message().'</td>'
194: .'<td>'.(!is_integer($Entry->Timestamp())?'-NA-':date( 'd.m.Y H:i', $Entry->Timestamp() )).'</td>'
195: .'</tr>';
196: } else {
197: $Table .= '<tr style="'.(is_integer($Entry->Timestamp())?'':'color: red;').'">'
198: .'<td style="border-top: 1px dotted silver;">'.$Entry->Location().'</td>'
199: .'<td>'.$Entry->Type().'</td>'
200: .'<td>'.$Entry->Cause().'</td>'
201: .'<td>'.$Entry->Version().'</td>'
202: .'<td>'.$Entry->Message().'</td>'
203: .'<td>'.(!is_integer($Entry->Timestamp())?'-NA-':date( 'd.m.Y H:i', $Entry->Timestamp() )).'</td>'
204: .'</tr>';
205: }
206:
207: }
208: } else {
209: trigger_error( $Class.' Missing ::InterfaceChangelog' );
210: }
211: }
212:
213: $Table .= '</tbody></table>';
214:
215: print $Table;
216:
217: // var_dump( $ClassList );
218: /*
219: $VersionList = array();
220: $DependingList = array();
221: /** @var \MOC\Generic\Common $Class */
222: /* foreach( (array)$ClassList as $Class ) {
223: $rClass = new \ReflectionClass( $Class );
224: if( $rClass->hasMethod( 'InterfaceChangelog' ) ) {
225: $VersionList[(string)$Class] = $Class::InterfaceChangelog()->Version();
226: } else {
227: trigger_error( $Class.' Missing ::InterfaceChangelog' );
228: }
229: if( $rClass->hasMethod( 'InterfaceDepending' ) ) {
230: /** @var \MOC\Core\Depending $Depending */
231: /* $Depending = $Class::InterfaceDepending();
232: foreach( (array)$Depending->Dependencies as $ClassName => $Version ) {
233: if( in_array( $ClassName, array_keys($DependingList) ) ) {
234: if( Api::Core()->Version()->Compare( $DependingList[$ClassName], $Version ) ) {
235: $DependingList[$ClassName] = $Version;
236: }
237: } else {
238: $DependingList[$ClassName] = $Version;
239: }
240: }
241: } else {
242: trigger_error( $Class.' Missing ::InterfaceDepending' );
243: }
244: }
245:
246: //var_dump( $ClassList );
247:
248: // var_dump( $VersionList );
249: // var_dump( $DependingList );
250: /*
251: $VersionStatusList = array();
252: foreach( (array)$VersionList as $Class => $Version ) {
253: if( in_array( $Class, array_keys( $DependingList ) ) ) {
254: if( false !== Api::Core()->Version()->Compare( $DependingList[(string)$Class], $Version ) ) {
255: array_push( $VersionStatusList, array(
256: $Class,
257: $Version->Number(),
258: $DependingList[(string)$Class]->Number(),
259: 'OK'
260: ));
261: } else {
262: array_push( $VersionStatusList, array(
263: $Class,
264: $Version->Number(),
265: $DependingList[(string)$Class]->Number(),
266: 'Fehler'
267: ));
268: }
269: } else {
270: array_push( $VersionStatusList, array(
271: $Class,
272: $Version->Number(),
273: '-NA-',
274: 'OK'
275: ));
276: }
277: }
278:
279: var_dump( $VersionStatusList );
280:
281: /*
282: set_time_limit(1);
283: $Directory = 'Core';
284: /** @var \MOC\Module\Drive\File $File */
285: /* foreach( (array)$FileList as $File ) {
286: /** @var \MOC\Generic\Common $Class */
287: /* $Class = '\\MOC\\'.$Directory.'\\'.$File->GetName();
288: var_dump( $Class );
289:
290: $Dependencies = new Dependencies();
291:
292: $Dependencies->Name( $Class );
293:
294: var_dump( $Dependencies );
295:
296: //var_dump( $Class, $Class::InterfaceChangelog()->Number(), $Class::InterfaceDepending()->Dependencies );
297:
298: var_dump( $Class::InterfaceChangelog() );
299: var_dump( $Class::InterfaceDepending() );
300:
301: }
302:
303: return array();// $FileList;
304: */
305: }
306:
307:
308:
309:
310:
311:
312: /**
313: * @return Installer\Server
314: */
315: public function Server() {
316: return Installer\Server::InterfaceInstance();
317: }
318:
319: /**
320: * @return Installer\Client
321: */
322: public function Client() {
323: return Installer\Client::InterfaceInstance();
324: }
325: }
326: