freenet-router |
Subversion Repositories: |
Compare with Previous - Blame - Download
<?php
namespace Phem\Controllers;
use Doctrine\Common\Annotations\AnnotationReader;
use Phem\Core\Collection;
use Phem\Environment\Application;
use Phem\Environment\EnvironmentManager;
use Phem\Environment\ResourceType;
use Phem\Libraries\Security\Model\MySQL\User;
use Phem\Libraries\UI\Annotations\ContentAttr;
use Phem\Libraries\UI\Annotations\DomAttr;
use Phem\Libraries\UI\Annotations\DomPath;
use Phem\Libraries\UI\Annotations\StyleAttr;
use Phem\Libraries\UI\Model\EventResult;
use Phem\Libraries\UI\Model\ScopeType;
use Phem\Libraries\UI\Model\Workspace;
use Phem\Views\SimpleView;
use ReflectionClass;
use ReflectionProperty;
use stdClass;
abstract class WorkspaceViewController extends Controller
{
protected $renderTemplate = true;
private $workspace;
private $connectionId;
public function getWorkspace()
{
return $this->workspace;
}
public function setWorkspace($workspace)
{
$this->workspace = $workspace;
}
public function execute($task)
{
parent::execute($task);
$this->connectionId = (int) EnvironmentManager::getRequestVar("connectionId", 0);
$template = "@Phem/UI/Workspace.twig";
$classPathArray = explode('\\', get_class($this));
$classShortName = end($classPathArray);
$controllerName = str_replace("Controller", "", $classShortName);
$model = new Collection();
$model->put("styles", EnvironmentManager::getResourceManager()
->getResourcePathCollection(ResourceType::CSS));
$model->put("scripts", EnvironmentManager::getResourceManager()
->getResourcePathCollection(ResourceType::JS));
$model->put("controller",$controllerName);
$model->put("task",$task);
$model->put("requestUrl", $_SERVER["REQUEST_URI"]);
$model->put("httpHost", $_SERVER["HTTP_HOST"]);
$model->put("workspace", $this->workspace);
if ($this->loggedUser == "guest")
{
$user = new User();
$user->setUsername($this->loggedUser);
$model->put("loggedUser", $user);
}
else if ($this->loggedUser != null)
{
$user = EnvironmentManager::getUserManager()->getUser($this->loggedUser);
$model->put("loggedUser", $user);
}
$model->put("sessionId", EnvironmentManager::getSession()->getId());
$lb = EnvironmentManager::getLinkBuilder();
$onEventLink = $lb->navigate($controllerName, "onEvent");
$onStrongEventLink = $lb->navigate($controllerName, "onStrongEvent");
$model->put("onEventLink", $onEventLink);
$model->put("onStrongEventLink", $onStrongEventLink);
if ($this->renderTemplate)
{
$view = new SimpleView($template, $model);
$view->display();
}
}
private function findInnerElement($elem, $name)
{
if (isset($elem->id) && $elem->id == $name)
{
return $elem;
}
else if (isset($elem->_children))
{
foreach ($elem->_children as $key => $child)
{
return $this->findInnerElement($elem->_children[$key], $name);
}
}
}
public function onStrongEvent($name,$value,$event,$invokedBy)
{
$this->renderTemplate = false;
//wkspc = EnvironmentManager::getSession()->getVar("phem.workspace");
$wkspc = $this->loadWorkspace("myWkspc", "\PhemDemo\Models\UI\MainWorkspace", $invokedBy);
if (!($wkspc instanceof Workspace))
{
//TODO: if wkspc is null
return;
}
$wkspc->changes = new Collection();
$control = $wkspc->findControl($name);
$src = json_decode(html_entity_decode($value));
$reflectionClass = new ReflectionClass($control);
$props = $reflectionClass->getProperties();
foreach ($props as $prop)
{
$reflectionProperty = new ReflectionProperty(get_class($control),$prop->getName());
$annotationReader = new AnnotationReader();
$propAnnotations = $annotationReader
->getPropertyAnnotations($reflectionProperty);
if (count($propAnnotations)<1) continue;
$path = "";
$srcElem = $src;
foreach ($propAnnotations as $annotation)
{
if ($annotation instanceof DomPath)
{
$path.=$annotation->path;
}
}
if ($path != "")
{
$srcElem = $this->findInnerElement($src, $name. "_".$path);
}
foreach ($propAnnotations as $annotation)
{
if ($annotation instanceof DomAttr)
{
$setterName = "set" . ucfirst($prop->getName());
$propName = $annotation->name;
$control->$setterName($srcElem->$propName);
}
else if ($annotation instanceof ContentAttr)
{
$setterName = "set" . ucfirst($prop->getName());
$control->$setterName($srcElem->_content);
}
else if ($annotation instanceof StyleAttr)
{
$styles = new Collection();
$stylePairs = str_getcsv($srcElem->style,";");
foreach ($stylePairs as $pair)
{
if ($pair != "")
{
$pairArr = explode(":", $pair);
$styles->put(trim($pairArr[0]), ($pairArr[1]));
}
}
$setterName = "set" . ucfirst($prop->getName());
$control->$setterName($styles->get($annotation->name));
}
}
}
$callbackCollection = ucfirst($event);
foreach ($control->$callbackCollection() as $callback)
{
call_user_func($callback,$control);
}
$wkspc->setCurrentVersion($wkspc->getCurrentVersion()+1);
//EnvironmentManager::getSession()
// ->setVar("pehm.workspace", $wkspc);
$this->persistWorkspace($wkspc);
$result = new EventResult($wkspc->getChanges(),
$wkspc->getCurrentVersion());
$result->setInvokedBy($invokedBy);
//echo json_encode($result);
Application::notifyRaw($result);
}
public function onEvent($name,$value,$event,$invokedBy)
{
$this->renderTemplate = false;
//$wkspc = EnvironmentManager::getSession()->getVar("phem.workspace");
$wkspc = $this->loadWorkspace("myWkspc", "\PhemDemo\Models\UI\MainWorkspace", $invokedBy);
if (!($wkspc instanceof Workspace))
{
//TODO: if wkspc is null
return;
}
$wkspc->changes = new Collection();
$control = $wkspc->findControl($name);
$control->setValue($value);
$callbackCollection = ucfirst($event);
foreach ($control->$callbackCollection() as $callback)
{
call_user_func($callback,$control);
}
$wkspc->setCurrentVersion($wkspc->getCurrentVersion()+1);
//EnvironmentManager::getSession()
// ->setVar("pehm.workspace", $wkspc);
$this->persistWorkspace($wkspc);
$result = new EventResult($wkspc->getChanges(),
$wkspc->getCurrentVersion());
$result->setInvokedBy($invokedBy);
//echo json_encode($result);
Application::notifyRaw($result);
}
protected function loadWorkspace($name, $className, $connectionId = null)
{
$applicationWorkspaces = Application::getVar("workspaces");
if ($applicationWorkspaces != null)
{
foreach ($applicationWorkspaces as $wkspc)
{
/* @var $wkspc Workspace */
if (($wkspc->getName() == $name)&&("\\".get_class($wkspc) == $className))
{
return $wkspc;
}
}
}
$users = Application::getVar("users");
$thisUser = null;
if ($users != null)
{
foreach ($users as $userName => $user)
{
if ($userName == $this->loggedUser)
{
$thisUser = $user;
}
}
}
if ($thisUser != null)
{
if ($user->workspaces != null)
{
foreach ($user->workspaces as $wkspc)
{
/* @var $wkspc Workspace */
if (($wkspc->getName() == $name)&&("\\".get_class($wkspc) == $className))
{
return $wkspc;
}
}
}
}
$sessionWorkspaces = EnvironmentManager::getSession()->getVar("workspaces");
if ($sessionWorkspaces != null)
{
foreach ($sessionWorkspaces as $wkspc)
{
/* @var $wkspc Workspace */
if (($wkspc->getName() == $name)&&("\\".get_class($wkspc) == $className))
{
return $wkspc;
}
}
}
$thisConnection = null;
if ($connectionId != null)
{
$connections = EnvironmentManager::getSession()->getVar("connections");
if ($connections != null)
{
foreach ($connections as $id => $connection)
{
if ($id == $connectionId)
{
$thisConnection = $connection;
}
}
}
}
if ($thisConnection != null)
{
foreach ($thisConnection->workspaces as $wkspc)
{
/* @var $wkspc Workspace */
if (($wkspc->getName() == $name)&&("\\".get_class($wkspc) == $className))
{
return $wkspc;
}
}
}
$wkspc = new $className();
$wkspc->setName($name);
$this->persistWorkspace($wkspc);
return $wkspc;
}
private function persistWorkspace(Workspace $wkspc)
{
switch ($wkspc->getScope())
{
case ScopeType::APPLICATION:
$lock = Application::lockVarsWait();
$workspaces = Application::getVar("workspaces");
if ($workspaces == null) { $workspaces = new Collection(); }
$workspaces->set($wkspc->getName(),$wkspc);
Application::setVar("workspaces",$workspaces);
$lock->unlock();
break;
case ScopeType::USER:
$lock = Application::lockVarsWait();
$users = Application::getVar("users");
if ($users == null)
{
$users = new Collection();
}
$foundUser = null;
foreach ($users as $userName => $user)
{
if ($userName == $this->loggedUser)
{
$foundUser = $user;
}
}
if ($foundUser == null)
{
$foundUser = new stdClass();
$users->set($this->loggedUser,$foundUser);
}
if ($foundUser->workspaces == null)
{
$foundUser->workspaces = new Collection();
}
$foundUser->workspaces->set($wkspc->getName(),$wkspc);
Application::setVar("users",$foundUser);
$lock->unlock();
break;
default:
case ScopeType::SESSION:
$workspaces = EnvironmentManager::getSession()->getVar("workspaces");
if ($workspaces == null)
{
$workspaces = new Collection();
}
$workspaces->set($wkspc->getName(),$wkspc);
EnvironmentManager::getSession()->setVar("workspaces",$workspaces);
break;
case ScopeType::CONNECTION:
$connections = EnvironmentManager::getSession()->getVar("connections");
if ($connections == null)
{
$connections = new Collection();
}
$foundConn = null;
foreach ($connections as $connId => $connection)
{
if ($connId == $this->connectionId)
{
$foundConn = $connection;
}
}
if ($foundConn == null)
{
$foundConn = new stdClass();
$connections->set($this->connectionId,$connection);
}
if ($foundConn->workspaces == null)
{
$foundConn->workspaces = new Collection();
}
$foundConn->workspaces->set($wkspc->getName(),$wkspc);
EnvironmentManager::getSession()->setVar("users",$foundUser);
break;
}
}
}