/** * @param AdminInterface $admin * * @return mixed * @throws \RuntimeException */ public function load(AdminInterface $admin) { $filename = $this->cacheFolder . '/route_' . md5($admin->getCode()); $cache = new ConfigCache($filename, $this->debug); if (!$cache->isFresh()) { $resources = array(); $routes = array(); $reflection = new \ReflectionObject($admin); $resources[] = new FileResource($reflection->getFileName()); if (!$admin->getRoutes()) { throw new \RuntimeException('Invalid data type, Admin::getRoutes must return a RouteCollection'); } foreach ($admin->getRoutes()->getElements() as $code => $route) { $routes[$code] = $route->getDefault('_sonata_name'); } if (!is_array($admin->getExtensions())) { throw new \RuntimeException('extensions must be an array'); } foreach ($admin->getExtensions() as $extension) { $reflection = new \ReflectionObject($extension); $resources[] = new FileResource($reflection->getFileName()); } $cache->write(serialize($routes), $resources); } return unserialize(file_get_contents($filename)); }
/** * Configure the object ACL for the passed object identities * * @param OutputInterface $output * @param AdminInterface $admin * @param array $oids an array of ObjectIdentityInterface implementations * @param UserSecurityIdentity $securityIdentity * * @throws \Exception * * @return array [countAdded, countUpdated] */ public function configureAcls(OutputInterface $output, AdminInterface $admin, array $oids, UserSecurityIdentity $securityIdentity = null) { $countAdded = 0; $countUpdated = 0; $securityHandler = $admin->getSecurityHandler(); if (!$securityHandler instanceof AclSecurityHandlerInterface) { $output->writeln(sprintf('Admin `%s` is not configured to use ACL : <info>ignoring</info>', $admin->getCode())); return array(0, 0); } $acls = $securityHandler->findObjectAcls($oids); foreach ($oids as $oid) { if ($acls->contains($oid)) { $acl = $acls->offsetGet($oid); $countUpdated++; } else { $acl = $securityHandler->createAcl($oid); $countAdded++; } if (!is_null($securityIdentity)) { // add object owner $securityHandler->addObjectOwner($acl, $securityIdentity); } $securityHandler->addObjectClassAces($acl, $securityHandler->buildSecurityInformation($admin)); try { $securityHandler->updateAcl($acl); } catch (\Exception $e) { $output->writeln(sprintf('Error saving ObjectIdentity (%s, %s) ACL : %s <info>ignoring</info>', $oid->getIdentifier(), $oid->getType(), $e->getMessage())); } } return array($countAdded, $countUpdated); }
/** * {@inheritDoc} */ public function buildSecurityInformation(AdminInterface $admin) { $baseRole = 'ROLE_' . str_replace('.', '_', strtoupper($admin->getCode())) . '_%s'; $results = array(); foreach ($admin->getSecurityInformation() as $name => $permissions) { $results[sprintf($baseRole, $name)] = $permissions; } return $results; }
/** * @throws \RuntimeException * @param \Sonata\AdminBundle\Admin\AdminInterface $admin * @param $name * @param array $parameter * @param bool $absolute * @return string */ public function generateUrl(AdminInterface $admin, $name, array $parameters = array(), $absolute = false) { if (!$admin->isChild()) { if (strpos($name, '.')) { $name = $admin->getCode() . '|' . $name; } else { $name = $admin->getCode() . '.' . $name; } } else { if ($admin->isChild()) { $name = $admin->getBaseCodeRoute() . '.' . $name; // twig template does not accept variable hash key ... so cannot use admin.idparameter ... // switch value if (isset($parameters['id'])) { $parameters[$admin->getIdParameter()] = $parameters['id']; unset($parameters['id']); } $parameters[$admin->getParent()->getIdParameter()] = $admin->getRequest()->get($admin->getParent()->getIdParameter()); } } // if the admin is linked to a parent FieldDescription (ie, embedded widget) if ($admin->hasParentFieldDescription()) { // merge link parameter if any provided by the parent field $parameters = array_merge($parameters, $admin->getParentFieldDescription()->getOption('link_parameters', array())); $parameters['uniqid'] = $admin->getUniqid(); $parameters['code'] = $admin->getCode(); $parameters['pcode'] = $admin->getParentFieldDescription()->getAdmin()->getCode(); $parameters['puniqid'] = $admin->getParentFieldDescription()->getAdmin()->getUniqid(); } if ($name == 'update' || substr($name, -7) == '|update') { $parameters['uniqid'] = $admin->getUniqid(); $parameters['code'] = $admin->getCode(); } // allows to define persistent parameters if ($admin->hasRequest()) { $parameters = array_merge($admin->getPersistentParameters(), $parameters); } $route = $admin->getRoute($name); if (!$route) { throw new \RuntimeException(sprintf('unable to find the route `%s`', $name)); } return $this->router->generate($route->getDefault('_sonata_name'), $parameters, $absolute); }
/** * {@inheritdoc} */ public function batchConfigureAcls(OutputInterface $output, AdminInterface $admin, UserSecurityIdentity $securityIdentity = null) { $securityHandler = $admin->getSecurityHandler(); if (!$securityHandler instanceof AclSecurityHandlerInterface) { $output->writeln('Admin class is not configured to use ACL : <info>ignoring</info>'); return; } $output->writeln(sprintf(' > generate ACLs for %s', $admin->getCode())); $objectOwnersMsg = is_null($securityIdentity) ? '' : ' and set the object owner'; /** @var DocumentManager $om */ $om = $admin->getModelManager()->getDocumentManager(); $qb = $om->createQueryBuilder($admin->getClass()); $count = 0; $countUpdated = 0; $countAdded = 0; try { $batchSize = 20; $batchSizeOutput = 200; $objectIds = array(); foreach ($qb->getQuery()->iterate() as $row) { $objectIds[] = ObjectIdentity::fromDomainObject($row); $objectIdIterator = new \ArrayIterator($objectIds); // detach from Doctrine, so that it can be Garbage-Collected immediately $om->detach($row); ++$count; if ($count % $batchSize == 0) { list($batchAdded, $batchUpdated) = $this->configureAcls($output, $admin, $objectIdIterator, $securityIdentity); $countAdded += $batchAdded; $countUpdated += $batchUpdated; $objectIds = array(); } if ($count % $batchSizeOutput == 0) { $output->writeln(sprintf(' - generated class ACEs%s for %s objects (added %s, updated %s)', $objectOwnersMsg, $count, $countAdded, $countUpdated)); } } if (count($objectIds) > 0) { list($batchAdded, $batchUpdated) = $this->configureAcls($output, $admin, $objectIdIterator, $securityIdentity); $countAdded += $batchAdded; $countUpdated += $batchUpdated; } } catch (\BadMethodCallException $e) { throw new ModelManagerException('', 0, $e); } $output->writeln(sprintf(' - [TOTAL] generated class ACEs%s for %s objects (added %s, updated %s)', $objectOwnersMsg, $count, $countAdded, $countUpdated)); }
/** * {@inheritDoc} */ public function configureAcls(OutputInterface $output, AdminInterface $admin) { $securityHandler = $admin->getSecurityHandler(); if (!$securityHandler instanceof AclSecurityHandlerInterface) { $output->writeln(sprintf('Admin `%s` is not configured to use ACL : <info>ignoring</info>', $admin->getCode())); return; } $objectIdentity = ObjectIdentity::fromDomainObject($admin); $newAcl = false; if (is_null($acl = $securityHandler->getObjectAcl($objectIdentity))) { $acl = $securityHandler->createAcl($objectIdentity); $newAcl = true; } // create admin ACL $output->writeln(sprintf(' > install ACL for %s', $admin->getCode())); $configResult = $this->addAdminClassAces($output, $acl, $securityHandler, $securityHandler->buildSecurityInformation($admin)); if ($configResult) { $securityHandler->updateAcl($acl); } else { $output->writeln(sprintf(' - %s , no roles and permissions found', $newAcl ? 'skip' : 'removed')); $securityHandler->deleteAcl($objectIdentity); } }
/** * {@inheritdoc} */ public function addChild(AdminInterface $child) { $this->children[$child->getCode()] = $child; $child->setBaseCodeRoute($this->getCode() . '|' . $child->getCode()); $child->setParent($this); }
/** * {@inheritdoc} */ public function getBaseRole(AdminInterface $admin) { return 'ROLE_' . str_replace('.', '_', strtoupper($admin->getCode())) . '_%s'; }
public function getActionsByAdmin(AdminInterface $admin) { return $this->getActionsByAdminId($admin->getCode()); }
/** * @param AdminInterface $admin */ private function loadCache(AdminInterface $admin) { if ($admin->isChild()) { $this->loadCache($admin->getParent()); } else { if (in_array($admin->getCode(), $this->loaded)) { return; } $this->caches = array_merge($this->cache->load($admin), $this->caches); $this->loaded[] = $admin->getCode(); } }
/** * {@inheritdoc} */ public function getBaseRole(AdminInterface $admin) { $code = $this->siteManager->getCurrentSite()->getSlug(); return 'ROLE_' . str_replace('.', '_', $code . '.' . strtoupper($admin->getCode())) . '_%s'; }
/** * @param \Sonata\AdminBundle\Admin\AdminInterface $admin * @param string $adminCode * @return bool */ public function isAdminActive(AdminInterface $admin, $adminCode = '') { $active = false; if ($adminCode == $admin->getCode()) { $active = true; } if (method_exists($admin, 'getSubNavLinks')) { foreach ($admin->getSubNavLinks() as $value) { if ($value instanceof AdminInterface) { if ($value->getCode() == $adminCode) { $active = true; } } } } return $active; }
/** * {@inheritdoc} */ public function preRemove(AdminInterface $admin, $object) { $this->create($this->getSubject(), 'sonata.admin.delete', array('target_text' => $admin->toString($object), 'admin_code' => $admin->getCode())); }