Skip to content

Instantly share code, notes, and snippets.

@robzienert
Created August 29, 2011 07:28
Show Gist options
  • Select an option

  • Save robzienert/1177942 to your computer and use it in GitHub Desktop.

Select an option

Save robzienert/1177942 to your computer and use it in GitHub Desktop.
CalendarBundle arch refactor
<?php
// Project: CalendarBundle
// Goal: Speed up development and reduce bugs by abandoning dev. of
// PHP iCalendar RFC implementation. Use vetted scripts like RiDoc (Ruby)
// or dateutil (Python) as a base.
//
// This code illustrates a vertical slice of the class architecture up to
// the service layer.
$processor = \Processor\Factory::create($container->get('CalendarBundle.processor_driver'));
$recurrenceService->setProcessor(function() use ($driver, $cache = false) {
$processor = new ProcessorRepository(new Processor\$driver);
if ($cache) {
$processor = \Zend_Cache::factory('Class', 'Memcached', array(
'class' => $processor
));
}
return $processor;
});
class CalendarService
{
public function getCalendarEvents(Calendar $calendar)
{
$events = new ArrayCollection();
foreach ($calendar->getEvents as $event) {
$event->setRecurrences($this->recurrenceService->getAll($event));
$events->add($event);
}
return $events;
}
}
class RecurrenceService
{
public function getAll(Event $event, $page = 1)
{
$processor = $this->getDateProcessor();
$result = $processor->getAllOccurrences($event, $page);
return $result;
}
}
class ProcessorRepository
{
public function getAllRecurrences(Event $event, $page = 1)
{
$models = new ArrayCollection();
$results = $driver->exec('get-occurrences' array(
'page' => $page));
foreach ($results as $result) {
$models->add(new Recurrence($result));
}
return $models;
}
}
// These example methods might fall under an abstract driver.
final class PythonDriver implements Driver
{
public function exec($command, array $options = array())
{
$options = $this->setOptions($options);
$command = $this->prepare($command);
$process = $this->getNewProcess();
$breakerRetries = 3;
while (true) {
--$breakerRetries;
try {
$result = $process->doCommand($command);
break;
} catch (DriverFaultException $e) {
if (!$breakerRetries) {
// @todo Log failure
throw $e;
}
}
}
return $result;
}
protected function prepare($command)
{
$command = preg_replace('/[\W\-]/', '', $command);
// @todo Convert command name into a method name: $method
// @todo Check for valid command
// build command method?
// Should this be transferred to an array or something?
$command = $this->$method();
return $command;
}
protected function getNewProcess()
{
$process = new Driver\Process();
array_push($this->openProcesses, $process);
return $process;
}
public function __destruct()
{
foreach ($this->openProcesses as $process) {
$process->close();
}
}
}
interface Driver
{
public function exec($command, array $options = array());
}
// Similar: {@link http://docs.php.net/manual/en/function.exec.php#88704}
// Add support for proc_open(), etc.
class Driver\Process
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment