Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 957 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

<?php
declare(strict_types=1);

namespace LeadersLinked;

use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Cache\Storage\Adapter\AbstractAdapter as CacheAdapter;
use Laminas\ModuleManager\ModuleEvent;
use Laminas\ModuleManager\ModuleManager;
use Laminas\Mvc\MvcEvent;
use Laminas\Config\Reader\Ini;
use Laminas\Permissions\Acl\Acl;
use LeadersLinked\Plugin\CurrentUserPlugin;
use LeadersLinked\Model\Company;
use LeadersLinked\Mapper\UserMapper;
use Laminas\Permissions\Acl\Resource\GenericResource;
use Laminas\Permissions\Acl\Role\GenericRole;
use LeadersLinked\Mapper\CompanyUserMapper;
use LeadersLinked\Mapper\CompanyUserRoleMapper;
use LeadersLinked\Mapper\RoleMapper;
use LeadersLinked\Mapper\CompanyServiceMapper;
use LeadersLinked\Model\Service;

class Module 
{
    /**
     * 
     * @var boolean
     */
    private $isJson;

    /**
     *
     * @var boolean
     */
    private $isHtml;
    
    /**
     * 
     * @var Acl
     */
    private $acl;
    
    /**
     * 
     * @var Company
     */
    private $company;
    
    /**
     * 
     * @var AdapterInterface
     */
    private $adapter;
    
    
    /**
     * 
     * @var CacheAdapter
     */
    private $cache;
    
    /**
     * 
     * @var CurrentUserPlugin
     */
    private $currentUser;
    
    
    /**
     * 
     * @var array
     */
    private $routesAuthorized = [];
    
    /**
     * 
     * @var boolean
     */
    private $authByHeaders = false;
    
    public function init(ModuleManager $moduleManager)
    {
        $events = $moduleManager->getEventManager();
        $events->attach(ModuleEvent::EVENT_MERGE_CONFIG, array($this, 'onMergeConfig'));
    }
    
    public function onMergeConfig(ModuleEvent $event)
    {
        $configListener = $event->getConfigListener();
        $config         = $configListener->getMergedConfig(false);
            
        $reader = new Ini();
        $data = $reader->fromFile('config/leaderslinked.ini');
            
        $prefix = 'leaderslinked';
        foreach($data as $section => $pairs)
        {
            foreach($pairs as $key => $value)
            {
                $config[$prefix . '.' . $section . '.' . $key] = $value;
            }
        }
        $configListener->setMergedConfig($config);
    }
    
    
    public function getConfig() : array
    {
        return include __DIR__ . '/../config/module.config.php';
    }

