1818 */ 
1919class  Stopwatch
2020{
21-  private  $ waiting
2221 private  $ sections
23-  private  $ events
24-  private  $ origin
22+  private  $ activeSections
23+ 
24+  public  function  __construct ()
25+  {
26+  $ this sections  = $ this activeSections  = array ('__root__ '  => new  Section ('__root__ ' ));
27+  }
2528
2629 /** 
27-  * Starts a new section. 
30+  * Creates a new section or re-opens an existing section. 
31+  * 
32+  * @param string|null $id The id of the session to re-open, null to create a new one 
33+  * 
34+  * @throws \LogicException When the section to re-open is not reachable 
2835 */ 
29-  public  function  startSection ( )
36+  public  function  openSection ( $ id  =  null )
3037 {
31-  if  ($ this events ) {
32-  $ this start ('__section__.child ' , 'section ' );
33-  $ this waiting [] = array ($ this events , $ this origin );
34-  $ this events  = array ();
35-  }
38+  $ currentend ($ this activeSections );
3639
37-  $ this origin  = microtime (true ) * 1000 ;
40+  if  (null  !== $ id
41+  if  (false  === $ currentget ($ id
42+  throw  new  \LogicException (sprintf ('The section "%s" has been started at an other level and can not be opened. ' , $ id
43+  }
44+  }
3845
46+  $ this start ('__section__.child ' , 'section ' );
47+  $ this activeSections [] = $ currentopen ($ id
3948 $ this start ('__section__ ' );
4049 }
4150
@@ -52,17 +61,12 @@ public function stopSection($id)
5261 {
5362 $ this stop ('__section__ ' );
5463
55-  if  (null  ! == $ id 
56-  $ this -> sections [ $ id ] =  $ this -> events ;
64+  if  (1   == count ( $ this -> activeSections ) ) {
65+  throw   new  \ LogicException ( ' There is no started section to stop. ' ) ;
5766 }
5867
59-  if  ($ this waiting ) {
60-  list ($ this events , $ this origin ) = array_pop ($ this waiting );
61-  $ this stop ('__section__.child ' );
62-  } else  {
63-  $ this origin  = null ;
64-  $ this events  = array ();
65-  }
68+  $ this sections [$ idarray_pop ($ this activeSections )->setId ($ id
69+  $ this stop ('__section__.child ' );
6670 }
6771
6872 /** 
@@ -74,6 +78,129 @@ public function stopSection($id)
7478 * @return StopwatchEvent A StopwatchEvent instance 
7579 */ 
7680 public  function  start ($ name$ categorynull )
81+  {
82+  return  end ($ this activeSections )->startEvent ($ name$ category
83+  }
84+ 
85+  /** 
86+  * Stops an event. 
87+  * 
88+  * @param string $name The event name 
89+  * 
90+  * @return StopwatchEvent A StopwatchEvent instance 
91+  */ 
92+  public  function  stop ($ name
93+  {
94+  return  end ($ this activeSections )->stopEvent ($ name
95+  }
96+ 
97+  /** 
98+  * Stops then restarts an event. 
99+  * 
100+  * @param string $name The event name 
101+  * 
102+  * @return Symfony\Component\HttpKernel\Debug\StopwatchEvent A StopwatchEvent instance 
103+  */ 
104+  public  function  lap ($ name
105+  {
106+  return  end ($ this activeSections )->stopEvent ($ namestart ();
107+  }
108+ 
109+  /** 
110+  * Gets all events for a given section. 
111+  * 
112+  * @param string $id A section identifier 
113+  * 
114+  * @return Symfony\Component\HttpKernel\Debug\StopwatchEvent[] An array of StopwatchEvent instances 
115+  */ 
116+  public  function  getSectionEvents ($ id
117+  {
118+  return  isset ($ this sections [$ id$ this sections [$ idgetEvents () : array ();
119+  }
120+ }
121+ 
122+ class  Section
123+ {
124+  private  $ eventsarray ();
125+  private  $ origin
126+  private  $ id
127+  private  $ childrenarray ();
128+ 
129+  /** 
130+  * Constructor. 
131+  * 
132+  * @param float|null $origin Set the origin of the events in this section, use null to set their origin to their start time 
133+  */ 
134+  public  function  __construct ($ originnull )
135+  {
136+  $ this origin  = is_numeric ($ origin$ originnull ;
137+  }
138+ 
139+  /** 
140+  * Returns the child section. 
141+  * 
142+  * @param string $id The child section identifier 
143+  * 
144+  * @return Section|false The child section or false when none found 
145+  */ 
146+  public  function  get ($ id
147+  {
148+  foreach  ($ this children  as  $ child
149+  if  ($ id$ childgetId ()) {
150+  return  $ child
151+  }
152+  }
153+ 
154+  return  false ;
155+  }
156+ 
157+  /** 
158+  * Creates or re-opens a child section. 
159+  * 
160+  * @param string|null $id null to create a new section, the identifier to re-open an existing one. 
161+  * 
162+  * @return Section A child section 
163+  */ 
164+  public  function  open ($ id
165+  {
166+  if  (false  === $ session$ this get ($ id
167+  $ session$ this children [] = new  self (microtime (true ) * 1000 );
168+  }
169+ 
170+  return  $ session
171+  }
172+ 
173+  /** 
174+  * @return string The identifier of the section 
175+  */ 
176+  public  function  getId ()
177+  {
178+  return  $ this id ;
179+  }
180+ 
181+  /** 
182+  * Sets the session identifier. 
183+  * 
184+  * @param string $id The session identifier 
185+  * 
186+  * @return Section The current section 
187+  */ 
188+  public  function  setId ($ id
189+  {
190+  $ this id  = $ id
191+ 
192+  return  $ this 
193+  }
194+ 
195+  /** 
196+  * Starts an event. 
197+  * 
198+  * @param string $name The event name 
199+  * @param string $category The event category 
200+  * 
201+  * @return Symfony\Component\HttpKernel\Debug\StopwatchEvent The event 
202+  */ 
203+  public  function  startEvent ($ name$ category
77204 {
78205 if  (!isset ($ this events [$ name
79206 $ this events [$ namenew  StopwatchEvent ($ this origin  ?: microtime (true ) * 1000 , $ category
@@ -87,9 +214,11 @@ public function start($name, $category = null)
87214 * 
88215 * @param string $name The event name 
89216 * 
90-  * @return StopwatchEvent A StopwatchEvent instance 
217+  * @return Symfony\Component\HttpKernel\Debug\StopwatchEvent The event 
218+  * 
219+  * @throws \LogicException When the event has not been started 
91220 */ 
92-  public  function  stop ($ name
221+  public  function  stopEvent ($ name
93222 {
94223 if  (!isset ($ this events [$ name
95224 throw  new  \LogicException (sprintf ('Event "%s" is not started. ' , $ name
@@ -99,26 +228,26 @@ public function stop($name)
99228 }
100229
101230 /** 
102-  * Stops then restart  an event. 
231+  * Stops then restarts  an event. 
103232 * 
104233 * @param string $name The event name 
105234 * 
106-  * @return StopwatchEvent A StopwatchEvent instance 
235+  * @return Symfony\Component\HttpKernel\Debug\StopwatchEvent The event 
236+  * 
237+  * @throws \LogicException When the event has not been started 
107238 */ 
108239 public  function  lap ($ name
109240 {
110241 return  $ this stop ($ namestart ();
111242 }
112243
113244 /** 
114-  * Gets all events for a given section. 
115-  * 
116-  * @param string $id A section identifier 
245+  * Returns the events from this section. 
117246 * 
118-  * @return StopwatchEvent[] An array of StopwatchEvent instances 
247+  * @return Symfony\Component\HttpKernel\Debug\ StopwatchEvent[] An array of StopwatchEvent instances 
119248 */ 
120-  public  function  getSectionEvents ( $ id 
249+  public  function  getEvents ( )
121250 {
122-  return  isset ( $ this sections [ $ id ]) ?  $ this -> sections [ $ id ] :  array () ;
251+  return  $ this events ;
123252 }
124- }
253+ }
0 commit comments