Merge for release in staging

This commit is contained in:
Michael RICOIS 2013-11-21 16:13:20 +00:00
parent 8ad7e351cc
commit 50ddcde1c3
10 changed files with 458 additions and 217 deletions

View File

@ -78,7 +78,7 @@ class DocumentationController extends Zend_Controller_Action
}
// Affichage de la documentation
$doc = new Scores_WebClassDoc(ucfirst($ws), $classmap, $pathClassService);
$doc = new Scores_Ws_Doc(ucfirst($ws), $classmap, $pathClassService);
$tabServiceMethods = $doc->getServiceMethods();
// Tri des méthodes par ordre alphabétique
$tabServiceMethodsK = array();
@ -169,7 +169,7 @@ class DocumentationController extends Zend_Controller_Action
$wsdl_url.= '/'.$ws.'/v'.$version.'?wsdl-auto';
}
// Affichage de la documentation
$doc = new Scores_WebClassDoc(ucfirst($ws), $classmap, $pathClassService);
$doc = new Scores_Ws_Doc(ucfirst($ws), $classmap, $pathClassService);
$tabServiceMethods = $doc->getServiceMethods();
// Tri des méthodes par ordre alphabétique
$tabServiceMethodsK = array();

View File

@ -29,7 +29,7 @@ class UserController extends Zend_Controller_Action {
$login = $form->getValue('login');
$pass = $form->getValue('pass');
$auth = Zend_Auth::getInstance();
$authAdapter = new Scores_AuthAdapter($login, $pass);
$authAdapter = new Scores_Auth_Adapter_Db($login, $pass, true);
$result = $auth->authenticate($authAdapter);
if (!$result->isValid()){
$this->view->message = '';

View File

@ -40,13 +40,13 @@ class Application_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract
if (!empty($hach)) {
$pass = $hach;
}
$auth = Zend_Auth::getInstance();
//On vérifie le tout lors d'une connexion par url
if ( !empty($login) && !empty($pass) ) {
$authAdapter = new Scores_AuthAdapter($login, $pass, $checkWs);
$authAdapter = new Scores_Auth_Adapter_Db($login, $pass, $checkWs);
$result = $auth->authenticate($authAdapter);
if (!$result->isValid()) {
$layout = Zend_Layout::getMVCInstance();

View File

@ -1,13 +1,25 @@
<?php
class Scores_AuthAdapter implements Zend_Auth_Adapter_Interface
class Scores_Auth_Adapter_Db implements Zend_Auth_Adapter_Interface
{
protected $_username;
protected $_password;
protected $_hash;
protected $_timeout = 1800;
protected $checkWs = true;
public function __construct($username, $password, $checkWs = true)
protected $_password;
protected $_hash;
protected $_timeout = 3600;
protected $checkWs = false;
protected $clients = array();
/**
*
* @param string $username
* @param string $password
* @param boolean $checkWs
*/
public function __construct($username, $password, $checkWs = false)
{
$this->_username = $username;
$this->_password = $password;
@ -15,19 +27,50 @@ class Scores_AuthAdapter implements Zend_Auth_Adapter_Interface
$this->checkWs = $checkWs;
}
/**
* Limit access to only client IDs
* @param array $id
*/
public function limitClient($id = null)
{
if (is_array($id) && count($id)>0) {
$this->clients = $id;
}
}
/**
* Override the timeout
* @param integer $seconds
*/
public function setTimeout($seconds = null)
{
if ($seconds===null)
return;
$this->_timeout = $seconds;
}
/**
* (non-PHPdoc)
* @see Zend_Auth_Adapter_Interface::authenticate()
*/
public function authenticate()
{
$userM = new Application_Model_Sdv1Utilisateurs();
$sql = $userM->select()
->setIntegrityCheck(false)
->from(array('u'=>'utilisateurs'), array('u.idClient', 'u.login', 'u.password'))
->from(array('u'=>'utilisateurs'), array('u.idClient', 'u.id', 'u.login', 'u.password'))
->join(array('c'=>'clients'), 'u.idClient = c.id', array('c.timeout'))
->where('u.login=?', $this->_username)
->where('u.actif=?', 1)
->where('u.deleted=?', 0)
->where('c.actif=?','Oui');
if ( count($this->clients) > 0 ) {
$sql->where('u.idClient IN('.join(',',$this->clients).')');
}
if ($this->checkWs) {
$sql->where('u.accesWS=?',1);
}
@ -42,8 +85,9 @@ class Scores_AuthAdapter implements Zend_Auth_Adapter_Interface
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND, $identity);
} else {
if ( $this->_password == $result->password
|| $this->_password == md5($result->login.'|'.$result->password) ) {
|| $this->_password == md5($result->login.'|'.$result->password) ) {
$identity->id = $result->id;
$identity->idClient = $result->idClient;
$timeout = (!empty($result->timeout)) ? $result->timeout : $this->_timeout;
$identity->timeout = $timeout;

View File

@ -0,0 +1,179 @@
<?php
class Scores_Auth_Adapter_Ws implements Zend_Auth_Adapter_Interface
{
/**
*
* @var unknown
*/
protected $_username;
/**
*
* @var unknown
*/
protected $_password;
/**
*
* @var unknown
*/
protected $_timeout = 1800;
/**
*
* @var unknown
*/
protected $_checkIp = false;
public function __construct($username, $password, $iponly = false)
{
$this->_username = $username;
$this->_password = $password;
if ($iponly){
$this->_password = 'iponly:'.$_SERVER['REMOTE_ADDR'];
}
$this->_checkIp = $iponly;
}
/**
* (non-PHPdoc)
* @see Zend_Auth_Adapter_Interface::authenticate()
*/
public function authenticate()
{
$adressIp = $_SERVER['REMOTE_ADDR'];
require_once 'Scores/WsScores.php';
$ws = new WsScores($this->_username, $this->_password);
$InfosLogin = $ws->getInfosLogin($this->_username, $adressIp);
$identity = new stdClass();
$identity->username = $this->_username;
$identity->password = $this->_password;
$identity->email = $InfosLogin->result->email;
$identity->profil = $InfosLogin->result->profil;
$identity->pref = $InfosLogin->result->pref;
$identity->droits = $InfosLogin->result->droits;
$identity->droitsClients = $InfosLogin->result->droitsClients;
$identity->nom = $InfosLogin->result->nom;
$identity->prenom = $InfosLogin->result->prenom;
$identity->tel = $InfosLogin->result->tel;
$identity->fax = $InfosLogin->result->fax;
$identity->mobile = $InfosLogin->result->mobile;
$identity->id = $InfosLogin->result->id;
$identity->idClient = $InfosLogin->result->idClient;
$identity->reference = $InfosLogin->result->reference;
$identity->nbReponses = $InfosLogin->result->nbReponses;
$identity->typeScore = $InfosLogin->result->typeScore;
$identity->dateValidation = $InfosLogin->result->dateValidation;
$identity->nombreConnexions = $InfosLogin->result->nombreConnexions;
$identity->dateDerniereConnexion = $InfosLogin->result->dateDerniereConnexion;
$identity->dateDebutCompte = $InfosLogin->result->dateDebutCompte;
$identity->dateFinCompte = $InfosLogin->result->dateFinCompte;
$identity->acceptationCGU = $InfosLogin->result->acceptationCGU;
$identity->ip = $adressIp;
$identity->modeEdition = false;
$timeout = (!empty($InfosLogin->result->timeout)) ? $InfosLogin->result->timeout : $this->_timeout;
$identity->timeout = $timeout;
$identity->time = time() + $timeout;
$lang = in_array($InfosLogin->result->lang, array('fr','en')) ? $InfosLogin->result->lang : 'fr';
$identity->lang = $lang;
$identity->langtmp = $lang;
/*
* Adresse Ip interdites
*/
$ipInterdites =
'81.252.88.0-81.252.88.7' // CTE D AGGLOMERATION DE SOPHIA
. ';' . '195.200.187.163' // PacWan
. ';' . '213.11.81.41' // Verizon France SAS
. ';' . '83.206.171.252' // FR-BASE-D-INFORMATIONS-LEGALES-BI
. ';' . '81.255.32.139'
. ';' . '212.155.191.1*' // Satair A/S
. ';' . '217.70.1*.17' // OJSC "Sibirtelecom"
. ';' . '212.37.196.156' // GENERALE-MULTIMEDIA-SUD
. ';' . '80.245.60.121' // Planete Marseille - Mailclub
. ';' . '213.246.57.101' // IKOULA
. ';' . '193.104.158.0-193.104.158.255' // Altares.fr
. ';' . '195.6.3.0-195.6.3.255' // ORT
. ';' . '217.144.112.0-217.144.116.63' // Coface
;
if ( $this->checkPlagesIp($ipInterdites, $adressIp) ) {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_UNCATEGORIZED, $identity);
}
// Renvoi
if ( is_string($InfosLogin) || $InfosLogin->error->errnum!=0){
$message = $InfosLogin;
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, $identity, array($message));
} elseif ($this->_username == $InfosLogin->result->login) {
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity);
} else {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_UNCATEGORIZED, $identity);
}
}
/**
* Controle si une adresse IP est dans une liste des IP communiquées sous la forme
* 192.168.3.5-192.68.3.10;192.168.3.*;192.168.3.10
* @param string $strPlageIP
* La plage d'adresses IP
* @param string $adresseIP
* L'adresse IP à tester
* @return boolean
*/
protected function checkPlagesIp($strPlageIP, $adresseIP)
{
$connected = false;
$tabIpAllowed = explode(';', trim($strPlageIP));
if (count($tabIpAllowed)==1 && $tabIpAllowed[0]=='') $tabIpAllowed = array();
foreach ($tabIpAllowed as $ip) {
$tabPlages = explode('-', $ip);
// C'est une plage d'adresse '-'
if (isset($tabPlages[1]))
$connected = $this->in_plage($tabPlages[0],$tabPlages[1],$adresseIP);
else {
// C'est une adresse avec ou sans masque '*'
if (preg_match('/^'.str_replace('*','.*',str_replace('.','\.',$ip)).'$/', $adresseIP) )
$connected=true;
}
if ($connected) break;
}
if (count($tabIpAllowed)==0) return false;
elseif (!$connected) {
return false;
}
return true;
}
/**
* Enter description here ...
* @param unknown_type $plage_1
* @param unknown_type $plage_2
* @param unknown_type $ip
* @return boolean
*/
protected function in_plage($plage_1,$plage_2,$ip)
{
$ip2 = $this->getIpNumber($ip);
if ($ip2>=$this->getIpNumber($plage_1) && $ip2<=$this->getIpNumber($plage_2))
return true;
else
return false;
}
/**
* Converti une IP en nombre
* @param string $ip Adresse IP
* @return integer
*/
protected function getIpNumber($ip)
{
$tab=explode('.', $ip);
return (($tab[0]*256*256*256) + ($tab[1]*256*256) + ($tab[2]*256) + ($tab[3]));
}
}

View File

@ -1,188 +0,0 @@
<?php
class Scores_WebClassDoc
{
private $serviceClass;
private $classmap = array();
private $serviceMethods = array();
private $serviceTypes = array();
public function __construct($serviceClass = null, $classmap = null, $path)
{
$this->serviceClass = $serviceClass;
$this->classmap = $classmap;
require_once $path . $this->serviceClass . '.php';
$this->parseService();
$this->parseTypes();
}
/**
* Retourne la liste des services et leurs paramètres
* @return array
*/
public function getServiceMethods()
{
return $this->serviceMethods;
}
/**
* Retourne la liste des types de données et leurs paramètres
* @return array
*/
public function getServiceTypes()
{
return $this->serviceTypes;
}
private function parseService()
{
$class = new Zend_Server_Reflection();
$methods = $class->reflectClass($this->serviceClass)
->getMethods();
$methodsElement = array();
foreach ($methods as $method) {
$prototype = null;
$maxNumArgumentsOfPrototype = -1;
foreach ($method->getPrototypes() as $tmpPrototype) {
$numParams = count($tmpPrototype->getParameters());
if ($numParams > $maxNumArgumentsOfPrototype) {
$maxNumArgumentsOfPrototype = $numParams;
$prototype = $tmpPrototype;
}
}
$paramsElement = array();
foreach ($prototype->getParameters() as $param) {
$paramElement = array(
'type' => $param->getType(),
'name' => $param->getName(),
'description' => $param->getDescription(),
);
if ($param->isOptional()){
$paramElement['optional'] = $param->isOptional();
$paramElement['defaultValue'] = $param->getDefaultValue();
}
$paramsElement[] = $paramElement;
}
$methodElement = array(
'name' => $method->getName(),
'desc' => $method->getDescription(),
'params' => $paramsElement,
'return' => $prototype->getReturnType(),
);
$methodsElement[] = $methodElement;
}
$this->serviceMethods = $methodsElement;
}
private function parseTypes()
{
$typesElement = array();
if (count($this->classmap)>0)
{
foreach ($this->classmap as $className)
{
$class = new ReflectionClass($className);
$paramsElement = array();
foreach ($class->getProperties() as $property) {
if ($property->isPublic() && preg_match_all('/@var\s+([^\s]+)/m', $property->getDocComment(), $matches)) {
$name = $property->getName();
$type = $matches[1][0];
/**
* Traitement éléments de documentation à placer dans le WSDL
* Supprime les retours chariots.
* Récupére les éléments de documentation
*/
$comment = '';
$docBlock = preg_replace('/\n/', '', $property->getDocComment() );
if (preg_match('/\/\*\*(.+) \* @var\s+[^\s]+\s+(?:\*|@)/m', $docBlock, $docBlockMatches)) {
$comment.= preg_replace(
array('/\r/', '/\*/' ),
array('' , ''), $docBlockMatches[1]
);
}
/**
* Traitement des @xsd (Provisoire)
* Définition des longueurs dans la documentation
* @xsd minLength=[\d]+ => (Longueur min = [\d]+)
* @xsd maxLength=[\d]+ => (Longueur max = [\d]+)
* @xsd enumeration=element,element
*/
if (preg_match_all('/@xsd\s+(minLength|maxLength)=([\d]+)\s+(?:\*|@)/m', $property->getDocComment(), $resMatches, PREG_SET_ORDER)){
$comment.= '(';
$parcourCpt = 0;
foreach ($resMatches as $res ) {
switch ($res[1]){
case 'minLength':
$comment.= 'Longueur min = '.$res[2];
break;
case 'maxLength':
$comment.= 'Longueur max = '.$res[2];
break;
}
$parcourCpt++;
if ($parcourCpt>0 && $parcourCpt<count($resMatches)) {
$comment.= ', ';
}
}
$comment.= ')';
}
/**
* Traitement des références
* @ref fichier:titre:nom_du_fichier
* => http://vhost/ref/fichier/
* @ref mysql:titre:requete.sql
* => http://vhost/ref/table/
*/
if (preg_match_all('/@ref\s+(fichier|mysql):(.*):(.*)\.(?:csv|sql)\s+(?:\*|@)/m', $property->getDocComment(), $refMatches, PREG_SET_ORDER)){
$view = new Zend_View();
$comment.= ', Référence(s) : ';
foreach ($refMatches as $ref){
switch ($ref[1]){
case 'fichier':
$urlFichier = $view->url(array(
'controller' => 'ref',
'action' => 'fichier',
'q' => $ref[3],
), null, true);
$comment.= '<a href="'.$urlFichier.'">'.$ref[2].'</a>';
break;
case 'mysql':
$urlMysql = $view->url(array(
'controller' => 'ref',
'action' => 'table',
'q' => $ref[3],
), null, true);
$comment.= '<a href="'.$urlMysql.'">'.$ref[2].'</a>';
break;
}
$comment.= ', ';
}
}
$paramElement = array(
'name' => $name,
'type' => $type,
'description' => trim($comment)
);
}
$paramsElement[] = $paramElement;
}
$typesElement[$className] = $paramsElement;
}
$this->serviceTypes = $typesElement;
}
}
}

188
library/Scores/Ws/Doc.php Normal file
View File

@ -0,0 +1,188 @@
<?php
class Scores_Ws_Doc
{
private $serviceClass;
private $classmap = array();
private $serviceMethods = array();
private $serviceTypes = array();
public function __construct($serviceClass = null, $classmap = null, $path)
{
$this->serviceClass = $serviceClass;
$this->classmap = $classmap;
require_once $path . $this->serviceClass . '.php';
$this->parseService();
$this->parseTypes();
}
/**
* Retourne la liste des services et leurs paramètres
* @return array
*/
public function getServiceMethods()
{
return $this->serviceMethods;
}
/**
* Retourne la liste des types de données et leurs paramètres
* @return array
*/
public function getServiceTypes()
{
return $this->serviceTypes;
}
private function parseService()
{
$class = new Zend_Server_Reflection();
$methods = $class->reflectClass($this->serviceClass)
->getMethods();
$methodsElement = array();
foreach ($methods as $method) {
$prototype = null;
$maxNumArgumentsOfPrototype = -1;
foreach ($method->getPrototypes() as $tmpPrototype) {
$numParams = count($tmpPrototype->getParameters());
if ($numParams > $maxNumArgumentsOfPrototype) {
$maxNumArgumentsOfPrototype = $numParams;
$prototype = $tmpPrototype;
}
}
$paramsElement = array();
foreach ($prototype->getParameters() as $param) {
$paramElement = array(
'type' => $param->getType(),
'name' => $param->getName(),
'description' => $param->getDescription(),
);
if ($param->isOptional()){
$paramElement['optional'] = $param->isOptional();
$paramElement['defaultValue'] = $param->getDefaultValue();
}
$paramsElement[] = $paramElement;
}
$methodElement = array(
'name' => $method->getName(),
'desc' => $method->getDescription(),
'params' => $paramsElement,
'return' => $prototype->getReturnType(),
);
$methodsElement[] = $methodElement;
}
$this->serviceMethods = $methodsElement;
}
private function parseTypes()
{
$typesElement = array();
if (count($this->classmap)>0)
{
foreach ($this->classmap as $className)
{
$class = new ReflectionClass($className);
$paramsElement = array();
foreach ($class->getProperties() as $property) {
if ($property->isPublic() && preg_match_all('/@var\s+([^\s]+)/m', $property->getDocComment(), $matches)) {
$name = $property->getName();
$type = $matches[1][0];
/**
* Traitement éléments de documentation à placer dans le WSDL
* Supprime les retours chariots.
* Récupére les éléments de documentation
*/
$comment = '';
$docBlock = preg_replace('/\n/', '', $property->getDocComment() );
if (preg_match('/\/\*\*(.+) \* @var\s+[^\s]+\s+(?:\*|@)/m', $docBlock, $docBlockMatches)) {
$comment.= preg_replace(
array('/\r/', '/\*/' ),
array('' , ''), $docBlockMatches[1]
);
}
/**
* Traitement des @xsd (Provisoire)
* Définition des longueurs dans la documentation
* @xsd minLength=[\d]+ => (Longueur min = [\d]+)
* @xsd maxLength=[\d]+ => (Longueur max = [\d]+)
* @xsd enumeration=element,element
*/
if (preg_match_all('/@xsd\s+(minLength|maxLength)=([\d]+)\s+(?:\*|@)/m', $property->getDocComment(), $resMatches, PREG_SET_ORDER)){
$comment.= '(';
$parcourCpt = 0;
foreach ($resMatches as $res ) {
switch ($res[1]){
case 'minLength':
$comment.= 'Longueur min = '.$res[2];
break;
case 'maxLength':
$comment.= 'Longueur max = '.$res[2];
break;
}
$parcourCpt++;
if ($parcourCpt>0 && $parcourCpt<count($resMatches)) {
$comment.= ', ';
}
}
$comment.= ')';
}
/**
* Traitement des références
* @ref fichier:titre:nom_du_fichier
* => http://vhost/ref/fichier/
* @ref mysql:titre:requete.sql
* => http://vhost/ref/table/
*/
if (preg_match_all('/@ref\s+(fichier|mysql):(.*):(.*)\.(?:csv|sql)\s+(?:\*|@)/m', $property->getDocComment(), $refMatches, PREG_SET_ORDER)){
$view = new Zend_View();
$comment.= ', Référence(s) : ';
foreach ($refMatches as $ref){
switch ($ref[1]){
case 'fichier':
$urlFichier = $view->url(array(
'controller' => 'ref',
'action' => 'fichier',
'q' => $ref[3],
), null, true);
$comment.= '<a href="'.$urlFichier.'">'.$ref[2].'</a>';
break;
case 'mysql':
$urlMysql = $view->url(array(
'controller' => 'ref',
'action' => 'table',
'q' => $ref[3],
), null, true);
$comment.= '<a href="'.$urlMysql.'">'.$ref[2].'</a>';
break;
}
$comment.= ', ';
}
}
$paramElement = array(
'name' => $name,
'type' => $type,
'description' => trim($comment)
);
}
$paramsElement[] = $paramElement;
}
$typesElement[$className] = $paramsElement;
}
$this->serviceTypes = $typesElement;
}
}
}

View File

@ -2596,11 +2596,11 @@ class Interne extends WsScore
* @return ContactEtReturn
* @throws SoapFault
*/
public function getContactEt($siret, $filtre, $position = 0, $nbRep = 200)
public function getContactEt($siret, $filtre = null, $position = 0, $nbRep = 200)
{
$this->authenticate();
if ( strlen($siret)!=9 || strlen($siret)!=14 ) {
if ( strlen($siret)!=9 && strlen($siret)!=14 ) {
$this->sendError('1010');
}
@ -2609,20 +2609,26 @@ class Interne extends WsScore
$this->sendError('1010');
}
$nic = substr($nic,10,5);
$nic = substr($siret,9,5);
if (intval($nic)==0) {
$nic = '00000';
}
$typeToSelect = array('fax', 'web', 'mail', 'tel');
$telephonieM = new Application_Model_JoTelephonie();
$sql = $telephonieM->select()
->from($telephonieM, array('id', 'typeTel', 'infoTel', 'telephone', 'partenaire', "DATE_FORMAT(dateInsert,'%Y%m%d')"))
->from($telephonieM, array('id', 'typeTel', 'infoTel', 'LPAD(telephone, 10, 0) AS telephone', 'partenaire', "DATE_FORMAT(dateInsert,'%Y%m%d') AS dateInsert"))
->where('actif=1')
->where('typeTel=?','tel')
->where('siren=?',$siren)
->where('nic=?',$nic)
->order('dateInsert DESC')
->limit($nbRep, $position);
->where('typeTel IN ("'.join('","', $typeToSelect).'")')
->where('siren=?',$siren);
if ( intval($nic) > 0 ) {
$sql->where('nic=?',$nic);
}
$sql->order('dateInsert DESC')->limit($nbRep, $position);
try {
$contacts = $telephonieM->fetchAll($sql);
} catch (Zend_Db_Exception $e) {
@ -2637,11 +2643,18 @@ class Interne extends WsScore
$sql = $telephonieM->select()
->from($telephonieM, 'COUNT(*) as nb')
->where('actif=1')
->where('typeTel=?','tel')
->where('siren=?',$siren)
->where('nic=?',$nic);
->where('typeTel IN ("'.join('","', $typeToSelect).'")')
->where('siren=?',$siren);
if ( intval($nic) > 0 ) {
$sql->where('nic=?',$nic);
}
$nbContacts = $telephonieM->fetchRow($sql)->nb;
$result = $telephonieM->fetchRow($sql);
$nbContacts = 0;
if ( $result !== null ) {
$nbContacts = $result->nb;
}
$list = array();
if ( $contacts->count() > 0) {
@ -2649,7 +2662,11 @@ class Interne extends WsScore
{
$contact = new ContactEt();
$contact->id = $item->id;
$contact->value = $item->telephone;
if ( in_array($item->typeTel, array('mail', 'web')) ) {
$contact->value = $item->infoTel;
} else {
$contact->value = $item->telephone;
}
$contact->type = $item->typeTel;
$contact->description = '';
$contact->source = '';

View File

@ -1567,7 +1567,7 @@ class BilanSaisieInfos
class ContactEtReturn
{
/** @var int */
public $nbContacts;
public $nbReponses;
/** @var ContactEt[] */
public $result;
}

View File

@ -8,8 +8,9 @@ appnamespace = "Application"
resources.session.save_path = APPLICATION_PATH "/../data/sessions"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.plugins.Auth = "Application_Controller_Plugin_Auth"
resources.frontController.plugins.Services = "Application_Controller_Plugin_Services"
resources.frontController.params.displayExceptions = 0
resources.layout.layout = "main"
resources.layout.layout = "layout"
resources.layout.layoutPath = APPLICATION_PATH "/views"
resources.view.basePath = APPLICATION_PATH "/views"
autoloaderNamespaces[] = "Application_"