    public function onBootstrap(MvcEvent $event)
    {
        $serviceManager = $event->getApplication()->getServiceManager();
        $adapter = $serviceManager->get('leaders-linked-db');
       // $logger          = $serviceManager->get('Zend\Log\Logger');
        
      
        $session = $serviceManager->get('leaders-linked-session');
        $session->start();


        $translator = $serviceManager->get('MvcTranslator');
        $translator->addTranslationFile(
            'phpArray',
            __DIR__ . '/i18n/validate.php',
            'default'
            );
        
        $translator->addTranslationFile(
            'phpArray',
            __DIR__ . '/i18n/spanish.php',
            'default'
            );
        
        \Laminas\Validator\AbstractValidator::setDefaultTranslator($translator);
        

        $this->isHtml = $this->isJson ? false : true;
        $this->currentUser = new CurrentUserPlugin($adapter);
        $this->initAcl($event);
        $eventManager = $event->getApplication()->getEventManager();
        $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this,'onDispatchError'], 0);
        $eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, [$this,'onRenderError'], 0);
        
        $sharedManager = $eventManager->getSharedManager();
        $sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPreDispatch'], 100);
        $sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPosDispatch'], -100);
    }
    
    public function initAcl(MvcEvent $event)
    {
        $serviceManager = $event->getApplication()->getServiceManager();
        $adapter = $serviceManager->get('leaders-linked-db');
        
        require_once   (dirname(__DIR__) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'acl.config.php');
        
        
        $this->acl = new Acl();
        $resources = getAclResources();
        foreach($resources as $resourceName)
        {
           // echo $resourceName . PHP_EOL;
            
            $this->acl->addResource(new GenericResource($resourceName));
        }
        

        
        
        $company = $this->currentUser->getCompany(); 
        if($company) { 
            $companyServiceMapper = CompanyServiceMapper::getInstance($adapter);
            $companyServiceMicrolearning = $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company->id, Service::MICRO_LEARNING);
            
            $companyServiceAutoEvaluation = $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company->id, Service::SELF_EVALUATION);
            $roles = getAclRolesCompany(); 
            
          
            $user = $this->currentUser->getUser(); 
            
            $this->acl->addRole(new GenericRole($user->usertype_id));
            
            $companyUserMapper = CompanyUserMapper::getInstance($adapter);
            $companyUser = $companyUserMapper->fetchOneByCompanyIdAndUserId($company->id, $user->id);
            
            if($companyUser && $companyUser->creator) {
                if(isset($roles['creator'])) {
                
                    foreach($roles['creator'] as $resourceName)
                    {
                        $this->acl->allow($user->usertype_id, $resourceName);
                    }
                    
                
                    if($companyServiceMicrolearning) {
                        foreach($roles['creator-microlearning'] as $resourceName)
                        {
                            $this->acl->allow($user->usertype_id, $resourceName);
                        }
                    }
                    
                    if($companyServiceAutoEvaluation) {
                        foreach($roles['creator-self-evaluation'] as $resourceName)
                        {
                            $this->acl->allow($user->usertype_id, $resourceName);
                        }
                    }
                    
                }
                
            } else {
                
                $companyUserRoleMapper = CompanyUserRoleMapper::getInstance($this->adapter);
                $companyUserRoles = $companyUserRoleMapper->fetchAllByCompanyIdAndUserId($company->id, $user->id);
                
                $roleMapper = RoleMapper::getInstance($this->adapter); 
                
                
                foreach($companyUserRoles as $companyUserRole)
                {
                    $role = $roleMapper->fetchOne($companyUserRole->role_id);
                    if($role) { 
                        if($role->service_id == Service::SELF_EVALUATION && !$companyServiceAutoEvaluation) {
                            continue;
                        }
                        
                        if($role->service_id == Service::MICRO_LEARNING && !$companyServiceMicrolearning) {
                            continue;
                        }
                        
                        if(isset($roles[ $role->code ] )) { 
                        
                    
                            foreach($roles[ $role->code ] as $resourceName)
                            {
                                $this->acl->allow($user->usertype_id, $resourceName);
                            }
                        } 
                    }
                }
                
            }
            
            
            
            
        }  else { 
            $usertypes = getAclUsertype();
            foreach($usertypes as $usertype => $resources)
            {
                $this->acl->addRole(new GenericRole($usertype));
                foreach ($resources as $resourceName)
                {
                    $this->acl->allow($usertype, $resourceName);
                }
            }
        
        }
        

        $event->getViewModel()->setVariable('acl', $this->acl);
    }
    
    public function onDispatchError(MvcEvent $event)
    {
        $this->processError($event);
    }
    
    public function onRenderError(MvcEvent $event)
    {
        $this->processError($event);
    }
    
    public function sendResponse(\Laminas\Http\Response $response, $data)
    {
        
       
        if($this->isJson) {
            $headers = $response->getHeaders();
            $headers->clearHeaders();
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
            
            $response->setStatusCode(200);
            $response->setContent(json_encode($data));
            $response->send();
            
            
        } else {
            throw new \Exception($data['data']);
        }
        exit;
    }
    
    public function processError(MvcEvent $event)
    {

        
        $request =  $event->getRequest();
        if((method_exists($request, 'isXmlHttpRequest') && $request->isXmlHttpRequest()) || ($this->isJson && !$this->isHtml)) {
            
            $error = $event->getError();
            if (!$error) {
                return;
            }
            
            $response = $event->getResponse();
            
            if('error-exception' == $error) {
                $exception = $event->getParam('exception');
                error_log($exception->getCode() . ' ' . $exception->getMessage());
                //error_log($exception->getTraceAsString());
                

                $data = [
                    'success' => false,
                    'data' => 'An error occurred during execution; please try again later.'
                ];
                
            } else if('error-router-no-match' == $error) {
                $data = [
                    'success' => false,
                    'data' => 'Resource not found.'
                    
                ];
            } else if(' error-controller-not-found' == $error) {
                $data = [
                    'success' => false,
                    'data' => 'Controller not found.'
                    
                ];
            } else {
                $data = [
                    'success' => false,
                    'data' => 'Unknow error.' , 'error' => $error
                    
                ];
            }
            
 
            
            $this->sendResponse($response, $data);
        }
        
        $this->initAcl($event);
    }

    
    public function authPreDispatch(MvcEvent $event)
    {
        $serviceManager = $event->getApplication()->getServiceManager();
        $adapter = $serviceManager->get('leaders-linked-db');
        
        $userTypeId = $this->currentUser->getUserTypeId();
        

        

        $routeName = $event->getRouteMatch()->getMatchedRouteName();
        
        

        if($this->acl->isAllowed($userTypeId, $routeName)) {
            $user = $this->currentUser->getUser();
            
            
            
            /*if($user && !in_array($routeName, ['check-session', 'dashboard'])) {
                
               
            }*/
            
            if($user) {
                $userMapper = UserMapper::getInstance($adapter);
                $userMapper->updateLastActivity($user->id);
            }
            
        } else {
            
      
            /*
            if($this->authByHeaders) {
                $response = $event->getResponse();
                $headers = $response->getHeaders();
                $headers->clearHeaders();
                $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
                
                $response->setStatusCode(401);
                $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
                $response->send();
                exit;
                
            }*/
            
            
            //print_r($this->routesAuthorized);
           // echo 'sin permiso'; exit;
            
           
            $this->currentUser->clearIdentity(); 
            

            if($this->isJson) {
                $response = $event->getResponse();
                $headers = $response->getHeaders();
                $headers->clearHeaders();
                $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
                
                $response->setStatusCode(200);
                $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
                $response->send();
            } else {
                $url = $event->getRouter()->assemble([], ['name' => 'signout']);
                
                $response = $event->getResponse();
                $headers = $response->getHeaders();
                $headers->clearHeaders();
                $headers->addHeaderLine('Location', $url);
                
                $response->setStatusCode(302);
                $response->send();
            }
            exit;
        }

        
    }
   

    public function authPosDispatch(MvcEvent $event)
    {
        
    }

    
}