diff --git a/src/Scores/Account/Access.php b/src/Scores/Account/Access.php new file mode 100644 index 0000000..678041f --- /dev/null +++ b/src/Scores/Account/Access.php @@ -0,0 +1,85 @@ + "Export des résultats de la recherche", + 'IPARI' => "Investigation par l'image IparI©", + 'HISTOBODACC' => "Historique des annonces bodacc", + 'INVESTIG' => "Investigation", + 'SEARCHENT' => "Recherche Entreprise", + 'SEARCHDIR' => "Recherche Dirigeant", + 'SEARCHACT' => "Recherche Actionnaire", + + //IDENTITE + 'IDENTITE' => "Fiche d'identité", + 'IDPROCOL' => 'Fiche procédure collective', + 'LIENS' => "Liens inter-entreprise", + 'ETABLISSEMENTS' => "Liste des établissements", + 'GROUPE' => "Informations et organigramme du groupe", + 'EVENINSEE' => 'Évènements INSEE', + 'AVISINSEE' => 'Avis de situation INSEE', + 'AVISRNCS' => 'Avis de situation RNCS', + 'RNVP' => "Normalisation postale", + + //DIRIGEANT + 'DIRIGEANTS' => "Liste des dirigeants", + 'DIRIGEANTSOP' => "Liste des dirigeants opérationnels", + + //FINANCE + 'SYNTHESE' => "Synthèse", + 'RATIOS' => "Ratios", + 'FLUX' => "Flux de trésorerie", + 'LIASSE' => "Liasse fiscale", + 'LIASSEXLS' => "Export des Liasses au format XLS", + 'UPLOADBILAN' => "Saisie de bilan", + 'BOURSE' => "Bourse & cotations", + 'BANQUE' => "Relations bancaires", + + //JURIDIQUE + 'ANNONCES' => "Annonces légales", + 'INFOSREG' => "Informations réglementée", + 'COMPETENCES' => "Compétences territoriales", + 'CONVENTIONS' => "Conventions collectives", + 'MARQUES' => "Marques déposées", + 'CONTENTIEUX' => "Contentieux Judiciaires", + + //EVALUATION + 'INDISCORE' => "indiScore©", + 'INDISCORE2' => "Rapport synthetique", + 'INDISCORE3' => "Rapport complet", + 'INDISCOREP' => "indiScore+", + 'INDISCORE2P' => "Rapport synthetique+", + 'INDISCORE3P' => "Rapport complet+", + 'VALORISATION' => "Valorisation", + 'SCORECSF' => "Score CSF", + 'ENQUETEC' => "Enquête commerciale", + 'AVISCREDIT' => "Avis de crédit personnalisé", + + //PIECES + 'KBIS' => "Extrait RCS", + 'ACTES' => "Pièces officielles", + 'PRIVILEGES' => "Privilèges", + + //SURVEILLANCES + 'SURVANNONCE' => "Surveillance des annonces légales", + 'SURVINSEE' => "Surveillance des événements INSEE", + 'SURVBILAN' => "Surveillance des bilans saisies (liasse fiscale)", + 'SURVSCORE' => "Surveillance des événements sur le score", + 'SURVACTES' => "Surveillance des pieces officielles (comptes annuels, actes)", + 'SURVDIRIGEANTS'=> "Surveillance des dirigeants", + 'SURVPAIEMENTS' => "Surveillance des paiements", + 'SURVLIENS' => "Surveillance des liens financiers", + 'SURVPRIV' => "Surveillance des privilèges", + + //OPTIONS + 'MONPROFIL' => "Mon profil", + 'EDITION' => "Mode Edition", + 'PORTEFEUILLE' => "Portefeuille", + 'SURVLISTE' => "Liste des surveillances", + + //DIVERS + 'INTERNATIONAL' => "Recherche Internationale", + 'BDF' => "Banque de France", + 'WORLDCHECK' => "World-Check Risk Intelligence", + +); diff --git a/src/Scores/Account/Category.php b/src/Scores/Account/Category.php new file mode 100644 index 0000000..badd2b1 --- /dev/null +++ b/src/Scores/Account/Category.php @@ -0,0 +1,112 @@ + array( + 'label' => "Recherche", + 'droits' => array( + 'RECHCSV', + 'IPARI', + 'HISTOBODACC', + 'INVESTIG', + 'SEARCHENT', + 'SEARCHDIR', + 'SEARCHACT' + ), + ), + 'IDENTITE' => array( + 'label' => "Identité", + 'droits' => array( + 'IDENTITE', + 'IDPROCOL', + 'LIENS', + 'ETABLISSEMENTS', + 'GROUPE', + 'EVENINSEE', + 'AVISINSEE', + 'AVISRNCS', + 'RNVP' + ), + ), + 'DIRIGEANT' => array( + 'label' => "Dirigeant", + 'droits' => array( + 'DIRIGEANTS', + 'DIRIGEANTSOP', + 'WORLDCHECK' + ), + ), + 'FINANCE' => array( + 'label' => 'Elements Financiers', + 'droits' => array( + 'SYNTHESE', + 'RATIOS', + 'FLUX', + 'LIASSE', + 'LIASSEXLS', + 'UPLOADBILAN', + 'BOURSE', + 'BANQUE' + ), + ), + 'JURIDIQUE' => array( + 'label' => 'Elements Juridiques', + 'droits' => array('ANNONCES', + 'INFOSREG', + 'COMPETENCES', + 'CONVENTIONS', + 'MARQUES', + 'CONTENTIEUX' + ), + ), + 'EVALUATION' => array( + 'label' => 'Evaluation', + 'droits' => array( + 'INDISCORE', + 'INDISCORE2', + 'INDISCORE3', + 'INDISCOREP', + 'INDISCORE2P', + 'INDISCORE3P', + 'VALORISATION', + 'ENQUETEC', + 'AVISCREDIT' + ), + ), + 'PIECES' => array( + 'label' => 'Pièces officielles', + 'droits' => array( + 'KBIS', + 'ACTES', + 'PRIVILEGES' + ), + ), + 'SURVEILLANCES' => array( + 'label' => 'Surveillances', + 'droits' => array( + 'SURVANNONCE', + 'SURVINSEE', + 'SURVBILAN', + 'SURVSCORE', + 'SURVACTES', + 'SURVDIRIGEANTS', + 'SURVPAIEMENTS', + 'SURVLIENS', + 'SURVPRIV', + ), + ), + 'OPTIONS' => array( + 'label' => 'Options', + 'droits' => array( + 'MONPROFIL', + 'SURVLISTE', + 'PORTEFEUILLE', + 'EDITION' + ), + ), + 'DIVERS' => array( + 'label' => 'Divers', + 'droits' => array( + 'INTERNATIONAL', + 'BDF' + ), + ), +); diff --git a/src/Scores/Account/modeles/create.html b/src/Scores/Account/modeles/create.html new file mode 100755 index 0000000..4f4d4c4 --- /dev/null +++ b/src/Scores/Account/modeles/create.html @@ -0,0 +1,67 @@ +
+

+Scores & Décisions - Paramètres d'accès

+ + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + +
+
Interface
+
+ http://extranet.scores-decisions.com + - Cliquer sur ce lien et enregistrer le dans votre navigateur +
+
Login
+
+
+
{{Login}} + - Votre Identifiant
+
+
+
Mot de passe
+
+
+
{{Password}} + - respecter la casse des caractères
+
+
+
Date d'ouverture de compte
+
{{DateHeure}} + Paris +
+
+
+

Vous recevez ce message à l'adresse {{Email}}, +suite à l'ouverture d'un contrat pour une prestation chez Scores & Décisions. +http://www.scores-decisions.com.
+L’équipe Support est à votre disposition pour +toute question. +

+
+
\ No newline at end of file diff --git a/src/Scores/Account/modeles/password.html b/src/Scores/Account/modeles/password.html new file mode 100755 index 0000000..738815a --- /dev/null +++ b/src/Scores/Account/modeles/password.html @@ -0,0 +1,67 @@ +
+

+Scores & Décisions - Modification de vos paramètres d'accès

+ + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + +
+
Interface
+
+ http://extranet.scores-decisions.com + - Cliquer sur ce lien et enregistrer le dans votre navigateur +
+
Login
+
+
+
{{Login}} + - Votre Identifiant
+
+
+
Mot de passe
+
+
+
{{Password}} + - respecter la casse des caractères
+
+
+
Date de modification
+
{{DateHeure}} + Paris +
+
+
+

Vous recevez ce message à l'adresse {{Email}}, +suite à une modification de votre accès chez Scores & Décisions. +http://www.scores-decisions.com.
+L’équipe Support est à votre disposition pour +toute question. +

+
+
\ No newline at end of file diff --git a/src/Scores/Auth/Adapter/Db.php b/src/Scores/Auth/Adapter/Db.php new file mode 100644 index 0000000..0ac61cb --- /dev/null +++ b/src/Scores/Auth/Adapter/Db.php @@ -0,0 +1,152 @@ +_username = $username; + $this->_password = $password; + $this->_hash = md5($username.'|'.$password); + $this->checkWs = $checkWs; + + $this->conn = Zend_Registry::get('doctrine'); + + if (Zend_Registry::isRegistered('logger')) { + $this->logger = Zend_Registry::get('logger'); + } + } + + /** + * 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() + { + try { + $qb = $this->conn->createQueryBuilder(); + $qb->select(array('u.idClient', 'u.id', 'u.login', 'u.password', 'c.timeout')) + ->from('sdv1.utilisateurs', 'u') + ->join('u', 'sdv1.clients', 'c', 'u.idClient = c.id') + ->where("u.login=:login")->setParameter('login', $this->_username) + ->andWhere("u.actif=1") + ->andWhere("u.deleted=0") + ->andWhere("c.actif='Oui'"); + if (count($this->clients) > 0) { + $qb->andWhere('u.idClient IN('.join(',', $this->clients).')'); + } + + if ($this->checkWs) { + $qb->andWhere('u.accesWS=1'); + } + + $stmt = $qb->execute(); + } catch (\Doctrine\DBAL\DBALException $e) { + if ($this->logger !== null) { + $this->logger->error($e->getMessage()); + } + } + + $identity = new stdClass(); + $identity->username = $this->_username; + $identity->hash = $this->_hash; + + if ($stmt->rowCount() == 0) { + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND, $identity, + array("Identifiant ou mot de passe invalid")); + } else { + $result = $stmt->fetch(PDO::FETCH_OBJ); + if ($this->_password == $result->password + || $this->_password == md5($result->login.'|'.$result->password)) { + + /** + * Date de debut de compte + */ + if (!empty($result->dateDebutCompte) && $result->dateDebutCompte!='0000-00-00') { + $today = mktime(0, 0, 0, date('m'), date('d'), date('Y')); + $dateDebutCompte = mktime(0, 0, 0, substr($result->dateDebutCompte, 5, 2), + substr($result->dateDebutCompte, 8, 2), substr($result->dateDebutCompte, 0, 4)); + if ($today < $dateDebutCompte) { + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, $identity, + array("Date de validité dépassé")); + } + } + + /** + * Date de fin de compte + */ + if (!empty($result->dateFinCompte) && $result->dateFinCompte!='0000-00-00') { + $today = mktime(0, 0, 0, date('m'), date('d'), date('Y')); + $dateFinCompte = mktime(0, 0, 0, substr($result->dateFinCompte, 5, 2), + substr($result->dateFinCompte, 8, 2), substr($result->dateFinCompte, 0, 4)); + if ($today > $dateFinCompte) { + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, $identity, + array("Date de validité dépassé")); + } + } + + $identity->id = $result->id; + $identity->idClient = $result->idClient; + $timeout = (!empty($result->timeout)) ? $result->timeout : $this->_timeout; + $identity->timeout = $timeout; + $identity->time = time() + $timeout; + return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity); + } else { + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, $identity, + array("Identification impossible")); + } + } + } +} diff --git a/src/Scores/Auth/Adapter/Ws.php b/src/Scores/Auth/Adapter/Ws.php new file mode 100644 index 0000000..98f482d --- /dev/null +++ b/src/Scores/Auth/Adapter/Ws.php @@ -0,0 +1,189 @@ +_username = $username; + $this->_password = $password; + + if ($mode == 'hach') { + $this->_checkHach = true; + } + + if ($mode == 'iponly') { + $ip = $_SERVER['REMOTE_ADDR']; + if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && in_array($ip, $this->listProxyIp)) { + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } + $this->_password = 'iponly:'.$ip; + $this->_checkIp = true; + } + } + + /** + * (non-PHPdoc) + * @see Zend_Auth_Adapter_Interface::authenticate() + */ + public function authenticate() + { + $ip = $_SERVER['REMOTE_ADDR']; + if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && in_array($ip, $this->listProxyIp)) { + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } + + $ws = new Scores_Ws_Client('gestion', '0.3'); + $ws->setHttpLogin($this->_username); + $ws->setHttpPassword($this->_password); + $adressIp = $_SERVER['REMOTE_ADDR']; + $parameters = new stdClass(); + $parameters->login = $this->_username; + $parameters->ipUtilisateur = $ip; + $parameters->from = 'auth'; + $InfosLogin = $ws->getInfosLogin($parameters); + + // --- 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)); + } + // --- Assignation identity + elseif ($InfosLogin !== false && !empty($InfosLogin->result->login)) { + $identity = new stdClass(); + if ($this->_checkIp || $this->_checkHach) { + Zend_Registry::get('firebug')->info("IN"); + $identity->password = $this->_password; + } else { + $identity->password = md5($InfosLogin->result->login.'|'.$this->_password); + } + Zend_Registry::get('firebug')->info($identity->password); + $identity->username = $InfosLogin->result->login; + $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 = $ip; + $identity->version = $InfosLogin->result->version; + $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 = array( + '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.100-212.155.191.199', // Satair A/S + '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 + ); + + // --- Validation IP + $overallIpValidate = false; + foreach ($ipInterdites as $filtre) { + if (strpos($filtre, '*')) { + $filtre = str_replace('*', '0', $filtre) . '-' . str_replace('*', '255', $filtre); + } + // Is it a range ? + if (strpos($filtre, '-')) { + $validateIp = new Scores_Validate_IpInNetwork(); + $validateIp->setNetworkNotation($filtre); + $overallIpValidate = $validateIp->isValid($ipToValidate); + } + // Ip only + else { + if ($filtre === $ipToValidate) { + $overallIpValidate = true; + } + } + // Break foreach + if ($overallIpValidate === true) { + break; + } + } + + // Exit with error + if ($overallIpValidate === false) { + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_UNCATEGORIZED, $identity); + } + + // --- OK connecté + $this->_username = $identity->username; + $this->_password = $identity->password; + return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity); + } else { + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_UNCATEGORIZED, $identity, array("Identification impossible")); + } + } +} diff --git a/src/Scores/Bill/Article.php b/src/Scores/Bill/Article.php new file mode 100644 index 0000000..f6aa708 --- /dev/null +++ b/src/Scores/Bill/Article.php @@ -0,0 +1,7 @@ + "Extranet", + 'webservice' => "WebService", +); \ No newline at end of file diff --git a/src/Scores/Bill/Data.php b/src/Scores/Bill/Data.php new file mode 100644 index 0000000..15591c3 --- /dev/null +++ b/src/Scores/Bill/Data.php @@ -0,0 +1,17 @@ +Image($image_file, PDF_MARGIN_LEFT, 0, 50, '', 'JPG', '', 'T', false, 300, 'C', false, false, 0, false, false, false); + // Set font + $this->SetFont('helvetica', 'B', 15); + $this->SetAbsXY(PDF_MARGIN_LEFT, PDF_MARGIN_HEADER); + $this->Cell(0, 15, '', 'B', false, 'C', 0, '', 0, false, 'M', 'M'); + } + + public function Footer() + { + $cur_y = $this->y; + $this->SetTextColorArray($this->footer_text_color); + //set style for cell border + $line_width = (0.85 / $this->k); + $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $this->footer_line_color)); + + $w_page = isset($this->l['w_page']) ? $this->l['w_page'].' ' : ''; + if (empty($this->pagegroups)) { + $pagenumtxt = $w_page.$this->getAliasNumPage().' / '.$this->getAliasNbPages(); + } else { + $pagenumtxt = $w_page.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias(); + } + $this->SetY($cur_y); + + // Print legal + $this->Cell(0, 10, "Société anonyme par actions simplifiée au capital de 618 450,00 Euros - SIRET : 494 967 938 00056 RCS VERSAILLES B 494967938 - N.I.I: FR 84 494967938", 'T', 1, 'C'); + + // Print page number + $this->SetX($this->original_lMargin); + $this->Cell(0, 0, $this->getAliasRightShift().$pagenumtxt, 0, 0, 'R'); + } + + public function setData($id) + { + // --- Lecture des paramètres de la facturation + $factureM = new Application_Model_FacturationFacture(); + $factureSql = $factureM->select()->where('id=?', $id); + $factureResult = $factureM->fetchRow($factureSql); + + if ($factureResult->type == 'avoir') { + $this->Title = 'Avoir'; + } + switch($factureResult->paiement) { + case 'virement': + $this->ModePaiement = 'Virement'; + break; + case 'cheque': + $this->ModePaiement = 'Cheque'; + break; + case 'none': + $this->ModePaiement = ''; + break; + } + $this->Num = $factureResult->num; + $this->Label = $factureResult->label; + $this->Date = substr($factureResult->date,8,2).'/'.substr($factureResult->date,5,2).'/'.substr($factureResult->date,0,4); + $this->DateDue = substr($factureResult->dateDue,8,2).'/'.substr($factureResult->dateDue,5,2).'/'.substr($factureResult->dateDue,0,4); + $this->ClientNum = $factureResult->clientCode; + $this->DatePeriodBegin = substr($factureResult->periodBegin,8,2).'/'.substr($factureResult->periodBegin,5,2).'/'.substr($factureResult->periodBegin,0,4); + $this->DatePeriodEnd = substr($factureResult->periodEnd,8,2).'/'.substr($factureResult->periodEnd,5,2).'/'.substr($factureResult->periodEnd,0,4); + + /* + $adresseM = new Application_Model_FacturationFactureZoneclient(); + $adresseSql = $adresseM->select()->where('factId=?', $id); + */ + + // --- Articles à facturer + $lineM = new Application_Model_FacturationFactureLine(); + $lineSql = $lineM->select()->where('factId=?', $id)->order('num ASC'); + $lineResult = $lineM->fetchAll($lineSql); + $data = array(); + foreach ($lineResult as $l) { + $data[] = array($l->code, $l->zonetxt, $l->qte, $l->montantUnit, $l->montantLine, $l->tva); + } + $this->Line = $data; + + // --- Calcul + if (count($lineResult) > 0) { + foreach($lineResult as $l) { + $lineTVA = new stdClass(); + if (array_key_exists($l->tva, $this->TauxTVA)) { + $old = $this->TauxTVA[$l->tva]; + $lineTVA->Base = $l->montantLine + $old->Base; + $lineTVA->Mt = $lineTVA->Base * ($l->tva / 100); + } else { + $lineTVA->Base = $l->montantLine; + } + $lineTVA->Mt = $lineTVA->Base * ($l->tva / 100); + $this->TauxTVA[$l->tva] = $lineTVA; + $this->TotalHT+= $l->montantLine; + $this->TotalTTC+= $l->montantLine * (1 + $l->tva / 100); + $this->TotalTVA = $this->TotalTTC - $this->TotalHT; + } + } + } + + public function displayLines() + { + // column titles + $header = array('Code', 'Description', 'Quantité', 'P.U. HT', 'Total HT', 'Tx TVA'); + $w = array(30, 86, 16, 16, 16, 16); + + // Colors, line width and bold font + $this->SetFillColor(200, 200, 200); + $this->SetTextColor(0); + $this->SetDrawColor(0, 0, 0); + //$this->SetLineWidth(0.3); + $this->SetFont('', 'B', 10); + // Header + $num = count($header); + for($i = 0; $i < $num; ++$i) { + $this->Cell($w[$i], 7, $header[$i], 1, 0, 'C', 1); + } + $this->Ln(); + // Color and font restoration + $this->SetFillColor(224, 235, 255); + $this->SetTextColor(0); + $this->SetFont(''); + // Data + $fill = 0; + foreach($this->Line as $row) { + // Label cell + //$this->Cell($w[1], 6, $row[1], 'LR', 0, 'L', $fill, '', 0, true); + $this->SetAbsX(PDF_MARGIN_LEFT + $w[0]); + $nbLine = $this->MultiCell($w[1], 6, $row[1], 'LR', 'L', $fill, 0); + // Other cells + $this->SetAbsX(PDF_MARGIN_LEFT); + $this->Cell($w[0], 6 * $nbLine, $row[0], 'LR', 0, 'L', $fill, '', 0, false, 'T', 'T'); + $this->SetAbsX(PDF_MARGIN_LEFT + $w[0] + $w[1]); + $this->Cell($w[2], 6 * $nbLine, number_format($row[2], 2, ',', ' '), 'LR', 0, 'R', $fill, '', 0, false, 'T', 'T'); + $this->Cell($w[3], 6 * $nbLine, number_format($row[3], 2, ',', ' '), 'LR', 0, 'R', $fill, '', 0, false, 'T', 'T'); + $this->Cell($w[4], 6 * $nbLine, number_format($row[4], 2, ',', ' '), 'LR', 0, 'R', $fill, '', 0, false, 'T', 'T'); + $this->Cell($w[5], 6 * $nbLine, number_format($row[5], 2, ',', ' '), 'LR', 0, 'R', $fill, '', 0, false, 'T', 'T'); + $this->Ln(); + $fill=!$fill; + } + $this->Cell(array_sum($w), 0, '', 'T'); + $this->Ln(); + } + + public function displayResumeTaxe() + { + $this->posY = $this->y; + + $header = array('Tx TVA', 'Base', 'Montant TVA'); + $data = array(); + foreach ($this->TauxTVA as $t => $d) { + $data[] = array($t, $d->Base, $d->Mt); + } + $widthColTotal = $this->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT - 80; + $widthCol = $widthColTotal / 3; + $w = array($widthCol, $widthCol, $widthCol); + + // Colors, line width and bold font + $this->SetFillColor(200, 200, 200); + $this->SetTextColor(0); + $this->SetDrawColor(0, 0, 0); + //$this->SetLineWidth(0.3); + $this->SetFont('', 'B', 8); + // Header + $num = count($header); + for($i = 0; $i < $num; ++$i) { + $this->Cell($w[$i], 6, $header[$i], 1, 0, 'C', 1); + } + $this->Ln(); + // Color and font restoration + $this->SetFillColor(224, 235, 255); + $this->SetTextColor(0); + $this->SetFont(''); + // Data + $fill = 0; + foreach($data as $row) { + for($i = 0; $i < $num; ++$i) { + $this->Cell($w[$i], 6, number_format($row[$i], 2, ',', ' '), 'LR', 0, 'R', $fill); + } + $this->Ln(); + $fill=!$fill; + } + $this->Cell(array_sum($w), 0, '', 'T'); + $this->Ln(); + } + + public function displayTotal() + { + $this->setY($this->posY); + + $header = array('Total HT', 'Total TVA', 'Total TTC', 'Net à payer (en euros)'); + $data = array($this->TotalHT, $this->TotalTVA, $this->TotalTTC, $this->TotalTTC); + $w = array(45, 45, 45, 45); + $maxPosX = $this->getPageWidth() - PDF_MARGIN_RIGHT; + + $num = count($header); + for($i = 0; $i < $num; ++$i) { + $this->SetAbsX($maxPosX - 45 - 30); + // Header - Colors, line width and bold font + $this->SetFillColor(200, 200, 200); + $this->SetTextColor(0); + $this->SetDrawColor(0, 0, 0); + $this->SetLineWidth(0.3); + $this->SetFont('', 'B', 10); + $this->Cell(45, 7, $header[$i], 1, 0, 'C', 1); + + // Data - Color and font restoration + $this->SetFillColor(224, 235, 255); + $this->SetTextColor(0); + $this->SetFont(''); + //$this->SetAbsX($maxPosX - $x); + $this->Cell(30, 7, number_format($data[$i], 2, ',', ' '), 1, 0, 'R', 0); + + $this->Ln(); + } + } + + public function displayPaiement() + { + $this->SetFont('', 'B', 8); + $w = $this->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT - 80; + $this->Cell($w, 0, "Mode de paiement : " . $this->ModePaiement, 'LTR', 1); + $this->Cell($w, 0, "Date d'échéance : " . $this->DateDue, 'LBR', 1); + } + + public function displayIBAN() + { + $header = array('Code Banque', 'Code Guichet', 'N° Compte', 'Clé'); + $data = array('42559', '00072', '21009306208', '91'); + + $widthColTotal = $this->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT - 80; + $widthCol = $widthColTotal / count($header); + + $this->SetFont(''); + $this->Ln(); + // Header + $num = count($header); + for($i = 0; $i < $num; ++$i) { + $this->Cell($widthCol, 6, $header[$i], 1, 0, 'C', 0); + } + $this->Ln(); + // Data + $fill = 0; + for($i = 0; $i < $num; ++$i) { + $this->Cell($widthCol, 6, $data[$i], 'LTRB', 0, 'C', $fill); + } + $this->Ln(); + + $w = $this->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT - 80; + $this->Cell($w, 0, "Code IBAN : FR76 4255 9000 7221 0093 0620 891", 'LTR', 1); + $this->Cell($w, 0, "BIC : CCOPFRPPXXX - Domiciliation : CREDITCOOP PARIS POMMIER", 'LBR', 1); + } + + public function displayFooter() + { + $this->Ln(); + $this->SetFont('', '', 8); + $maxPosX = $this->getPageWidth() - PDF_MARGIN_RIGHT; + $this->Cell($this->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT, 0, '', 'T'); + $this->Ln(); + // Info + $this->Cell(20, 0, "Escompte pour paiement anticipé : Néant", 0, 1, 'L', 0, '', 0, false, 'T', 'M'); + $this->Cell(20, 0, "Pénalités de retard ; 1,5 fois le taux de l'interêt légal", 0, 1, 'L', 0, '', 0, false, 'T', 'M'); + $this->Cell(20, 0, "Frais de recouvrement : pénalité forfaitaire fixée à 10% des sommes dues", 0, 1, 'L', 0, '', 0, false, 'T', 'M'); + + } + + public function compile($id) + { + $this->setPageUnit('mm'); + $this->setPageFormat('A4', 'P'); + + $this->SetAuthor('SCORES ET DECISIONS'); + + $this->setData($id); + + $this->SetTitle($this->Title); + $this->SetSubject($this->Title); + + // set default header data + //$this->SetHeaderData('', 200, "FACTURE", "Scores & Décisions"); + + // set header and footer fonts + $this->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN)); + $this->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA)); + + // set default monospaced font + $this->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); + + // set margins + $this->SetMargins(PDF_MARGIN_LEFT, 20, PDF_MARGIN_RIGHT); + $this->SetHeaderMargin(PDF_MARGIN_HEADER); + $this->SetFooterMargin(PDF_MARGIN_FOOTER); + + // set auto page breaks + $this->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); + + // set image scale factor + $this->setImageScale(PDF_IMAGE_SCALE_RATIO); + + // add a page + $this->AddPage(); + + // set font + $this->SetFont('times', '', 16); + + $maxPosX = $this->getPageWidth() - PDF_MARGIN_RIGHT; + $minPosX = PDF_MARGIN_LEFT; + $maxWidth = $this->getPageWidth() - PDF_MARGIN_RIGHT - PDF_MARGIN_LEFT; + + $this->Cell($maxWidth - 115, 15, strtoupper($this->Title), 0, false, 'C', 0, '', 0, false, 'M', 'M'); + + $this->SetAbsY(15); + + $this->SetFont('times', '', 10); + + // Infos Facture + $this->SetFillColor(200, 200, 200); + $this->SetTextColor(0); + $this->SetDrawColor(0, 0, 0); + //$this->SetLineWidth(0.3); + $this->SetFont('', 'B'); + // Header + $header = array('N°', 'Date', 'Code client'); + $w = array(40, 35, 40); + $num = count($header); + $x = 0; + for($i = 0; $i < $num; ++$i) { + $x+= $w[$num-($i+1)]; + $this->SetAbsX($maxPosX - $x); + $this->Cell($w[$num-($i+1)], 7, $header[$num-($i+1)], 1, 0, 'C', 1); + } + $this->Ln(); + // Data + $this->SetFillColor(255, 255, 255); + $data = array($this->Num, $this->Date, $this->ClientNum); + $num = count($data); + $x = 0; + for($i = 0; $i < $num; ++$i) { + $x+= $w[$num-($i+1)]; + $this->SetAbsX($maxPosX - $x); + $this->Cell($w[$num-($i+1)], 7, $data[$num-($i+1)], 1, 0, 'C', 1); + } + + $this->Ln(); + + $infoClientY = $this->GetY(); + + // set color for background + $this->SetFillColor(255, 255, 255); + + // Infos Client + $w = 90; + $this->SetFont('', 'B'); + $this->SetAbsXY($maxPosX - $w, $infoClientY + 5); + $this->Cell($w, 0, "Adresse de facturation", '', 1, '', false, '', 0, false, 'T', 'M'); + $this->SetFont('', ''); + $this->SetAbsX($maxPosX - $w); + $this->Cell($w, 0, "L1", '', 1, '', false, '', 0, false, 'T', 'M'); + $this->SetAbsX($maxPosX - $w); + $this->Cell($w, 0, "L2", '', 1, '', false, '', 0, false, 'T', 'M'); + $this->SetAbsX($maxPosX - $w); + $this->Cell($w, 0, "L3", '', 1, '', false, '', 0, false, 'T', 'M'); + $this->SetAbsX($maxPosX - $w); + $this->Cell($w, 0, "L4", '', 1, '', false, '', 0, false, 'T', 'M'); + $this->SetAbsX($maxPosX - $w); + $this->Cell($w, 0, "L5", '', 1, '', false, '', 0, false, 'T', 'M'); + $this->SetAbsX($maxPosX - $w); + $this->Cell($w, 0, "L6", '', 1, '', false, '', 0, false, 'T', 'M'); + $this->SetAbsX($maxPosX - $w); + $this->Cell($w, 0, "L7", '', 1, '', false, '', 0, false, 'T', 'M'); + $this->SetAbsX($maxPosX - $w); + $this->Cell($w, 0, "L8", '', 1, '', false, '', 0, false, 'T', 'M'); + + $infoClientEndY = $this->GetY(); + + // Infos SCORES + $w = 90; + $this->SetAbsY($infoClientY + 10); + $this->Cell($w, 0, "SCORES ET DECISIONS SAS", 0, 1, '', false, '', 0, false, 'T', 'M'); + $this->SetFont('', ''); + $this->Cell($w, 0, "1 RUE DE CLAIREFONTAINE", 0, 1, '', false, '', 0, false, 'T', 'M'); + $this->Cell($w, 0, "78120 RAMBOUILLET", 0, 1, '', false, '', 0, false, 'T', 'M'); + $this->Cell($w, 0, "compta@scores-decisions.com", 0, 1, '', false, '', 0, false, 'T', 'M'); + $this->Cell($w, 0, "Tél : 01 75 43 80 10 - Fax : 01 75 43 85 74", 0, 1, '', false, '', 0, false, 'T', 'M'); + $this->Ln(); + + + $this->SetAbsY($infoClientEndY); + $this->SetFont('', 'B', 12); + $this->Cell(20, 0, "Période du " . $this->DatePeriodBegin . " au " . $this->DatePeriodEnd, 0, 1); + $this->SetFont('', '', 12); + $this->Cell(20, 0, "Objet : " . $this->Label, 0, 1); + $this->Ln(); + + // Create table article + $this->displayLines(); + + // Create taxe Resume + $this->displayResumeTaxe(); + + $this->displayPaiement(); + + $this->displayIBAN(); + + $this->displayFooter(); + + //Create total + $this->displayTotal(); + + + // move pointer to last page + $this->lastPage(); + + // --------------------------------------------------------- + + //Close and output PDF document + $this->Output(APPLICATION_PATH . '/../testfacture.pdf', 'F'); + } +} \ No newline at end of file diff --git a/src/Scores/Bill/Pdf/Table.php b/src/Scores/Bill/Pdf/Table.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/src/Scores/Bill/Pdf/Table.php @@ -0,0 +1 @@ +readConfig(); + $this->_defineDb(); + $this->_definePath(); + $this->_defineSphinx(); + $this->_defineMail(); + } + + /** + * Read config application.ini + */ + protected function readConfig() + { + if ( Zend_Registry::isRegistered('config') ) { + $c = Zend_Registry::get('config'); + $this->profil = $c->profil; + } else { + $c = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', 'production'); + $this->profil = $c->profil; + } + } + + protected function _defineDb() + { + $c = Zend_Registry::get('config'); + if ( $c->resources->db ) { + define('MYSQL_HOST', $c->resources->db->params->host); + define('MYSQL_USER', $c->resources->db->params->username); + define('MYSQL_PASS', $c->resources->db->params->password); + define('MYSQL_DEFAULT_DB', 'jo'); + define('MYSQL_SQL_LOG', 'NONE'); + } + } + + + protected function _definePath() + { + //Use of realpath + + define('BODACC_LOCAL_DIR' , '/home/data/bodacc/'); + define('JAL_LOCAL_DIR' , '/home/data/jal/'); + define('HUGIN_LOCAL_DIR' , '/home/data/infosreg/hugin/'); + define('ACTUSNEWS_LOCAL_DIR' , '/home/data/infosreg/actusnews/'); + define('DIRELEASE_LOCAL_DIR' , '/home/data/infosreg/direlease/'); + define('LESECHOS_LOCAL_DIR' , '/home/data/infosreg/lesechos/'); + define('BUSINESSWIRE_LOCAL_DIR_INCOMING' , '/home/data/ftp/businesswire/'); + define('BUSINESSWIRE_LOCAL_DIR' , '/home/data/infosreg/businesswire/'); + + define('DOC_WEB_LOCAL' , $this->profil->path->files.'/'); + define('DOC_WEB_URL' , '/fichier/'); + define('LOG_PATH' , $this->profil->path->shared.'/log'); + } + + protected function _defineSphinx() + { + // Entreprise + define('SPHINX_ENT_HOST', $this->profil->sphinx->ent->host); + define('SPHINX_ENT_PORT', intval($this->profil->sphinx->ent->port)); + define('SPHINX_ENT_VERSION', $this->profil->sphinx->ent->version); + + // Dirigeants + define('SPHINX_DIR_HOST', $this->profil->sphinx->dir->host); + define('SPHINX_DIR_PORT', intval($this->profil->sphinx->dir->port)); + define('SPHINX_DIR_VERSION', $this->profil->sphinx->dir->version); + + // Historique + define('SPHINX_HISTO_HOST', $this->profil->sphinx->histo->host); + define('SPHINX_HISTO_PORT', intval($this->profil->sphinx->histo->port)); + define('SPHINX_HISTO_VERSION', $this->profil->sphinx->histo->version); + + // Actionnaire + define('SPHINX_ACT_HOST', $this->profil->sphinx->act->host); + define('SPHINX_ACT_PORT', intval($this->profil->sphinx->act->port)); + define('SPHINX_ACT_VERSION', $this->profil->sphinx->act->version); + + //Old + define('SPHINX_HOST', $this->profil->sphinx->ent->host); + define('SPHINX_PORT', intval($this->profil->sphinx->ent->port)); + } + + protected function _defineMail() + { + //Messagerie + define('SMTP_HOST', $this->profil->mail->smtp_host); + define('SMTP_PORT', ''); + define('SMTP_USER', ''); + define('SMTP_PASS', ''); + } + +} \ No newline at end of file diff --git a/src/Scores/Conso/Export.php b/src/Scores/Conso/Export.php new file mode 100644 index 0000000..9845793 --- /dev/null +++ b/src/Scores/Conso/Export.php @@ -0,0 +1,95 @@ + "Identifiant", + 'referenceParDefaut' => "Service", + 'page' => "Code Requete", + 'pageLib' => "Libellé Requete", + 'params' => "Paramètres", + 'siren' => "Siren", + 'nic' => "Nic", + 'raisonSociale' => "Raison Sociale", + 'cp' => "CP", + 'ville' => "Ville", + 'dateHeure' => "DateHeure", + 'nbDoublon' => "Nb Doublon", + ); + + protected $pageLib = array(); + + protected $data = array(); + + /** + * Export des logs de conso sous forme de fichier CSV + */ + public function __construct() + { + $this->setPageLib(); + } + + public function setData($d) + { + $this->data = $d; + } + + /** + * Formattage des données pour le CSV + * @param string $filename + * @param string $addEntete + */ + public function export($filename, $addEntete = true) + { + $enteteCode = array_keys($this->entete); + $enteteLabel = array_values($this->entete); + + // Create CSV File + $csv = Writer::createFromPath($filename, 'w'); + // Insert the CSV header + $csv->insertOne($enteteLabel); + + // --- Parcours des données + foreach ($this->data as $data){ + $row = array(); + foreach ($enteteCode as $entete) { + if (array_key_exists($entete, $data)) { + $row[] = $data[$entete]; + } else if (property_exists($this, $entete)){ + $code = str_replace('Lib', '', $entete); + if (array_key_exists($data[$code], $this->{$entete})) { + $row[] = $this->{$entete}[$data[$code]]; + } else { + $row[] = 'NO LABEL'; + } + } else { + $row[] = 'UNKNOWN'; + } + } + + // Insert Data + $csv->insertOne($row); + } + } + + /** + * Récupération des libellés de requete + */ + protected function setPageLib() + { + $libM = new Application_Model_Sdv1LogsItem(); + $libSql = $libM->select()->from($libM, array('Code', 'Label')); + $libResult = $libM->fetchAll($libSql); + if (count($libResult) > 0) { + foreach ($libResult as $l) { + $this->pageLib[$l->Code] = $l->Label; + } + } + } + +} \ No newline at end of file diff --git a/src/Scores/Conso/File.php b/src/Scores/Conso/File.php new file mode 100644 index 0000000..ebdb616 --- /dev/null +++ b/src/Scores/Conso/File.php @@ -0,0 +1,135 @@ +table = $table; + $this->sql = $this->table->select(); + } + + /** + * Array of login + * @param array $login + */ + public function setLogin($login) + { + $this->login = $login; + } + + /** + * Date au format AAAAMM + * @param string $date + */ + public function setDate($date) + { + $this->date = $date; + } + + /** + * Code de l'élément à compter + * @param string $item + */ + public function setItem($item) + { + $this->item = $item; + } + + /** + * Retourne la requete + * @return Zend_Db_Select + */ + public function getSqlRule() + { + $this->addSqlLogin(); + $this->addSqlItem(); + $this->addSqlDate(); + + return $this->sql; + } + + /** + * + * @param unknown $name + * @param unknown $value + */ + public function setOption($name, $value) + { + if ( null === $this->item ) { + return new Zend_Exception('Item is not set !'); + } + + if ($name == 'duplicate') { + if ( !array_key_exists('duplicate', $this->rules[$this->item]) ) { + switch ( strtolower($value) ) { + case 'day': + case 'jour': + $this->rules[$this->item]['duplicate'] = 'day'; + break; + case 'month': + case 'mois': + case 'period': + case 'periode': + $this->rules[$this->item]['duplicate'] = 'period'; + break; + } + } + } + } + + /** + * + */ + public function addSqlLogin() + { + $this->sql->where("login IN ('".join("','", $this->login)."')"); + } + + public function addSqlDate() + { + $formatedDate = substr($this->date,0,4).'-'.substr($this->date,4,2); + $this->sql->where("dateAjout BETWEEN '".$formatedDate."-01 00:00:00' AND '".$formatedDate."-31 23:59:59'"); + } + + public function addSqlItem() + { + $this->sql->from($this->table, array('COUNT(*) AS NB')); + + $rule = $this->rules[$this->item]; + + //Apply item parameters + /*if ( array_key_exists('params', $rule) && count($rule['params'])>0 ) { + foreach ( $rule['params'] as $param ) { + $this->sql->where($param); + } + }*/ + $this->sql->where('source=?', $this->item); + + $this->sql->order('dateAjout ASC'); + } + +} \ No newline at end of file diff --git a/src/Scores/Conso/Flux.php b/src/Scores/Conso/Flux.php new file mode 100644 index 0000000..8f63773 --- /dev/null +++ b/src/Scores/Conso/Flux.php @@ -0,0 +1,66 @@ +table = $table; + $this->sql = $this->table->select(); + } + + /** + * Date au format AAAAMM + * @param string $date + * @param boolean $stock + */ + public function setDate($date, $stock = false) + { + $this->date = $date; + $this->dateStock = $stock; + } + + public function setCode($name) + { + $this->code = $name; + } + + public function setType($name) + { + + } + + public function getSqlRule() + { + $this->sql->from($this->table, array('COUNT(*) AS NB')); + + $formatedDate = substr($this->date,0,4).'-'.substr($this->date,4,2); + if ($this->dateStock === true) { + $this->sql->where("dateSuppr = 0"); + } else { + $this->sql->where("dateAjout BETWEEN '".$formatedDate."-01 00:00:00' AND '".$formatedDate."-31 23:59:59'"); + } + + $this->sql->where('idClient=?', $this->code); + + return $this->sql; + } + +} \ No newline at end of file diff --git a/src/Scores/Conso/Logs.php b/src/Scores/Conso/Logs.php new file mode 100644 index 0000000..f30223e --- /dev/null +++ b/src/Scores/Conso/Logs.php @@ -0,0 +1,358 @@ + array( + * 'params' => array of supplemental sql and where + * 'duplicate' => none, day, month, period (specified if this params must not change) + * ) + * @var array + */ + protected $rules = array ( + 'identite' => array(), + 'annonces' => array(), + 'dirigeants' => array(), + 'dirigeantsop' => array(), + 'evenements' => array(), + 'etablissements' => array(), + 'liens' => array( + 'duplicate' => 'none', + ), + 'competences' => array(), + 'kbis' => array(// à correler avec la table des commandes - Non fonctionnel + 'duplicate' => 'day', + ), + 'synthese' => array(), + 'ratios' => array(), + 'bilan' => array( + 'duplicate' => 'none', + ), + 'indiscore' => array(), + 'indiscore2' => array(), + 'indiscore3' => array(), + 'indiscorep' => array(), + 'indiscore2p' => array(), + 'indiscore3p' => array(), + 'flux' => array(), + 'liassexls' => array( + 'duplicate' => 'none', + ), + 'rapport1' => array(), + 'rapport2' => array(), + 'rapport3' => array(), + 'marques' => array(), + 'banque' => array(), + 'conventions' => array(), + 'groupeinfos' => array(), + 'groupesarbo' => array(), + 'infosreg' => array(), + 'rechcsv' => array( + 'duplicate' => 'none', + ), + 'greffe_bilans' => array( + 'params' => array( + "params != 'Liste'" + ), + 'group' => array('login', 'siren', 'page', 'params', 'raisonSociale', 'period'), + ), + 'greffe_actes' => array( + 'params' => array( + "params != 'Liste'" + ), + 'group' => array('login', 'siren', 'page', 'params', 'raisonSociale', 'period'), + ), + 'greffe_statuts' => array( + 'group' => array('login', 'siren', 'page', 'params', 'raisonSociale', 'period'), + ), + 'bourse' => array(), + 'scorecsf' => array(), + 'avis_situation' => array(), + 'privileges' => array(), + 'commandeAsso' => array(), + 'privcumul' => array(), + 'privdetail' => array(), + 'uploadbilan' => array(), + 'histobodacc' => array(), + 'aviscredit' => array(), + 'tva' => array(), + 'sirenExiste' => array(), + 'histobodacc' => array(), + 'valo' => array(), + 'rnvp' => array(), + 'avisrncs' => array(), + 'affairelist' => array(), + 'affairedetail' => array(), + ); + + /** + * @var Zend_Db_Table_Abstract + */ + protected $table; + + /** + * + * @var Zend_Db_Select + */ + protected $sql; + + /** + * + * @param Zend_Db_Table_Abstract $table + */ + public function __construct(Zend_Db_Table_Abstract $table) + { + $this->table = $table; + $this->sql = $this->table->select(); + } + + /** + * Array of login + * @param array $login + */ + public function setLogin($login) + { + $this->login = $login; + } + + /** + * Date au format AAAAMM + * @param string $date + */ + public function setDate($date) + { + $this->date = $date; + } + + /** + * Code de l'élément à compter + * @param string $item + */ + public function setItem($item) + { + $this->item = $item; + } + + /** + * Retourne requete SQL avec les règles + * @return Zend_Db_Select + */ + public function getSqlRule($file = false) + { + $this->addSqlLogin(); + $this->addSqlItem($file); + $this->addSqlDate(); + + return $this->sql; + } + + /** + * Retourne requete SQL + * @return Zend_Db_Select + */ + public function getSql() + { + $this->addSqlLogin(); + $this->addSqlDate(); + + $columns = array( + 'LOWER(login) AS login', 'page', 'LPAD(siren, 9, 0) AS siren', 'LPAD(nic, 5, 0) AS nic', + 'params', 'raisonSociale', 'cp', 'ville', 'dateHeure', new Zend_Db_Expr('"none" as nbDoublon')); + $this->sql->from($this->table, $columns); + + return $this->sql; + } + + /** + * + * @param unknown $name + * @param unknown $value + */ + public function setOption($name, $value) + { + if ( null === $this->item ) { + return new Zend_Exception('Item is not set !'); + } + + if ($name == 'duplicate') { + if ( !array_key_exists('duplicate', $this->rules[$this->item]) ) { + switch ( strtolower($value) ) { + case 'day': + case 'jour': + $this->rules[$this->item]['duplicate'] = 'day'; + break; + case 'month': + case 'mois': + case 'period': + case 'periode': + $this->rules[$this->item]['duplicate'] = 'period'; + break; + } + } + } + } + + /** + * + */ + public function addSqlLogin() + { + $this->sql->where($this->table->info('name').".login IN ('".join("','", $this->login)."')"); + } + + public function addSqlDate() + { + $formatedDate = substr($this->date,0,4).'-'.substr($this->date,4,2); + $this->sql->where("dateHeure BETWEEN '".$formatedDate."-01 00:00:00' AND '".$formatedDate."-31 23:59:59'"); + } + + public function addSqlItem($file = false) + { + $rule = array(); + + if ( array_key_exists($this->item, $this->rules) ){ + $rule = $this->rules[$this->item]; + } + + // --- Group to deduplicate + if ( array_key_exists('duplicate', $rule) ) { + switch($rule['duplicate']) { + + case 'day': + if ($file === false ) { + $columns = array('COUNT(*) AS doublon', "DATE_FORMAT(dateHeure, '%Y%m%d') AS period"); + } else { + $columns = array( + 'LOWER('.$this->table->info('name').'.login) AS login', + 'page', + 'LPAD(siren, 9, 0) AS siren', + 'LPAD(nic, 5, 0) AS nic', + 'params', + 'raisonSociale', + 'cp', + 'ville', + 'dateHeure', + "DATE_FORMAT(dateHeure, '%Y%m%d') AS period", + 'COUNT(*) AS nbDoublon' + ); + } + $this->sql->from($this->table, $columns); + + if ( array_key_exists('group', $rule) ) { + $this->sql->group($rule['group']); + } else { + $this->sql->group(array('login', 'siren', 'page', 'raisonSociale', 'period')); + } + break; + + case 'period': + if ($file === false ) { + /*SELECT count(doublon) as NB FROM () test*/ + $columns = array('COUNT(*) AS doublon', "DATE_FORMAT(dateHeure, '%Y%m') AS period"); + } else { + $columns = array( + 'LOWER('.$this->table->info('name').'.login) AS login', + 'page', + 'LPAD(siren, 9, 0) AS siren', + 'LPAD(nic, 5, 0) AS nic', + 'params', + 'raisonSociale', + 'cp', + 'ville', + 'dateHeure', + "DATE_FORMAT(dateHeure, '%Y%m') AS period", + 'COUNT(*) AS nbDoublon' + ); + } + $this->sql->from($this->table, $columns); + + if ( array_key_exists('group', $rule) ) { + $this->sql->group($rule['group']); + } else { + $this->sql->group(array('login', 'siren', 'page', 'raisonSociale', 'period')); + } + + break; + + case 'none': + default: + if ($file === false ) { + $columns = array('dateHeure AS period'); + } else { + $columns = array( + 'LOWER('.$this->table->info('name').'.login) AS login', + 'page', + 'LPAD(siren, 9, 0) AS siren', + 'LPAD(nic, 5, 0) AS nic', + 'params', + 'raisonSociale', + 'cp', + 'ville', + 'dateHeure', + new Zend_Db_Expr('"none" as nbDoublon') + ); + } + $this->sql->from($this->table, $columns); + break; + } + } + + // --- No duplicate rules + if ( !array_key_exists('duplicate', $rule) || count($rule) == 0 ) { + if ($file === false ) { + $columns = array('dateHeure'); + } else { + $columns = array( + 'LOWER('.$this->table->info('name').'.login) AS login', + 'page', + 'LPAD(siren, 9, 0) AS siren', + 'LPAD(nic, 5, 0) AS nic', + 'params', + 'raisonSociale', + 'cp', + 'ville', + 'dateHeure', + new Zend_Db_Expr('"none" as nbDoublon') + ); + } + $this->sql->from($this->table, $columns); + } + + // --- Apply item parameters + if ( array_key_exists('params', $rule) && count($rule['params'])>0 ) { + foreach ( $rule['params'] as $param ) { + $this->sql->where($param); + } + } + + if ($file === true) { + $this->sql->setIntegrityCheck(false) + ->joinLeft('utilisateurs', 'utilisateurs.login='.$this->table->info('name').'.login', array('referenceParDefaut'), 'sdv1'); + } + + $this->sql->where('page=?', $this->item); + + $this->sql->order('dateHeure ASC'); + } + +} \ No newline at end of file diff --git a/src/Scores/Conso/Surveillances.php b/src/Scores/Conso/Surveillances.php new file mode 100644 index 0000000..113afcd --- /dev/null +++ b/src/Scores/Conso/Surveillances.php @@ -0,0 +1,165 @@ + array( + * 'params' => array of supplemental sql and where + * 'duplicate' => none, day, month, period (specified if this params must not change) + * ) + * @var array + */ + protected $rules = array ( + 'annonces' => array(), + 'insee' => array(), + 'bilans' => array(), + 'score' => array(), + 'actes' => array(), + 'dirigeants' => array(), + 'paiements' => array(), + 'liens' => array(), + 'privileges' => array(), + ); + + /** + * @var Zend_Db_Table_Abstract + */ + protected $table; + + /** + * + * @var Zend_Db_Select + */ + protected $sql; + + /** + * + * @param Zend_Db_Table_Abstract $table + */ + public function __construct(Zend_Db_Table_Abstract $table) + { + $this->table = $table; + $this->sql = $this->table->select(); + } + + /** + * Array of login + * @param array $login + */ + public function setLogin($login) + { + $this->login = $login; + } + + /** + * Date au format AAAAMM + * @param string $date + * @param boolean $stock + */ + public function setDate($date, $stock = false) + { + $this->date = $date; + $this->dateStock = $stock; + } + + /** + * Code de l'élément à compter + * @param string $item + */ + public function setItem($item) + { + $this->item = $item; + } + + /** + * Retourne la requete + * @return Zend_Db_Select + */ + public function getSqlRule() + { + $this->addSqlLogin(); + $this->addSqlItem(); + $this->addSqlDate(); + + return $this->sql; + } + + /** + * + * @param unknown $name + * @param unknown $value + */ + public function setOption($name, $value) + { + if ( null === $this->item ) { + return new Zend_Exception('Item is not set !'); + } + + if ($name == 'duplicate') { + if ( !array_key_exists('duplicate', $this->rules[$this->item]) ) { + switch ( strtolower($value) ) { + case 'day': + case 'jour': + $this->rules[$this->item]['duplicate'] = 'day'; + break; + case 'month': + case 'mois': + case 'period': + case 'periode': + $this->rules[$this->item]['duplicate'] = 'period'; + break; + } + } + } + } + + /** + * + */ + public function addSqlLogin() + { + $this->sql->where("login IN ('".join("','", $this->login)."')"); + } + + public function addSqlDate() + { + $formatedDate = substr($this->date,0,4).'-'.substr($this->date,4,2); + if ($this->dateStock === true) { + $this->sql->where("dateSuppr = 0"); + } else { + $this->sql->where("dateAjout BETWEEN '".$formatedDate."-01 00:00:00' AND '".$formatedDate."-31 23:59:59'"); + } + + } + + public function addSqlItem() + { + $this->sql->from($this->table, array('COUNT(*) AS NB')); + + $rule = $this->rules[$this->item]; + + //Apply item parameters + /*if ( array_key_exists('params', $rule) && count($rule['params'])>0 ) { + foreach ( $rule['params'] as $param ) { + $this->sql->where($param); + } + }*/ + $this->sql->where('source=?', $this->item); + + $this->sql->order('dateAjout ASC'); + } + +} \ No newline at end of file diff --git a/src/Scores/Courrier/Generate.php b/src/Scores/Courrier/Generate.php new file mode 100644 index 0000000..58b41bb --- /dev/null +++ b/src/Scores/Courrier/Generate.php @@ -0,0 +1,373 @@ +path = realpath($c->profil->path->shared).'/courrier/'; + + $this->info = new stdClass(); + $this->info->ref = $numCommande; + $this->info->refType = $type; + } + + public function setInfosCommande() + { + $typeCommande = $this->info->refType; + $id = $this->info->ref; + + if ($typeCommande == 'ac') { + + $commande = new Application_Model_Sdv1GreffeCommandesAc(); + $sql = $commande->select()->where('id = ?', $id); + $result = $commande->fetchRow($sql); + $typeDocument = 'actes'; + + $gM = new Application_Model_JoGreffesActes(); + $sql = $gM->select() + ->where('siren=?', $result->siren) + ->where('num_depot=?', $result->depotNum) + ->where('date_depot=?', $result->depotDate) + ->where('num_acte=?', $result->acteNum) + ->where('date_acte=?', $result->acteDate) + ->where('type_acte=?', $result->acteType); + $document = $gM->fetchRow($sql); + + $this->info->libDocument = $document->type_acte_libelle; + $this->info->dateDocument = $result->acteDate; + $this->info->dateDepot = $result->acteType; + + } else if ($typeCommande == 'bi') { + + $commande = new Application_Model_Sdv1GreffeCommandesBi(); + $sql = $commande->select()->where('id = ?', $id); + $result = $commande->fetchRow($sql); + $typeDocument = 'bilans'; + + $gM = new Application_Model_JoGreffesBilans(); + $sql = $gM->select() + ->where('siren=?', $result->siren) + ->where('date_cloture=?', $result->bilanCloture); + if ( $result->bilanType == 'sociaux' || $result->bilanType == '' ) { + $sql->where("(type_comptes='sociaux' OR type_comptes='')"); + } else { + $sql->where('type_comptes=?', $result->bilanType); + } + $sql->order('dateInsert DESC')->order('num_depot DESC')->limit(1); + $document = $gM->fetchRow($sql); + + + $this->info->libDocument = ''; + $this->info->dateDocument = $result->bilanCloture; + + } else if ($typeCommande == 'kb') { + + $commande = new Application_Model_Sdv1GreffeCommandesKb(); + $sql = $commande->select()->where('id = ?', $id); + $result = $commande->fetchRow($sql); + $typeDocument = 'kbis'; + if ($result->type == 'M') { + $this->info->type = 'MAIL'; + } + + } + //Assignation des variables + $this->info->siren = $result->siren; + $this->info->typeDocument = $typeDocument; + + } + + public function setInfosIdentite() + { + // @todo : How to include old framework + $insee = new Metier_Insee_MInsee(); + $reponse = $insee->getIdentiteEntreprise($this->info->siren); + + $this->info->commune = $reponse['codeCommune']; + $this->info->dept = $reponse['Dept']; + $this->info->siret = $reponse['Siret']; + $this->info->numRC = $reponse['NumRC']; + //$info->siren = substr($siren, 0, 3).' '.substr($siren, 3, 3).' '.substr($siren, 6, 3); + $this->info->nom = htmlspecialchars_decode($reponse['Nom'], ENT_QUOTES); + $this->info->adresse = htmlspecialchars_decode($reponse['Adresse'], ENT_QUOTES).' '; + if (empty($reponse['Adresse2']) == false) { + $info->adresse .= $reponse['Adresse2'].' '; + } + $this->info->adresse .= "\n".$reponse['CP'].' '.$reponse['Ville']; + } + + public function setInfosTribunal() + { + // Adresse du tribunal de commerce + // @todo : How to include old framework + $iBodacc = new Metier_Bodacc_MBodacc(); + $reponse = $iBodacc->getTribunauxParCommune($this->info->dept.$this->info->commune); + + $tribunalLib = $reponse[0]['triNom']; + if (preg_match('/(A|B|C|D)/i', $this->info->numRC)) { + $libTrib = ' RCS '. + preg_replace('/(^TC |^TI |^TGIcc |^TMX )/i', '', $tribunalLib); + } else if (preg_match('/(P)/i', $this->info->numRC)) { + $libTrib = ' RSAC '. + preg_replace('/(^TC |^TI |^TGIcc |^TMX )/i', '', $tribunalLib); + } + $this->info->tribunalCode = $reponse[0]['triCode']; + $this->info->libTrib = $libTrib; + + + $this->info->tribunal->Adr = strtoupper(preg_replace('/ +/',' ', + $reponse[0]['triAdrNum'].' '. + $reponse[0]['triAdrIndRep'].' '. + $reponse[0]['triAdrTypeVoie'].' '. + $reponse[0]['triAdrVoie'])); + $this->info->tribunal->AdrComp = strtoupper($reponse[0]['triAdrComp']); + $this->info->tribunal->CP = $reponse[0]['triCP']; + $this->info->tribunal->Ville = strtoupper($reponse[0]['triVille']); + } + + public function setTarifs() + { + $tarifs = new Application_Model_Sdv1GreffeTarifs(); + + $sql = $tarifs->select()->where('codeTribunal = ?', $this->info->tribunalCode) + ->where('type = ?', $this->info->typeDocument) + ->where('annee = ?', date('Y')); + $result = $tarifs->fetchAll($sql)->toArray(); + + if (count($result) == 0) { + echo 'Commande '.$this->info->ref.' - Pas de tarifs défini pour le tribunal '. + $this->info->tribunal->Nom.' ('.$this->info->tribunalCode.')'; + exit; + } + $this->info->prix = number_format($result[0]['prix'], 2, ',', ' '); + $this->info->enveloppe = $result[0]['enveloppe']; + } + + protected function setDestinataire() + { + // Destinataire + $this->info->destinataire = "REGISTRE DU COMMERCE - GREFFE\n". + $this->normaliseVoie(trim($this->info->tribunal->Adr))."\n". + $this->normaliseVoie($this->info->tribunal->AdrComp)."\n". + $this->info->tribunal->CP.' '.$this->info->tribunal->Ville."\n"; + } + + protected function setSujet() + { + // Type de document demandé (actes ou bilans pour l'instant) + // [un Kbis / l'état d'endettement / la copie de jugement de XXX en date du XXX] + if ($this->info->typeDocument == 'bilans') { + + $this->info->sujet = 'une copie du bilan au '. + substr($this->info->dateDocument, 6, 2).'/'. + substr($this->info->dateDocument, 4, 2).'/'. + substr($this->info->dateDocument, 0, 4); + + } else if ($this->info->typeDocument == 'actes') { + + $this->info->sujet = 'une copie de l\'acte '.$this->info->libDocument; + + $this->info->sujet .= ' en date du '. + substr($this->info->dateDocument, 6, 2).'/'. + substr($this->info->dateDocument, 4, 2).'/'. + substr($this->info->dateDocument, 0, 4); + + } else if ($this->info->typeDocument == 'kbis') { + + $this->info->sujet = 'un extrait RCS'; + + } + } + + protected function setSociete() + { + // Societe + $this->info->societe = $this->info->nom."\n".'( '.$this->info->siren.$this->info->libTrib.' )'."\n"; + $this->info->societe .= $this->normaliseVoie($this->info->adresse); + } + + protected function setMontant() + { + // Piece jointe et montant + if ($this->info->enveloppe) { + $this->info->montant = 'Ci-joint une enveloppe timbrée ainsi qu\'un '. + 'chèque d\'un montant de '.$this->info->prix. + ' euros en règlement de cette commande.'; + } else { + $this->info->montant = 'Ci-joint un chèque d\'un montant de '.$this->info->prix. + ' euros en règlement de cette commande.'; + } + } + + public function computeOdt() + { + $config = array( + 'ZIP_PROXY' => 'PhpZipProxy', + ); + + $odf = new Odf(__DIR__.'/Model/modeleLettreGreffe.odt', $config); + + $this->setInfosCommande(); + $this->setInfosIdentite(); + $this->setInfosTribunal(); + $this->setTarifs(); + $this->setDestinataire(); + $this->setSujet(); + $this->setSociete(); + $this->setMontant(); + + $file = $this->info->siren.'-'.$this->info->ref.'.odt'; + + $odf->setVars('destinataire', $this->info->destinataire, true, 'UTF-8'); + $odf->setVars('date', date('d/m/Y'), true, 'UTF-8'); + $odf->setVars('ref', $this->info->ref, true, 'UTF-8'); + $odf->setVars('sujet', $this->info->sujet, true, 'UTF-8'); + $odf->setVars('societe', $this->info->societe, true, 'UTF-8'); + $odf->setVars('montant', $this->info->montant, true, 'UTF-8'); + if ($this->info->type == 'MAIL') { + $odf->setVars('bymail',"ou à votre convenance par mail à : support@scores-decisions.com", true, 'UTF-8'); + } + $odf->saveToDisk($this->path.$file); + + if (file_exists($this->path.$file) == true) { + header('Content-Transfer-Encoding: none'); + header('Content-type: application/vnd.oasis.opendocument.text'); + header('Content-Length: '.filesize($this->path.$file)); + header('Content-MD5: '.base64_encode(md5_file($this->path.$file))); + header('Content-Disposition:attachment; filename="'.$file.'"'); + header('Cache-Control: private, max-age=0, must-revalidate'); + header('Pragma: public'); + ini_set('zlib.output_compression','0'); + echo file_get_contents($this->path.$file); + } else { + echo 'Erreur Génération du fichier'; + } + } + + public function computePdf() + { + $this->setInfosCommande(); + $this->setInfosIdentite(); + $this->setInfosTribunal(); + $this->setTarifs(); + $this->setDestinataire(); + $this->setSujet(); + $this->setSociete(); + $this->setMontant(); + + // initiate PDF + $pdf = new Scores_Courrier_Pdf(); + /* + * Définition des marges + * Left, Top et Right + * Dimension du logo d'entete : + **/ + $pdf->SetMargins(25, 50, 25); + $border = 0; + // add a page + $pdf->AddPage(); + $pdf->SetFont("times", "", 10); + + //Position de départ + $pdf->SetY(50); + + //Bloc Addresse destinataire + $largeur = 80; + $positionX = 105; + $pdf->MultiCell($largeur, 5, $this->info->destinataire, $border, 'L', 0, 1, $positionX); + + //Bloc Lieu, date + $date = date('d/m/Y'); + $txt = "Rambouillet, le $date"; + $positionY = $pdf->GetY()+5; + $pdf->MultiCell($largeur, 5, $txt, $border, 'L', 0, 1, $positionX, $positionY); + + //Bloc objet + $positionY = $pdf->GetY()+5; + $pdf->MultiCell(20, 5, "Objet:", $border, 'L', 0, 0, '', $positionY, true); + $pdf->MultiCell(0, 5, "Commande de document", $border, 'L', 0, 1, '', '', true); + //Bloc ref + $pdf->MultiCell(20, 5, "Réf.", $border, 'L', 0, 0, '', '', true); + $pdf->MultiCell(0, 5, $this->info->ref, $border, 'L', 0, 1, '', '', true);; + //Bloc titre + $positionY = $pdf->GetY()+5; + $pdf->MultiCell(0, 5, "Madame, Monsieur,", $border, 'L', 0, 1, '', $positionY, true); + + //Type de document demandé (actes ou bilans pour l'instant) + //[un Kbis / l'état d'endettement / la copie de jugement de XXX en date du XXX ] + $positionY = $pdf->GetY()+2; + $pdf->MultiCell(0, 5, "Nous vous prions de nous faire parvenir $this->info->sujet concernant la société:", $border, 'L', 0, 1, '', $positionY, true); + + //Bloc société + $positionY = $pdf->GetY()+2; + $pdf->MultiCell(0, 5, $this->info->societe, $border, 'L', 0, 1, '', $positionY, true); + + //Bloc pièce jointe + $positionY = $pdf->GetY()+5; + $pdf->MultiCell(0, 5, $this->info->montant, $border, 'L', 0, 1, '', $positionY, true); + + //Bloc intitulé adresse reception + $positionY = $pdf->GetY()+2; + $pdf->MultiCell(0, 5, + "Veuillez nous renvoyer le(s) document(s) par retour à l'adresse suivante:", + $border, 'L', 0, 1, '', $positionY, true); + + //Bloc adresse s&d + $positionY = ''; + $pdf->MultiCell(0, 5, + "SCORES ET DECISIONS" . "\n" . + "19 rue Clairefontaine". "\n" . + "78120 RAMBOUILLET" . "\n" + , $border, 'L', 0, 1, '', $positionY, true); + + if ($this->info->type == 'MAIL') { + $positionY = $pdf->GetY()+2; + $pdf->MultiCell(0, 5, + "ou à votre convenance par mail à : support@scores-decisions.com", + $border, 'L', 0, 1, '', $positionY, true); + } + + //Bloc formule politesse + $positionY = $pdf->GetY()+2; + $pdf->MultiCell(0, 5, "Dans l'attente de notre prochain échange, nous vous prions de recevoir, Madame, Monsieur, l'expression de nos plus sincères salutations.", $border, 'L', 0, 1, '', $positionY, true); + + $file = $this->info->siren.'-'.$this->info->ref.'.pdf'; + $pdf->Output($this->path.$file, 'F'); + if(file_exists($path.$file)) + { + $content_type = 'application/pdf'; + header('Content-Transfer-Encoding: none'); + header('Content-type: '.$content_type.''); + header('Content-Length: '.filesize($this->path.$file)); + header('Content-MD5: '.base64_encode(md5_file($this->path.$file))); + header('Content-Disposition: attachment, filename="'.$file.'"'); + header('Cache-Control: private, max-age=0, must-revalidate'); + header('Pragma: public'); + ini_set('zlib.output_compression','0'); + echo file_get_contents($this->path.$file); + } + } + + protected function normaliseVoie($txt) + { + $replace_pairs = array( + 'BD ' => 'BOULEVARD ', + 'BVD ' => 'BOULEVARD ', + 'AV ' => 'AVENUE ', + 'AVE ' => 'AVENUE ', + 'PL ' => 'PLACE ', + 'PLA ' => 'PLACE ', + 'PLAC ' => 'PLACE ', + 'ESP ' => 'ESP ', + 'RTE ' => 'ROUTE ', + 'ST ' => 'SAINT ', + 'STE ' => 'SAINTE ', + 'QU ' => 'QUAI ' + ); + return strtr($txt, $replace_pairs); + } +} \ No newline at end of file diff --git a/src/Scores/Courrier/Model/modele.odt b/src/Scores/Courrier/Model/modele.odt new file mode 100644 index 0000000..f3f65a9 Binary files /dev/null and b/src/Scores/Courrier/Model/modele.odt differ diff --git a/src/Scores/Courrier/Model/modele.pdf b/src/Scores/Courrier/Model/modele.pdf new file mode 100644 index 0000000..f2a5c48 Binary files /dev/null and b/src/Scores/Courrier/Model/modele.pdf differ diff --git a/src/Scores/Courrier/Model/modeleLettreGreffe.odt b/src/Scores/Courrier/Model/modeleLettreGreffe.odt new file mode 100644 index 0000000..9900c4d Binary files /dev/null and b/src/Scores/Courrier/Model/modeleLettreGreffe.odt differ diff --git a/src/Scores/Courrier/Pdf.php b/src/Scores/Courrier/Pdf.php new file mode 100644 index 0000000..c118c90 --- /dev/null +++ b/src/Scores/Courrier/Pdf.php @@ -0,0 +1,22 @@ +_tplIdx)) { + $file = __DIR__.'/Model/modele.pdf'; + $this->setSourceFile($file); + $this->_tplIdx = $this->importPage(1); + } + $this->useTemplate($this->_tplIdx); + } + + function Footer() { + } +} \ No newline at end of file diff --git a/src/Scores/Extract/Dict.php b/src/Scores/Extract/Dict.php new file mode 100644 index 0000000..3a5cd64 --- /dev/null +++ b/src/Scores/Extract/Dict.php @@ -0,0 +1,680 @@ + array( + 'lib' => "SD : Identifiant - Etablissement", + 'help' => "Identifiant interne propre à SD, usage restreint", + 'columns' => array( + 'id' => 'Identifiant Interne', + ) + ), + 'source' => array( + 'lib' => "SD : Source" + //@todo : Yoann + ), + 'triCode' => array( + 'lib' => "?? : Code BODACC du Tribunal - Etablissement", + 'help' => "Code BODACC du tribunal, voir la table jo.tribunaux (à confirmer, sortir triNom) +
Entreprise exclusivement INSEE pas de code tribunal", + 'columns' => array( + 'triCode' => '' + ) + ), + 'autre_id' => array( + 'lib' => "Autre ID (SIREN ou WALDEC)", + 'help' => "Doublon SIREN (source RNCS) ou WALDEC (source JOAFE) si association", + 'columns' => array( + 'autre_id' => "Autre ID (SIREN ou WALDEC)", + ), + ), + 'actif' => array( + 'lib' => 'SD : ACTIF', + //@todo : Yoann + ), + 'siege' => array( + 'lib' => "SD : Siège ou Etablissement", + 'help' => "Valeur : 0 les établissements Secondaires (source INSEE), + 1 l'établissement Siège de l'entreprise (source INSEE) ; + 2 notion RNCS désignant l'établissement Principal qui n'est pas obligatoirement le siège + http://www.greffe-tc-caen.fr/rcs_etabs.php", + ), + 'raisonSociale' => array( + 'lib' => "SD : Raison Sociale", + 'help' => "Regle de composition de la donnée" + ), + 'enseigne' => array( + 'lib' => "SD : Enseigne", + 'help' => "Regle de composition de la donnée" + ), + 'sigle' => array( + 'lib' => "SD : Sigle", + 'help' => "Regle de composition de la donnée" + ), + 'marques' => array( + 'lib' => "SD : Marques déposées", + 'help' => "Chaine de caractère assemblé - Regle de composition de la donnée" + ), + 'adr_num' => array( + 'lib' => "SD : Adresse Numéro dans la voie - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'adr_btq' => array( + 'lib' => "SD : Adresse Bis/Ter/etc.. - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'adr_typeVoie' => array( + 'lib' => "SD : Adresse Type de voie - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'adr_libVoie' => array( + 'lib' => "SD : Adresse Libellé de la voie - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'adr_comp' => array( + 'lib' => "SD : Adresse Complément - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'adr_cp' => array( + 'lib' => "SD : Adresse Code Postal - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'adr_ville' => array( + 'lib' => "SD : Adresse Ville - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'adr_dep' => array( + 'lib' => "SD : Adresse Département - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'adr_codeCom' => array( + 'lib' => "SD : Adresse Code Commune étab - Etablissement", + 'help' => "Regle de composition de la donnée" + ), + 'telEtab' => array( + 'lib' => "Téléphone" + ), + 'faxEtab' => array( + 'lib' => "Télécopie" + ), + 'cj' => array( + 'lib' => "Forme juridique" + ), + 'capital' => array( + 'lib' => "Capital" + ), + 'capitalDev' => array( + 'lib' => "Devise du capital" + ), + 'ape_etab' => array( + 'lib' => "SD : NAF Etablissement", + 'help' => "Code NAF 5 positions", + 'columns' => array( + 'ape_etab' => "SD : NAF Etablissement", + ), + ), + 'ape_entrep' => array( + 'lib' => "SD : NAF Entreprise", + 'help' => "Code NAF 5 positions", + 'columns' => array( + 'ape_entrep' => "SD : NAF Entreprise", + ), + ), + 'NaceEtab' => array( + 'lib' => "SD : NACE Etablissement", + 'help' => "", + 'columns' => array( + 'NaceEtab' => "SD : NACE Etablissement", + 'NaceEtabLib' => "SD : NACE Etablissement", + ), + ), + 'NaceEn' => array( + 'lib' => "SD : NACE Entreprise", + 'help' => "", + 'columns' => array( + 'NaceEn' => "SD : NACE Entreprise", + 'NaceEnLib' => "SD : NACE Entreprise", + ), + ), + 'SiretEnBase' => array( + 'lib' => "Vérifier la présence en base du siren/siret" + ), + 'etActifInsee' => array( + 'lib' => "Insee : Actif" + ), + 'nomInsee' => array( + 'lib' => 'Insee : Raison Sociale' + ), + 'nomInsee2' => array( + 'lib' => 'Insee : Raison Sociale (suite)' + ), + 'sigleInsee' => array( + 'lib' => 'Insee : Sigle' + ), + 'enseigneInsee' => array( + 'lib' => 'Insee : Enseigne' + ), + 'adrNumVoieInsee' => array( + 'lib' => 'Insee : Adresse - Numéro dans la voie' + ), + 'adrBtqInsee' => array( + 'lib' => 'Insee : Adresse - Bis/Ter/etc' + ), + 'adrTypeVoieInsee' => array( + 'lib' => 'Insee : Adresse - Type de voie' + ), + 'adrVoieInsee' => array( + 'lib' => 'Insee : Adresse - Libellé de la voie' + ), + 'adrCompInsee' => array( + 'lib' => 'Insee : Adresse - Complément' + ), + 'adrCPInsee' => array( + 'lib' => 'Insee : Adresse - Code Postal' + ), + 'adrVilleInsee' => array( + 'lib' => 'Insee : Adresse - Commune' + ), + 'adrDistSPInsee' => array( + 'lib' => 'Insee : Adresse - Distribution spéciale' + ), + 'CjInsee' => array( + 'lib' => "Insee : Forme juridique de l'entreprise" + ), + 'nafEnInsee' => array( + 'lib' => "Insee : NAF de l'entreprise" + ), + 'nafEtInsee' => array( + 'lib' => "Insee : NAF de l'etablissement" + ), + 'APRM' => array( + 'lib' => "Insee : APRM" + ), + 'ACTIVNAT' => array( + 'lib' => "Insee : ACTIVNAT" + ), + 'ORIGINE' => array( + 'lib' => "Insee : Origine de création de l'établissement" + ), + 'MODET' => array( + 'lib' => "Insee : MODET" + ), + 'EXPLET' => array( + 'lib' => 'Insee : EXPLET' + ), + 'LIEUACT' => array( + 'lib' => "Insee : LIEUACT" + ), + 'ACTISURF' => array( + 'lib' => "Insee : ACTISURF" + ), + 'DEFET' => array( + 'lib' => "Insee : Année MAJ de l'effectif de l'établissement" + ), + 'MODEN' => array( + 'lib' => "Insee : MODEN" + ), + 'PRODPART' => array( + 'lib' => "Insee : PRODPART" + ), + 'EXPLEN' => array( + 'lib' => "Insee : EXPLEN" + ), + 'DEFEN' => array( + 'lib' => "Insee : Année MAJ de l'effectif de l'entreprise" + ), + 'MONOREG' => array( + 'lib' => "Insee : Mono-régionalité" + ), + 'REGIMP' => array( + 'lib' => "Insee : Principale région d'implantation" + ), + 'MONOACT' => array( + 'lib' => "Insee : Mono-activité" + ), + 'DCREN' => array( + 'lib' => "Insee : Date de création de l'entreprise" + ), + 'SIEGE' => array( + 'lib' => "Insee : Siege", + 'help' => "Qualité de siege ou non de l'établissement", + 'columns' => array( + 'SIEGE' => 'Insee : Siege', + ) + ), + 'AUXILT' => array( + 'lib' => "Insee : Auxiliarité" + ), + 'SAISONAT' => array( + 'lib' => "Insee : Saisonalité" + ), + 'CIVILITE' => array( + 'lib' => "Insee : Civilité" + ), + 'TCA' => array( + 'lib' => "Insee : Tranche de chiffre d'affaire" + ), + 'TCAEXP' => array( + 'lib' => "Insee : Tranche de chiffre d'affaire à l'export" + ), + 'EFF_ENT' => array( + 'lib' => "Insee : Effectif de l'entreprise" + ), + 'DCRET' => array( + 'lib' => "Insee : Date de création de l'établissement" + ), + 'TEFF_ENT' => array( + 'lib' => "Insee : Tranche effectif entreprise", + ), + 'ADR_DEP' => array( + 'lib' => "Insee : Adresse - Département", + 'help' => "Département de localisation de l'établissement (2 caractères)", + 'columns'=> array( + 'ADR_DEP' => 'Insee : Departement', + ), + ), + 'ADR_COM' => array( + 'lib' => "Insee : Commune de localisation de l'établissement", + 'help' => "(3 chiffres)", + 'columns' => array( + 'ADR_COM' => "Insee : Code commune", + ), + ), + 'EFF_ET' => array( + 'lib' => "Insee : Effectif de l'établissement" + ), + 'TEFF_ET' => array( + 'lib' => "Insee : Tranche effectif etablissement", + ), + 'CODEVOIE' => array( + 'lib' => "Insee : Code voie", + 'help' => "Code Rivoli / Ex Fantoir", + ), + 'dateMajInsee' => array( + 'lib' => "Insee : Date de la dernière mise à jour" + ), + 'insRPET' => array( + 'lib' => "Insee : RPET" + ), + 'insDEPCOMEN' => array( + 'lib' => "Insee : Code commune siège" + ), + 'insRPEN' => array( + 'lib' => "Insee : RPEN" + ), + 'insARRONET' => array( + 'lib' => "Insee : Arrondissement de l'établissement" + ), + 'insCTONET' => array( + 'lib' => "Insee : Canton de l'établissement" + ), + 'insTCD' => array( + 'lib' => "Insee : Tranche de commune détaillé" + ), + 'insZEMET' => array( + 'lib' => "Insee : ZEMET" + ), + 'insDU' => array( + 'lib' => "Insee : DU" + ), + 'insTU' => array( + 'lib' => "Insee : TU" + ), + 'insUU' => array( + 'lib' => "Insee : UU" + ), + 'insMMINTRET' => array( + 'lib' => "Insee : MMINTRET", + ), + 'insMMINTREN' => array( + 'lib' => "Insee : MMINTREN", + ), + 'insRECME' => array( + 'lib' => "Insee : RCEM" + ), + 'insEAEANT' => array( + 'lib' => "Insee : EAEANT" + ), + 'insEAEAPET' => array( + 'lib' => "Insee : EAEAPET" + ), + 'insEAESEC1T' => array( + 'lib' => "Insee : EAESEC1T" + ), + 'insEAESEC2T' => array( + 'lib' => "Insee : EAESEC2T" + ), + 'insEAEANN' => array( + 'lib' => "Insee : EAEANN" + ), + 'insEAEAPEN' => array( + 'lib' => "Insee : EAEAPEN" + ), + 'insEAESEC1N' => array( + 'lib' => "Insee : EAESEC1N" + ), + 'insEAESEC2N' => array( + 'lib' => "Insee : EAESEC2N" + ), + 'insEAESEC3N' => array( + 'lib' => "Insee : EAESEC3N" + ), + 'insEAESEC4N' => array( + 'lib' => "Insee : EAESEC4N" + ), + 'dateMajNotice' => array( + 'lib' => "Insee : Date de la dernière MAJ notice" + ), + 'NBETEXPL' => array( + 'lib' => "Insee : Nombre d'établissement exploitant actif" + ), + 'entActiveRncs' => array( + 'lib' => "RNCS : Actif - Entreprise" + ), + 'numRC2' => array( + 'lib' => "RNCS : Numéro RC" + ), + 'raisonSocialeRncs' => array( + 'lib' => "RNCS : Raison Sociale" + ), + 'sigleRncs' => array( + 'lib' => "RNCS : Sigle" + ), + 'dateNaiss' => array( + 'lib' => "RNCS : Date Naissance PP" + ), + 'lieuNaiss' => array( + 'lib' => "RNCS : Lieu Naissance PP" + ), + 'nationalite' => array( + 'lib' => "RNCS : Nationalité PP" + ), + 'pays' => array( + 'lib' => "RNCS : Pays" + ), + 'nafEnRncs' => array( + 'lib' => "RNCS : NAF Entrepise" + ), + 'cjRncs' => array( + 'lib' => "RNCS : Forme juridique" + ), + 'dateImma' => array( + 'lib' => "RNCS : Date Immatriculation" + ), + 'dateRad' => array( + 'lib' => "RNCS : Date de radiation" + ), + 'capitalType' => array( + 'lib' => "RNCS : Type de capital" + ), + 'dateMajEnRncs' => array( + 'lib' => "RNCS : Date MAJ Entreprise" + ), + 'etActifRncs' => array( + 'lib' => "RNCS : Actif" + ), + 'siegeRncs' => array( + 'lib' => "RNCS : Siège" + ), + 'enseigneRncs' => array( + 'lib' => "RNCS : Enseigne" + ), + 'nomCommercialRncs' => array( + 'lib' => "RNCS : Nom Commercial" + ), + 'adrNumVoieRncs' => array( + 'lib' => "RNCS : Numéro" + ), + 'adrIndRepRncs' => array( + 'lib' => "RNCS : Adresse - Numéro" + ), + 'adrLibVoieRncs' => array( + 'lib' => "RNCS : Adresse - Bis/Ter/etc" + ), + 'adrTypeVoieRncs' => array( + 'lib' => "RNCS : Adresse - Type de la voie" + ), + 'adrVoieRncs' => array( + 'lib' => "RNCS : Adresse - Libellé de la voie" + ), + 'cpRncs' => array( + 'lib' => "RNCS : Adresse - Code postal" + ), + 'villeRncs' => array( + 'lib' => "RNCS : Adresse - Ville" + ), + 'adrCompRncs' => array( + 'lib' => "RNCS : Adresse - Complément" + ), + 'nafEtRncs' => array( + 'lib' => "RNCS : NAF Etablissement" + ), + 'dateMajEtRncs' => array( + 'lib' => "RNCS : Date MAJ établissement" + ), + 'isin' => array( + 'lib' => "Code ISIN (société en bourse)" + ), + 'tel' => array( + + ), + 'fax' => array(), + 'web' => array(), + 'mail' => array(), + 'nicSiege'=> array( + 'lib' => "NIC du siège (si nic absent)" + ), + 'tva'=> array( + 'lib' => "Numéro de TVA (non validés)" + ), + 'dateFermetureEn'=> array(), + 'dateFermetureEt'=> array(), + 'activite'=> array(), + 'situationJuridique'=> array(), + 'indiScore'=> array( + 'lib' => 'SD : indiScore', + ), + 'AdresseNormalise' => array( + 'lib' => 'AdresseNormalise', + 'columns' => array( + 'AdresseL1_NOM' => '', + 'AdresseL2_NOM2' => '', + 'AdresseL3_ADRCOMP' => '', + 'AdresseL4_VOIE' => '', + 'AdresseL5_DISTSP' => '', + 'AdresseL6_POST' => '', + 'AdresseL7_PAYS' => '', + ), + ), + 'AdresseNormaliseInsee' => array( + 'lib' => 'AdresseNormaliseInsee', + 'columns' => array( + 'L1_NOM' => 'L1_NOMEN', + 'L2_NOM2' => 'L2_COMP', + 'L3_ADRCOMP' => 'L3_CADR', + 'L4_VOIE' => 'L4_VOIE', + 'L5_DISTSP' => 'L5_DISP', + 'L6_POST' => 'L6_POST', + 'L7_PAYS' => 'L7_ETRG', + ), + ), + 'SiretSuc' => array( + 'lib' => 'INSEE : Siret Successeur', + 'help' => "", + 'columns' => array( + 'SiretSuc' => '', + 'SiretSucNbDem' => '', + 'SiretSucSiege' => '', + 'SiretSucActif' => '', + 'SiretSucCodeEve' => '', + 'SiretSucDateEve' => '', + 'SiretSucOrigine' => '', + ) + ), + 'dirigeant'=> array(), + 'bilanN'=> array('values'=>''), + 'bilanN1'=> array('values'=>''), + 'bilanN2'=> array('values'=>''), + 'annonces'=> array('values'=>''), + 'privilege' => array(), + 'GPS' => array( + 'lib' => 'SD : Coordonnées GPS - Etablissement', + 'help' => "", + 'columns' => array( + 'latitude' => "Latitude en degrés et décimales de degrés", + 'longitude' => "Longitude en degrés et décimales de degrés", + 'altitude' => "Altitude en mètres", + 'precis' => "Précision du géocodage (de 0=non géocodé à 8/9=géocodage à l'adresse)", + ) + ), + 'TelOrder' => array( + 'lib' => 'Telephone priorisé', + 'help' => "", + 'columns' => array() + ), + 'LienHead' => array( + 'lib' => 'Tête de lien financier', + 'help' => "", + 'columns' => array() + ), + 'LienHeadUltimate' => array( + 'lib' => 'Tête de lien ultime', + 'help' => "", + 'columns' => array() + ), + 'ZonePrioritaire' => array( + 'lib' => 'Zone Prioritaire', + 'help' => "", + 'columns' => array() + ), + 'AdresseDom'=> array( + 'lib' => 'AdresseDom', + 'help' => "", + 'columns' => array() + ), + 'Iris'=> array( + 'lib' => 'Iris', + 'help' => "", + 'columns' => array() + ), + ); + + public function __construct() + { + } + + //Vérifie que les entêtes du fichier sont correct + public function checkFileEntete($pathFile) + { + $posKeySiren = $posKeySiret = $posKeyNic = false; + $row = 0; + $error = array(); + if (($handle = fopen($pathFile, 'r')) !== false) { + while (($data = fgetcsv($handle, 0, ',', '"')) !== false) { + $num = count($data); + //Traitement de la première ligne + if ($row == 0) { + for ($c=0; $c < $num; $c++) { + //Détection clé importante + switch (strtolower($data[$c])) { + case 'siren': + $posKeySiren = $c; + break; + case 'nic': + $posKeyNic = $c; + break; + case 'siret': + $posKeySiret = $c; + break; + case 'ref': + //Clé réference + break; + default: + //Détection clé pour enrichissement + $values = false; + if (preg_match('/(.*)\((.*)\)/', $key, $matches)) { + $key = $matches[1]; + $values = $matches[2]; + } else { + $key = $data[$c]; + } + if (!array_key_exists($key, $this->tabDico)) { + $error[] = "Clé enrichissement $key incorrect"; + } + break; + } + } + if ($posKeySiren!==false && $posKeyNic!==false && $posKeySiret!==false || $posKeySiren!==false && $posKeySiret!==false) { + $error[] = "Trop de clé!"; + } + if ($posKeySiren===false && $posKeySiret===false) { + $error[] = "Aucune clé détecté!"; + } + } else { + //Erreur dans les entetes, on arrete + if (count($error)>0) { + break; + } + } + $row++; + } + fclose($handle); + if (count($error)>0) { + return $error; + } + return $row-1; + } + return false; + } + + //Retourne les clés de dictionnaire pour les données d'enrichissement + public function getDico() + { + return $this->tabDico; + } + + //Retourne le libellé pour chaque clés du dictionnaire + public function getDicoLib($key) + { + //Si () alors traitement champs spécial + if (preg_match('/(.*)\((.*)\)/', $key, $matches)) { + $key = $matches[1]; + } + + if (array_key_exists($key, $this->tabDico)) { + $element = $this->tabDico[$key]; + if (array_key_exists('lib', $element) && !empty($element['lib'])) { + return $element['lib']; + } + return $key; + } + return false; + } + + //Retourne le texte d'aide + public function getDicoHelp($key) + { + if (array_key_exists($key, $this->tabDico)) { + $element = $this->tabDico[$key]; + if (array_key_exists('help', $element) && !empty($element['help'])) { + return $element['help']; + } + return ''; + } + return false; + } + + //Retourne les colonnes de sortie + public function getDicoColumns($key) + { + if (array_key_exists($key, $this->tabDico)) { + $element = $this->tabDico[$key]; + if (array_key_exists('columns', $element)) { + return $element['columns']; + } + return array(); + } + return false; + } +} diff --git a/src/Scores/Locale/String.php b/src/Scores/Locale/String.php new file mode 100644 index 0000000..e0c61b3 --- /dev/null +++ b/src/Scores/Locale/String.php @@ -0,0 +1,88 @@ +enabled) { + $this->start = microtime(true); + $this->query = array('sql' => $sql, 'params' => $params, 'types' => $types, 'executionMS' => 0); + } + } + + /** + * {@inheritdoc} + */ + public function stopQuery() + { + if ($this->enabled) { + $time = microtime(true) - $this->start; + $this->total+= $time; + $this->query['executionTotal'] = $this->total; + $this->query['executionMS'] = $time; + if ($this->nb == 0) { + file_put_contents('logger.log', print_r($this->query, 1)); + } else { + file_put_contents('logger.log', print_r($this->query, 1), FILE_APPEND); + } + $this->nb++; + } + } +} diff --git a/src/Scores/Mail/Method.php b/src/Scores/Mail/Method.php new file mode 100644 index 0000000..a58a26d --- /dev/null +++ b/src/Scores/Mail/Method.php @@ -0,0 +1,129 @@ + smtp, sendmail, file + * Si method = smtp + * (host => IP, dns) + * + * Activer l'authentification + * (auth => login, plain, ....) + * (username => ) + * (password => ) + */ + public function __construct($config = null) + { + if ($config === null) { + $c = Zend_Registry::get('config'); + $this->config = $c->profil->mail; + } else { + $this->config = $config; + } + + $this->_charset = 'ISO-8859-15'; + + // --- Configuration du transport SMTP + if ($this->config->method == 'smtp') { + $config = array(); + + if (isset($this->config->auth)) { + $config['auth'] = $this->config->auth; + if (isset($this->config->username)) { + $config['username'] = $this->config->username; + } + if (isset($this->config->password)) { + $config['password'] = $this->config->password; + } + } + + if (isset($this->config->port)) { + $config['port'] = $this->config->port; + } + + $tr = new Zend_Mail_Transport_Smtp($this->config->host, $config); + } + + // --- Configuration transport Sendmail + if ($this->config->method == 'sendmail') { + $tr = new Zend_Mail_Transport_Sendmail(); + } + + // --- Configuration transport File + if ($this->config->method == 'file') { + $tr = new Zend_Mail_Transport_File(array('callback' => array($this, 'recipientFilename'))); + } + + $this->transport = $tr; + } + + /** + * Champ From en fonction de la clé de configuration + * @param string $configKey + */ + public function setFromKey($configKey) + { + $email = $this->config->email->$configKey; + $this->setFrom($email, ucfirst($configKey)); + } + + /** + * Champ To en fonction de la clé de configuration + * @param string $configKey + */ + public function addToKey($configKey) + { + $email = $this->config->email->$configKey; + $this->addTo($email, ucfirst($configKey)); + } + + /** + * Définit le sujet de l'email + * @param string $texte + */ + public function setSubjectC($texte = '') + { + $this->setSubject($this->txtConvert($texte)); + } + + /** + * Définit le corps de l'email au format texte + * @param string $texte + */ + public function setBodyTextC($texte = '') + { + $this->setBodyText($this->txtConvert($texte)); + } + + /** + * Définit le corps de l'email au format html + * @param string $html + */ + public function setBodyHtmlC($html = '') + { + $this->setBodyHtml($this->txtConvert($html)); + } + + /** + * Envoi de l'emai + */ + public function execute() + { + return $this->send($this->transport); + } + + //We suppose that character encoding of strings is UTF-8 on PHP script. + protected function txtConvert($string) + { + return mb_convert_encoding($string, 'ISO-8859-1', 'UTF-8'); + } + + protected function recipientFilename($transport) + { + return $transport->recipients . '_' . mt_rand() . '.tmp'; + } +} diff --git a/src/Scores/Stat/Op.php b/src/Scores/Stat/Op.php new file mode 100644 index 0000000..f3650ba --- /dev/null +++ b/src/Scores/Stat/Op.php @@ -0,0 +1,237 @@ + array( + array( + 'table' => 'jo.bodacc_detail', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'annonce' => array( + array( + 'table' => 'jo.annonces', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idSaisie={id}', + 'source IN ("JS","TS","GC","PC") AND (dateInsert BETWEEN "{begin}" AND "{end}" OR dateUpdate BETWEEN "{begin}" AND "{end}")', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'asso' => array( + array( + 'table' => 'jo.asso', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'columnsCsv' => array('*'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ) + ), + 'dir' => array( + array( + 'table' => 'jo.rncs_dirigeants', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'columnsCsv' => array('*'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'cac' => array( + array( + 'table' => 'jo.bodacc_dirigeants', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'columnsCsv' => array('*'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'boamp' => array( + array( + 'table' => 'jo.boamp_lots', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + array( + 'table' => 'jo.boamp_detail', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'client' => array( + array( + 'table' => 'jo.sirenage_clients', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'marque' => array( + array( + 'table' => 'bopi.marques', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'columnsCsv' => array('*'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'lien' => array( + array( + 'table' => 'jo.liens2', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idInsert={id} AND dateInsert BETWEEN "{begin}" AND "{end}" OR + idUpdate={id} AND dateUpdate BETWEEN "{begin}" AND "{end}" OR + idSuppr={id} AND dateSuppr BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + array( + 'table' => 'jo.liensRef', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idInsert={id} AND dateInsert BETWEEN "{begin}" AND "{end}" OR + idUpdate={id} AND dateUpdate BETWEEN "{begin}" AND "{end}" OR + idSuppr={id} AND dateSuppr BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + array( + 'table' => 'jo.liensDoc', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idInsert={id}', + 'dateInsert BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'bilansaisie' => array( + array( + 'table' => 'jo.bilans_user', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idUtilisateur={id} AND dateAction BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + 'tourisme' => array( + array( + 'table' => 'jo.tourisme', + 'columnsTotal' => array('COUNT(*) as Nb'), + 'where' => array( + 'idSirenage={id}', + 'dateUpdate BETWEEN "{begin}" AND "{end}"', + ), + 'group' => array(), + 'order' => array(), + ), + ), + ); + + protected $category; + protected $user; + protected $begin; + protected $end; + protected $db; + + public function __construct($category, $user, $dateBegin, $dateEnd = null) + { + $this->category = $category; + $this->user = $user; + $this->begin = $dateBegin.' 00:00:00'; + $this->end = $dateBegin.' 23:59:59'; + if ($dateEnd !== null) { + $this->end = $dateEnd.' 23:59:59'; + } + + $this->db = Zend_Db_Table_Abstract::getDefaultAdapter(); + } + + public function total() + { + $config = $this->sql[$this->category]; + + $nb = 0; + foreach ($config as $param) { + $sql = $this->db->select()->from($param['table'], $param['columnsTotal']); + foreach ($param['where'] as $where) { + $where = preg_replace('/\{id\}/', $this->user, $where); + $where = preg_replace('/\{begin\}/', $this->begin, $where); + $where = preg_replace('/\{end\}/', $this->end, $where); + $sql->where($where); + } + $this->db->setFetchMode(Zend_Db::FETCH_OBJ); + $result = $this->db->fetchRow($sql); + if ($result !== null) { + $nb = $nb + $result->Nb; + } + } + + return $nb; + } + + public function csv() + { + $config = $this->sql[$this->category]; + + foreach ($config as $param) { + $sql = $this->db->select()->from($param['table'], $param['columnsCSV']); + foreach ($param['where'] as $where) { + $where = preg_replace('/\{id\}/', $this->user, $where); + $where = preg_replace('/\{begin\}/', $this->begin, $where); + $where = preg_replace('/\{end\}/', $this->end, $where); + $sql->where($where); + } + $this->db->setFetchMode(Zend_Db::FETCH_OBJ); + $result = $this->db->fetchRow($sql); + if ($result !== null) { + + } + } + + } + +} \ No newline at end of file diff --git a/src/Scores/Surveillance/File.php b/src/Scores/Surveillance/File.php new file mode 100644 index 0000000..a5e065e --- /dev/null +++ b/src/Scores/Surveillance/File.php @@ -0,0 +1,90 @@ +delimiter = ','; + if (null !== $delimiter) { + $this->delimiter = $delimiter; + } + } + + /** + * Check file header + * @param string $file + * @return boolean|array + */ + public function checkHeader($file) + { + $row = 0; + $error = array(); + if (($handle = fopen($file, 'r')) !== false) { + while (($data = fgetcsv($handle, 0, $this->delimiter, '"')) !== false) { + $num = count($data); + //First line + if ($row == 0) { + //Detect key + foreach ( $this->header as $key ) { + for ( $c=0; $c < $num; $c++ ) { + if ( $key == strtolower($data[$c]) ) { + $this->position[$key] = $c; + } + } + } + break; + } + $row++; + } + fclose($handle); + } + if ( count($this->position) > 0 ) { + $tabKey = array_keys($this->position); + foreach( $this->headerRequired as $key) { + if ( !in_array($key, $tabKey) ) { + return false; + } + } + return $tabKey; + } + return false; + } + + public function setCmd(){} + + public function loadLines(){} + + + +} \ No newline at end of file diff --git a/src/Scores/Upload/Handler.php b/src/Scores/Upload/Handler.php new file mode 100644 index 0000000..b3c50aa --- /dev/null +++ b/src/Scores/Upload/Handler.php @@ -0,0 +1,1393 @@ + 'The uploaded file exceeds the upload_max_filesize directive in php.ini', + 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form', + 3 => 'The uploaded file was only partially uploaded', + 4 => 'No file was uploaded', + 6 => 'Missing a temporary folder', + 7 => 'Failed to write file to disk', + 8 => 'A PHP extension stopped the file upload', + 'post_max_size' => 'The uploaded file exceeds the post_max_size directive in php.ini', + 'max_file_size' => 'File is too big', + 'min_file_size' => 'File is too small', + 'accept_file_types' => 'Filetype not allowed', + 'max_number_of_files' => 'Maximum number of files exceeded', + 'max_width' => 'Image exceeds maximum width', + 'min_width' => 'Image requires a minimum width', + 'max_height' => 'Image exceeds maximum height', + 'min_height' => 'Image requires a minimum height', + 'abort' => 'File upload aborted', + 'image_resize' => 'Failed to resize image' + ); + + protected $image_objects = array(); + + public function __construct($options = null, $initialize = true, $error_messages = null) { + $this->response = array(); + $this->options = array( + 'script_url' => $this->get_full_url().'/'.$this->basename($this->get_server_var('SCRIPT_NAME')), + 'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/', + 'upload_url' => $this->get_full_url().'/files/', + 'input_stream' => 'php://input', + 'user_dirs' => false, + 'mkdir_mode' => 0755, + 'param_name' => 'files', + // Set the following option to 'POST', if your server does not support + // DELETE requests. This is a parameter sent to the client: + 'delete_type' => 'DELETE', + 'access_control_allow_origin' => '*', + 'access_control_allow_credentials' => false, + 'access_control_allow_methods' => array( + 'OPTIONS', + 'HEAD', + 'GET', + 'POST', + 'PUT', + 'PATCH', + 'DELETE' + ), + 'access_control_allow_headers' => array( + 'Content-Type', + 'Content-Range', + 'Content-Disposition' + ), + // By default, allow redirects to the referer protocol+host: + 'redirect_allow_target' => '/^'.preg_quote( + parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_SCHEME) + .'://' + .parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_HOST) + .'/', // Trailing slash to not match subdomains by mistake + '/' // preg_quote delimiter param + ).'/', + // Enable to provide file downloads via GET requests to the PHP script: + // 1. Set to 1 to download files via readfile method through PHP + // 2. Set to 2 to send a X-Sendfile header for lighttpd/Apache + // 3. Set to 3 to send a X-Accel-Redirect header for nginx + // If set to 2 or 3, adjust the upload_url option to the base path of + // the redirect parameter, e.g. '/files/'. + 'download_via_php' => false, + // Read files in chunks to avoid memory limits when download_via_php + // is enabled, set to 0 to disable chunked reading of files: + 'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB + // Defines which files can be displayed inline when downloaded: + 'inline_file_types' => '/\.(gif|jpe?g|png)$/i', + // Defines which files (based on their names) are accepted for upload: + 'accept_file_types' => '/.+$/i', + // The php.ini settings upload_max_filesize and post_max_size + // take precedence over the following max_file_size setting: + 'max_file_size' => null, + 'min_file_size' => 1, + // The maximum number of files for the upload directory: + 'max_number_of_files' => null, + // Defines which files are handled as image files: + 'image_file_types' => '/\.(gif|jpe?g|png)$/i', + // Use exif_imagetype on all files to correct file extensions: + 'correct_image_extensions' => false, + // Image resolution restrictions: + 'max_width' => null, + 'max_height' => null, + 'min_width' => 1, + 'min_height' => 1, + // Set the following option to false to enable resumable uploads: + 'discard_aborted_uploads' => true, + // Set to 0 to use the GD library to scale and orient images, + // set to 1 to use imagick (if installed, falls back to GD), + // set to 2 to use the ImageMagick convert binary directly: + 'image_library' => 1, + // Uncomment the following to define an array of resource limits + // for imagick: + /* + 'imagick_resource_limits' => array( + imagick::RESOURCETYPE_MAP => 32, + imagick::RESOURCETYPE_MEMORY => 32 + ), + */ + // Command or path for to the ImageMagick convert binary: + 'convert_bin' => 'convert', + // Uncomment the following to add parameters in front of each + // ImageMagick convert call (the limit constraints seem only + // to have an effect if put in front): + /* + 'convert_params' => '-limit memory 32MiB -limit map 32MiB', + */ + // Command or path for to the ImageMagick identify binary: + 'identify_bin' => 'identify', + 'image_versions' => array( + // The empty image version key defines options for the original image: + '' => array( + // Automatically rotate images based on EXIF meta data: + 'auto_orient' => true + ), + // Uncomment the following to create medium sized images: + /* + 'medium' => array( + 'max_width' => 800, + 'max_height' => 600 + ), + */ + 'thumbnail' => array( + // Uncomment the following to use a defined directory for the thumbnails + // instead of a subdirectory based on the version identifier. + // Make sure that this directory doesn't allow execution of files if you + // don't pose any restrictions on the type of uploaded files, e.g. by + // copying the .htaccess file from the files directory for Apache: + //'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/thumb/', + //'upload_url' => $this->get_full_url().'/thumb/', + // Uncomment the following to force the max + // dimensions and e.g. create square thumbnails: + //'crop' => true, + 'max_width' => 80, + 'max_height' => 80 + ) + ), + 'print_response' => true + ); + if ($options) { + $this->options = $options + $this->options; + } + if ($error_messages) { + $this->error_messages = $error_messages + $this->error_messages; + } + if ($initialize) { + $this->initialize(); + } + } + + protected function initialize() { + switch ($this->get_server_var('REQUEST_METHOD')) { + case 'OPTIONS': + case 'HEAD': + $this->head(); + break; + case 'GET': + $this->get($this->options['print_response']); + break; + case 'PATCH': + case 'PUT': + case 'POST': + $this->post($this->options['print_response']); + break; + case 'DELETE': + $this->delete($this->options['print_response']); + break; + default: + $this->header('HTTP/1.1 405 Method Not Allowed'); + } + } + + protected function get_full_url() { + $https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0 || + !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && + strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0; + return + ($https ? 'https://' : 'http://'). + (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : ''). + (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME']. + ($https && $_SERVER['SERVER_PORT'] === 443 || + $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))). + substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/')); + } + + protected function get_user_id() { + @session_start(); + return session_id(); + } + + protected function get_user_path() { + if ($this->options['user_dirs']) { + return $this->get_user_id().'/'; + } + return ''; + } + + protected function get_upload_path($file_name = null, $version = null) { + $file_name = $file_name ? $file_name : ''; + if (empty($version)) { + $version_path = ''; + } else { + $version_dir = @$this->options['image_versions'][$version]['upload_dir']; + if ($version_dir) { + return $version_dir.$this->get_user_path().$file_name; + } + $version_path = $version.'/'; + } + return $this->options['upload_dir'].$this->get_user_path() + .$version_path.$file_name; + } + + protected function get_query_separator($url) { + return strpos($url, '?') === false ? '?' : '&'; + } + + protected function get_download_url($file_name, $version = null, $direct = false) { + if (!$direct && $this->options['download_via_php']) { + $url = $this->options['script_url'] + .$this->get_query_separator($this->options['script_url']) + .$this->get_singular_param_name() + .'='.rawurlencode($file_name); + if ($version) { + $url .= '&version='.rawurlencode($version); + } + return $url.'&download=1'; + } + if (empty($version)) { + $version_path = ''; + } else { + $version_url = @$this->options['image_versions'][$version]['upload_url']; + if ($version_url) { + return $version_url.$this->get_user_path().rawurlencode($file_name); + } + $version_path = rawurlencode($version).'/'; + } + return $this->options['upload_url'].$this->get_user_path() + .$version_path.rawurlencode($file_name); + } + + protected function set_additional_file_properties($file) { + $file->deleteUrl = $this->options['script_url'] + .$this->get_query_separator($this->options['script_url']) + .$this->get_singular_param_name() + .'='.rawurlencode($file->name); + $file->deleteType = $this->options['delete_type']; + if ($file->deleteType !== 'DELETE') { + $file->deleteUrl .= '&_method=DELETE'; + } + if ($this->options['access_control_allow_credentials']) { + $file->deleteWithCredentials = true; + } + } + + // Fix for overflowing signed 32 bit integers, + // works for sizes up to 2^32-1 bytes (4 GiB - 1): + protected function fix_integer_overflow($size) { + if ($size < 0) { + $size += 2.0 * (PHP_INT_MAX + 1); + } + return $size; + } + + protected function get_file_size($file_path, $clear_stat_cache = false) { + if ($clear_stat_cache) { + if (version_compare(PHP_VERSION, '5.3.0') >= 0) { + clearstatcache(true, $file_path); + } else { + clearstatcache(); + } + } + return $this->fix_integer_overflow(filesize($file_path)); + } + + protected function is_valid_file_object($file_name) { + $file_path = $this->get_upload_path($file_name); + if (is_file($file_path) && $file_name[0] !== '.') { + return true; + } + return false; + } + + protected function get_file_object($file_name) { + if ($this->is_valid_file_object($file_name)) { + $file = new \stdClass(); + $file->name = $file_name; + $file->size = $this->get_file_size( + $this->get_upload_path($file_name) + ); + $file->url = $this->get_download_url($file->name); + foreach ($this->options['image_versions'] as $version => $options) { + if (!empty($version)) { + if (is_file($this->get_upload_path($file_name, $version))) { + $file->{$version.'Url'} = $this->get_download_url( + $file->name, + $version + ); + } + } + } + $this->set_additional_file_properties($file); + return $file; + } + return null; + } + + protected function get_file_objects($iteration_method = 'get_file_object') { + $upload_dir = $this->get_upload_path(); + if (!is_dir($upload_dir)) { + return array(); + } + return array_values(array_filter(array_map( + array($this, $iteration_method), + scandir($upload_dir) + ))); + } + + protected function count_file_objects() { + return count($this->get_file_objects('is_valid_file_object')); + } + + protected function get_error_message($error) { + return isset($this->error_messages[$error]) ? + $this->error_messages[$error] : $error; + } + + public function get_config_bytes($val) { + $val = trim($val); + $last = strtolower($val[strlen($val)-1]); + $val = (int)$val; + switch ($last) { + case 'g': + $val *= 1024; + case 'm': + $val *= 1024; + case 'k': + $val *= 1024; + } + return $this->fix_integer_overflow($val); + } + + protected function validate($uploaded_file, $file, $error, $index) { + if ($error) { + $file->error = $this->get_error_message($error); + return false; + } + $content_length = $this->fix_integer_overflow( + (int)$this->get_server_var('CONTENT_LENGTH') + ); + $post_max_size = $this->get_config_bytes(ini_get('post_max_size')); + if ($post_max_size && ($content_length > $post_max_size)) { + $file->error = $this->get_error_message('post_max_size'); + return false; + } + if (!preg_match($this->options['accept_file_types'], $file->name)) { + $file->error = $this->get_error_message('accept_file_types'); + return false; + } + if ($uploaded_file && is_uploaded_file($uploaded_file)) { + $file_size = $this->get_file_size($uploaded_file); + } else { + $file_size = $content_length; + } + if ($this->options['max_file_size'] && ( + $file_size > $this->options['max_file_size'] || + $file->size > $this->options['max_file_size']) + ) { + $file->error = $this->get_error_message('max_file_size'); + return false; + } + if ($this->options['min_file_size'] && + $file_size < $this->options['min_file_size']) { + $file->error = $this->get_error_message('min_file_size'); + return false; + } + if (is_int($this->options['max_number_of_files']) && + ($this->count_file_objects() >= $this->options['max_number_of_files']) && + // Ignore additional chunks of existing files: + !is_file($this->get_upload_path($file->name))) { + $file->error = $this->get_error_message('max_number_of_files'); + return false; + } + $max_width = @$this->options['max_width']; + $max_height = @$this->options['max_height']; + $min_width = @$this->options['min_width']; + $min_height = @$this->options['min_height']; + if (($max_width || $max_height || $min_width || $min_height) + && preg_match($this->options['image_file_types'], $file->name)) { + list($img_width, $img_height) = $this->get_image_size($uploaded_file); + + // If we are auto rotating the image by default, do the checks on + // the correct orientation + if ( + @$this->options['image_versions']['']['auto_orient'] && + function_exists('exif_read_data') && + ($exif = @exif_read_data($uploaded_file)) && + (((int) @$exif['Orientation']) >= 5) + ) { + $tmp = $img_width; + $img_width = $img_height; + $img_height = $tmp; + unset($tmp); + } + + } + if (!empty($img_width)) { + if ($max_width && $img_width > $max_width) { + $file->error = $this->get_error_message('max_width'); + return false; + } + if ($max_height && $img_height > $max_height) { + $file->error = $this->get_error_message('max_height'); + return false; + } + if ($min_width && $img_width < $min_width) { + $file->error = $this->get_error_message('min_width'); + return false; + } + if ($min_height && $img_height < $min_height) { + $file->error = $this->get_error_message('min_height'); + return false; + } + } + return true; + } + + protected function upcount_name_callback($matches) { + $index = isset($matches[1]) ? ((int)$matches[1]) + 1 : 1; + $ext = isset($matches[2]) ? $matches[2] : ''; + return ' ('.$index.')'.$ext; + } + + protected function upcount_name($name) { + return preg_replace_callback( + '/(?:(?: \(([\d]+)\))?(\.[^.]+))?$/', + array($this, 'upcount_name_callback'), + $name, + 1 + ); + } + + protected function get_unique_filename($file_path, $name, $size, $type, $error, + $index, $content_range) { + while(is_dir($this->get_upload_path($name))) { + $name = $this->upcount_name($name); + } + // Keep an existing filename if this is part of a chunked upload: + $uploaded_bytes = $this->fix_integer_overflow((int)$content_range[1]); + while (is_file($this->get_upload_path($name))) { + if ($uploaded_bytes === $this->get_file_size( + $this->get_upload_path($name))) { + break; + } + $name = $this->upcount_name($name); + } + return $name; + } + + protected function fix_file_extension($file_path, $name, $size, $type, $error, + $index, $content_range) { + // Add missing file extension for known image types: + if (strpos($name, '.') === false && + preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) { + $name .= '.'.$matches[1]; + } + if ($this->options['correct_image_extensions'] && + function_exists('exif_imagetype')) { + switch (@exif_imagetype($file_path)){ + case IMAGETYPE_JPEG: + $extensions = array('jpg', 'jpeg'); + break; + case IMAGETYPE_PNG: + $extensions = array('png'); + break; + case IMAGETYPE_GIF: + $extensions = array('gif'); + break; + } + // Adjust incorrect image file extensions: + if (!empty($extensions)) { + $parts = explode('.', $name); + $extIndex = count($parts) - 1; + $ext = strtolower(@$parts[$extIndex]); + if (!in_array($ext, $extensions)) { + $parts[$extIndex] = $extensions[0]; + $name = implode('.', $parts); + } + } + } + return $name; + } + + protected function trim_file_name($file_path, $name, $size, $type, $error, + $index, $content_range) { + // Remove path information and dots around the filename, to prevent uploading + // into different directories or replacing hidden system files. + // Also remove control characters and spaces (\x00..\x20) around the filename: + $name = trim($this->basename(stripslashes($name)), ".\x00..\x20"); + // Use a timestamp for empty filenames: + if (!$name) { + $name = str_replace('.', '-', microtime(true)); + } + return $name; + } + + protected function get_file_name($file_path, $name, $size, $type, $error, + $index, $content_range) { + $name = $this->trim_file_name($file_path, $name, $size, $type, $error, + $index, $content_range); + return $this->get_unique_filename( + $file_path, + $this->fix_file_extension($file_path, $name, $size, $type, $error, + $index, $content_range), + $size, + $type, + $error, + $index, + $content_range + ); + } + + protected function get_scaled_image_file_paths($file_name, $version) { + $file_path = $this->get_upload_path($file_name); + if (!empty($version)) { + $version_dir = $this->get_upload_path(null, $version); + if (!is_dir($version_dir)) { + mkdir($version_dir, $this->options['mkdir_mode'], true); + } + $new_file_path = $version_dir.'/'.$file_name; + } else { + $new_file_path = $file_path; + } + return array($file_path, $new_file_path); + } + + protected function gd_get_image_object($file_path, $func, $no_cache = false) { + if (empty($this->image_objects[$file_path]) || $no_cache) { + $this->gd_destroy_image_object($file_path); + $this->image_objects[$file_path] = $func($file_path); + } + return $this->image_objects[$file_path]; + } + + protected function gd_set_image_object($file_path, $image) { + $this->gd_destroy_image_object($file_path); + $this->image_objects[$file_path] = $image; + } + + protected function gd_destroy_image_object($file_path) { + $image = (isset($this->image_objects[$file_path])) ? $this->image_objects[$file_path] : null ; + return $image && imagedestroy($image); + } + + protected function gd_imageflip($image, $mode) { + if (function_exists('imageflip')) { + return imageflip($image, $mode); + } + $new_width = $src_width = imagesx($image); + $new_height = $src_height = imagesy($image); + $new_img = imagecreatetruecolor($new_width, $new_height); + $src_x = 0; + $src_y = 0; + switch ($mode) { + case '1': // flip on the horizontal axis + $src_y = $new_height - 1; + $src_height = -$new_height; + break; + case '2': // flip on the vertical axis + $src_x = $new_width - 1; + $src_width = -$new_width; + break; + case '3': // flip on both axes + $src_y = $new_height - 1; + $src_height = -$new_height; + $src_x = $new_width - 1; + $src_width = -$new_width; + break; + default: + return $image; + } + imagecopyresampled( + $new_img, + $image, + 0, + 0, + $src_x, + $src_y, + $new_width, + $new_height, + $src_width, + $src_height + ); + return $new_img; + } + + protected function gd_orient_image($file_path, $src_img) { + if (!function_exists('exif_read_data')) { + return false; + } + $exif = @exif_read_data($file_path); + if ($exif === false) { + return false; + } + $orientation = (int)@$exif['Orientation']; + if ($orientation < 2 || $orientation > 8) { + return false; + } + switch ($orientation) { + case 2: + $new_img = $this->gd_imageflip( + $src_img, + defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2 + ); + break; + case 3: + $new_img = imagerotate($src_img, 180, 0); + break; + case 4: + $new_img = $this->gd_imageflip( + $src_img, + defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1 + ); + break; + case 5: + $tmp_img = $this->gd_imageflip( + $src_img, + defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1 + ); + $new_img = imagerotate($tmp_img, 270, 0); + imagedestroy($tmp_img); + break; + case 6: + $new_img = imagerotate($src_img, 270, 0); + break; + case 7: + $tmp_img = $this->gd_imageflip( + $src_img, + defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2 + ); + $new_img = imagerotate($tmp_img, 270, 0); + imagedestroy($tmp_img); + break; + case 8: + $new_img = imagerotate($src_img, 90, 0); + break; + default: + return false; + } + $this->gd_set_image_object($file_path, $new_img); + return true; + } + + protected function gd_create_scaled_image($file_name, $version, $options) { + if (!function_exists('imagecreatetruecolor')) { + error_log('Function not found: imagecreatetruecolor'); + return false; + } + list($file_path, $new_file_path) = + $this->get_scaled_image_file_paths($file_name, $version); + $type = strtolower(substr(strrchr($file_name, '.'), 1)); + switch ($type) { + case 'jpg': + case 'jpeg': + $src_func = 'imagecreatefromjpeg'; + $write_func = 'imagejpeg'; + $image_quality = isset($options['jpeg_quality']) ? + $options['jpeg_quality'] : 75; + break; + case 'gif': + $src_func = 'imagecreatefromgif'; + $write_func = 'imagegif'; + $image_quality = null; + break; + case 'png': + $src_func = 'imagecreatefrompng'; + $write_func = 'imagepng'; + $image_quality = isset($options['png_quality']) ? + $options['png_quality'] : 9; + break; + default: + return false; + } + $src_img = $this->gd_get_image_object( + $file_path, + $src_func, + !empty($options['no_cache']) + ); + $image_oriented = false; + if (!empty($options['auto_orient']) && $this->gd_orient_image( + $file_path, + $src_img + )) { + $image_oriented = true; + $src_img = $this->gd_get_image_object( + $file_path, + $src_func + ); + } + $max_width = $img_width = imagesx($src_img); + $max_height = $img_height = imagesy($src_img); + if (!empty($options['max_width'])) { + $max_width = $options['max_width']; + } + if (!empty($options['max_height'])) { + $max_height = $options['max_height']; + } + $scale = min( + $max_width / $img_width, + $max_height / $img_height + ); + if ($scale >= 1) { + if ($image_oriented) { + return $write_func($src_img, $new_file_path, $image_quality); + } + if ($file_path !== $new_file_path) { + return copy($file_path, $new_file_path); + } + return true; + } + if (empty($options['crop'])) { + $new_width = $img_width * $scale; + $new_height = $img_height * $scale; + $dst_x = 0; + $dst_y = 0; + $new_img = imagecreatetruecolor($new_width, $new_height); + } else { + if (($img_width / $img_height) >= ($max_width / $max_height)) { + $new_width = $img_width / ($img_height / $max_height); + $new_height = $max_height; + } else { + $new_width = $max_width; + $new_height = $img_height / ($img_width / $max_width); + } + $dst_x = 0 - ($new_width - $max_width) / 2; + $dst_y = 0 - ($new_height - $max_height) / 2; + $new_img = imagecreatetruecolor($max_width, $max_height); + } + // Handle transparency in GIF and PNG images: + switch ($type) { + case 'gif': + case 'png': + imagecolortransparent($new_img, imagecolorallocate($new_img, 0, 0, 0)); + case 'png': + imagealphablending($new_img, false); + imagesavealpha($new_img, true); + break; + } + $success = imagecopyresampled( + $new_img, + $src_img, + $dst_x, + $dst_y, + 0, + 0, + $new_width, + $new_height, + $img_width, + $img_height + ) && $write_func($new_img, $new_file_path, $image_quality); + $this->gd_set_image_object($file_path, $new_img); + return $success; + } + + protected function imagick_get_image_object($file_path, $no_cache = false) { + if (empty($this->image_objects[$file_path]) || $no_cache) { + $this->imagick_destroy_image_object($file_path); + $image = new \Imagick(); + if (!empty($this->options['imagick_resource_limits'])) { + foreach ($this->options['imagick_resource_limits'] as $type => $limit) { + $image->setResourceLimit($type, $limit); + } + } + $image->readImage($file_path); + $this->image_objects[$file_path] = $image; + } + return $this->image_objects[$file_path]; + } + + protected function imagick_set_image_object($file_path, $image) { + $this->imagick_destroy_image_object($file_path); + $this->image_objects[$file_path] = $image; + } + + protected function imagick_destroy_image_object($file_path) { + $image = (isset($this->image_objects[$file_path])) ? $this->image_objects[$file_path] : null ; + return $image && $image->destroy(); + } + + protected function imagick_orient_image($image) { + $orientation = $image->getImageOrientation(); + $background = new \ImagickPixel('none'); + switch ($orientation) { + case \imagick::ORIENTATION_TOPRIGHT: // 2 + $image->flopImage(); // horizontal flop around y-axis + break; + case \imagick::ORIENTATION_BOTTOMRIGHT: // 3 + $image->rotateImage($background, 180); + break; + case \imagick::ORIENTATION_BOTTOMLEFT: // 4 + $image->flipImage(); // vertical flip around x-axis + break; + case \imagick::ORIENTATION_LEFTTOP: // 5 + $image->flopImage(); // horizontal flop around y-axis + $image->rotateImage($background, 270); + break; + case \imagick::ORIENTATION_RIGHTTOP: // 6 + $image->rotateImage($background, 90); + break; + case \imagick::ORIENTATION_RIGHTBOTTOM: // 7 + $image->flipImage(); // vertical flip around x-axis + $image->rotateImage($background, 270); + break; + case \imagick::ORIENTATION_LEFTBOTTOM: // 8 + $image->rotateImage($background, 270); + break; + default: + return false; + } + $image->setImageOrientation(\imagick::ORIENTATION_TOPLEFT); // 1 + return true; + } + + protected function imagick_create_scaled_image($file_name, $version, $options) { + list($file_path, $new_file_path) = + $this->get_scaled_image_file_paths($file_name, $version); + $image = $this->imagick_get_image_object( + $file_path, + !empty($options['crop']) || !empty($options['no_cache']) + ); + if ($image->getImageFormat() === 'GIF') { + // Handle animated GIFs: + $images = $image->coalesceImages(); + foreach ($images as $frame) { + $image = $frame; + $this->imagick_set_image_object($file_name, $image); + break; + } + } + $image_oriented = false; + if (!empty($options['auto_orient'])) { + $image_oriented = $this->imagick_orient_image($image); + } + $new_width = $max_width = $img_width = $image->getImageWidth(); + $new_height = $max_height = $img_height = $image->getImageHeight(); + if (!empty($options['max_width'])) { + $new_width = $max_width = $options['max_width']; + } + if (!empty($options['max_height'])) { + $new_height = $max_height = $options['max_height']; + } + if (!($image_oriented || $max_width < $img_width || $max_height < $img_height)) { + if ($file_path !== $new_file_path) { + return copy($file_path, $new_file_path); + } + return true; + } + $crop = !empty($options['crop']); + if ($crop) { + $x = 0; + $y = 0; + if (($img_width / $img_height) >= ($max_width / $max_height)) { + $new_width = 0; // Enables proportional scaling based on max_height + $x = ($img_width / ($img_height / $max_height) - $max_width) / 2; + } else { + $new_height = 0; // Enables proportional scaling based on max_width + $y = ($img_height / ($img_width / $max_width) - $max_height) / 2; + } + } + $success = $image->resizeImage( + $new_width, + $new_height, + isset($options['filter']) ? $options['filter'] : \imagick::FILTER_LANCZOS, + isset($options['blur']) ? $options['blur'] : 1, + $new_width && $new_height // fit image into constraints if not to be cropped + ); + if ($success && $crop) { + $success = $image->cropImage( + $max_width, + $max_height, + $x, + $y + ); + if ($success) { + $success = $image->setImagePage($max_width, $max_height, 0, 0); + } + } + $type = strtolower(substr(strrchr($file_name, '.'), 1)); + switch ($type) { + case 'jpg': + case 'jpeg': + if (!empty($options['jpeg_quality'])) { + $image->setImageCompression(\imagick::COMPRESSION_JPEG); + $image->setImageCompressionQuality($options['jpeg_quality']); + } + break; + } + if (!empty($options['strip'])) { + $image->stripImage(); + } + return $success && $image->writeImage($new_file_path); + } + + protected function imagemagick_create_scaled_image($file_name, $version, $options) { + list($file_path, $new_file_path) = + $this->get_scaled_image_file_paths($file_name, $version); + $resize = @$options['max_width'] + .(empty($options['max_height']) ? '' : 'X'.$options['max_height']); + if (!$resize && empty($options['auto_orient'])) { + if ($file_path !== $new_file_path) { + return copy($file_path, $new_file_path); + } + return true; + } + $cmd = $this->options['convert_bin']; + if (!empty($this->options['convert_params'])) { + $cmd .= ' '.$this->options['convert_params']; + } + $cmd .= ' '.escapeshellarg($file_path); + if (!empty($options['auto_orient'])) { + $cmd .= ' -auto-orient'; + } + if ($resize) { + // Handle animated GIFs: + $cmd .= ' -coalesce'; + if (empty($options['crop'])) { + $cmd .= ' -resize '.escapeshellarg($resize.'>'); + } else { + $cmd .= ' -resize '.escapeshellarg($resize.'^'); + $cmd .= ' -gravity center'; + $cmd .= ' -crop '.escapeshellarg($resize.'+0+0'); + } + // Make sure the page dimensions are correct (fixes offsets of animated GIFs): + $cmd .= ' +repage'; + } + if (!empty($options['convert_params'])) { + $cmd .= ' '.$options['convert_params']; + } + $cmd .= ' '.escapeshellarg($new_file_path); + exec($cmd, $output, $error); + if ($error) { + error_log(implode('\n', $output)); + return false; + } + return true; + } + + protected function get_image_size($file_path) { + if ($this->options['image_library']) { + if (extension_loaded('imagick')) { + $image = new \Imagick(); + try { + if (@$image->pingImage($file_path)) { + $dimensions = array($image->getImageWidth(), $image->getImageHeight()); + $image->destroy(); + return $dimensions; + } + return false; + } catch (\Exception $e) { + error_log($e->getMessage()); + } + } + if ($this->options['image_library'] === 2) { + $cmd = $this->options['identify_bin']; + $cmd .= ' -ping '.escapeshellarg($file_path); + exec($cmd, $output, $error); + if (!$error && !empty($output)) { + // image.jpg JPEG 1920x1080 1920x1080+0+0 8-bit sRGB 465KB 0.000u 0:00.000 + $infos = preg_split('/\s+/', substr($output[0], strlen($file_path))); + $dimensions = preg_split('/x/', $infos[2]); + return $dimensions; + } + return false; + } + } + if (!function_exists('getimagesize')) { + error_log('Function not found: getimagesize'); + return false; + } + return @getimagesize($file_path); + } + + protected function create_scaled_image($file_name, $version, $options) { + if ($this->options['image_library'] === 2) { + return $this->imagemagick_create_scaled_image($file_name, $version, $options); + } + if ($this->options['image_library'] && extension_loaded('imagick')) { + return $this->imagick_create_scaled_image($file_name, $version, $options); + } + return $this->gd_create_scaled_image($file_name, $version, $options); + } + + protected function destroy_image_object($file_path) { + if ($this->options['image_library'] && extension_loaded('imagick')) { + return $this->imagick_destroy_image_object($file_path); + } + } + + protected function is_valid_image_file($file_path) { + if (!preg_match($this->options['image_file_types'], $file_path)) { + return false; + } + if (function_exists('exif_imagetype')) { + return @exif_imagetype($file_path); + } + $image_info = $this->get_image_size($file_path); + return $image_info && $image_info[0] && $image_info[1]; + } + + protected function handle_image_file($file_path, $file) { + $failed_versions = array(); + foreach ($this->options['image_versions'] as $version => $options) { + if ($this->create_scaled_image($file->name, $version, $options)) { + if (!empty($version)) { + $file->{$version.'Url'} = $this->get_download_url( + $file->name, + $version + ); + } else { + $file->size = $this->get_file_size($file_path, true); + } + } else { + $failed_versions[] = $version ? $version : 'original'; + } + } + if (count($failed_versions)) { + $file->error = $this->get_error_message('image_resize') + .' ('.implode($failed_versions, ', ').')'; + } + // Free memory: + $this->destroy_image_object($file_path); + } + + protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, + $index = null, $content_range = null) { + $file = new \stdClass(); + $file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error, + $index, $content_range); + $file->size = $this->fix_integer_overflow((int)$size); + $file->type = $type; + if ($this->validate($uploaded_file, $file, $error, $index)) { + $this->handle_form_data($file, $index); + $upload_dir = $this->get_upload_path(); + if (!is_dir($upload_dir)) { + mkdir($upload_dir, $this->options['mkdir_mode'], true); + } + $file_path = $this->get_upload_path($file->name); + $append_file = $content_range && is_file($file_path) && + $file->size > $this->get_file_size($file_path); + if ($uploaded_file && is_uploaded_file($uploaded_file)) { + // multipart/formdata uploads (POST method uploads) + if ($append_file) { + file_put_contents( + $file_path, + fopen($uploaded_file, 'r'), + FILE_APPEND + ); + } else { + move_uploaded_file($uploaded_file, $file_path); + } + } else { + // Non-multipart uploads (PUT method support) + file_put_contents( + $file_path, + fopen($this->options['input_stream'], 'r'), + $append_file ? FILE_APPEND : 0 + ); + } + $file_size = $this->get_file_size($file_path, $append_file); + if ($file_size === $file->size) { + $file->url = $this->get_download_url($file->name); + if ($this->is_valid_image_file($file_path)) { + $this->handle_image_file($file_path, $file); + } + } else { + $file->size = $file_size; + if (!$content_range && $this->options['discard_aborted_uploads']) { + unlink($file_path); + $file->error = $this->get_error_message('abort'); + } + } + $this->set_additional_file_properties($file); + } + return $file; + } + + protected function readfile($file_path) { + $file_size = $this->get_file_size($file_path); + $chunk_size = $this->options['readfile_chunk_size']; + if ($chunk_size && $file_size > $chunk_size) { + $handle = fopen($file_path, 'rb'); + while (!feof($handle)) { + echo fread($handle, $chunk_size); + @ob_flush(); + @flush(); + } + fclose($handle); + return $file_size; + } + return readfile($file_path); + } + + protected function body($str) { + echo $str; + } + + protected function header($str) { + header($str); + } + + protected function get_upload_data($id) { + return @$_FILES[$id]; + } + + protected function get_post_param($id) { + return @$_POST[$id]; + } + + protected function get_query_param($id) { + return @$_GET[$id]; + } + + protected function get_server_var($id) { + return @$_SERVER[$id]; + } + + protected function handle_form_data($file, $index) { + // Handle form data, e.g. $_POST['description'][$index] + } + + protected function get_version_param() { + return $this->basename(stripslashes($this->get_query_param('version'))); + } + + protected function get_singular_param_name() { + return substr($this->options['param_name'], 0, -1); + } + + protected function get_file_name_param() { + $name = $this->get_singular_param_name(); + return $this->basename(stripslashes($this->get_query_param($name))); + } + + protected function get_file_names_params() { + $params = $this->get_query_param($this->options['param_name']); + if (!$params) { + return null; + } + foreach ($params as $key => $value) { + $params[$key] = $this->basename(stripslashes($value)); + } + return $params; + } + + protected function get_file_type($file_path) { + switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) { + case 'jpeg': + case 'jpg': + return 'image/jpeg'; + case 'png': + return 'image/png'; + case 'gif': + return 'image/gif'; + default: + return ''; + } + } + + protected function download() { + switch ($this->options['download_via_php']) { + case 1: + $redirect_header = null; + break; + case 2: + $redirect_header = 'X-Sendfile'; + break; + case 3: + $redirect_header = 'X-Accel-Redirect'; + break; + default: + return $this->header('HTTP/1.1 403 Forbidden'); + } + $file_name = $this->get_file_name_param(); + if (!$this->is_valid_file_object($file_name)) { + return $this->header('HTTP/1.1 404 Not Found'); + } + if ($redirect_header) { + return $this->header( + $redirect_header.': '.$this->get_download_url( + $file_name, + $this->get_version_param(), + true + ) + ); + } + $file_path = $this->get_upload_path($file_name, $this->get_version_param()); + // Prevent browsers from MIME-sniffing the content-type: + $this->header('X-Content-Type-Options: nosniff'); + if (!preg_match($this->options['inline_file_types'], $file_name)) { + $this->header('Content-Type: application/octet-stream'); + $this->header('Content-Disposition: attachment; filename="'.$file_name.'"'); + } else { + $this->header('Content-Type: '.$this->get_file_type($file_path)); + $this->header('Content-Disposition: inline; filename="'.$file_name.'"'); + } + $this->header('Content-Length: '.$this->get_file_size($file_path)); + $this->header('Last-Modified: '.gmdate('D, d M Y H:i:s T', filemtime($file_path))); + $this->readfile($file_path); + } + + protected function send_content_type_header() { + $this->header('Vary: Accept'); + if (strpos($this->get_server_var('HTTP_ACCEPT'), 'application/json') !== false) { + $this->header('Content-type: application/json'); + } else { + $this->header('Content-type: text/plain'); + } + } + + protected function send_access_control_headers() { + $this->header('Access-Control-Allow-Origin: '.$this->options['access_control_allow_origin']); + $this->header('Access-Control-Allow-Credentials: ' + .($this->options['access_control_allow_credentials'] ? 'true' : 'false')); + $this->header('Access-Control-Allow-Methods: ' + .implode(', ', $this->options['access_control_allow_methods'])); + $this->header('Access-Control-Allow-Headers: ' + .implode(', ', $this->options['access_control_allow_headers'])); + } + + public function generate_response($content, $print_response = true) { + $this->response = $content; + if ($print_response) { + $json = json_encode($content); + $redirect = stripslashes($this->get_post_param('redirect')); + if ($redirect && preg_match($this->options['redirect_allow_target'], $redirect)) { + $this->header('Location: '.sprintf($redirect, rawurlencode($json))); + return; + } + $this->head(); + if ($this->get_server_var('HTTP_CONTENT_RANGE')) { + $files = isset($content[$this->options['param_name']]) ? + $content[$this->options['param_name']] : null; + if ($files && is_array($files) && is_object($files[0]) && $files[0]->size) { + $this->header('Range: 0-'.( + $this->fix_integer_overflow((int)$files[0]->size) - 1 + )); + } + } + $this->body($json); + } + return $content; + } + + public function get_response () { + return $this->response; + } + + public function head() { + $this->header('Pragma: no-cache'); + $this->header('Cache-Control: no-store, no-cache, must-revalidate'); + $this->header('Content-Disposition: inline; filename="files.json"'); + // Prevent Internet Explorer from MIME-sniffing the content-type: + $this->header('X-Content-Type-Options: nosniff'); + if ($this->options['access_control_allow_origin']) { + $this->send_access_control_headers(); + } + $this->send_content_type_header(); + } + + public function get($print_response = true) { + if ($print_response && $this->get_query_param('download')) { + return $this->download(); + } + $file_name = $this->get_file_name_param(); + if ($file_name) { + $response = array( + $this->get_singular_param_name() => $this->get_file_object($file_name) + ); + } else { + $response = array( + $this->options['param_name'] => $this->get_file_objects() + ); + } + return $this->generate_response($response, $print_response); + } + + public function post($print_response = true) { + if ($this->get_query_param('_method') === 'DELETE') { + return $this->delete($print_response); + } + $upload = $this->get_upload_data($this->options['param_name']); + // Parse the Content-Disposition header, if available: + $content_disposition_header = $this->get_server_var('HTTP_CONTENT_DISPOSITION'); + $file_name = $content_disposition_header ? + rawurldecode(preg_replace( + '/(^[^"]+")|("$)/', + '', + $content_disposition_header + )) : null; + // Parse the Content-Range header, which has the following form: + // Content-Range: bytes 0-524287/2000000 + $content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE'); + $content_range = $content_range_header ? + preg_split('/[^0-9]+/', $content_range_header) : null; + $size = $content_range ? $content_range[3] : null; + $files = array(); + if ($upload) { + if (is_array($upload['tmp_name'])) { + // param_name is an array identifier like "files[]", + // $upload is a multi-dimensional array: + foreach ($upload['tmp_name'] as $index => $value) { + $files[] = $this->handle_file_upload( + $upload['tmp_name'][$index], + $file_name ? $file_name : $upload['name'][$index], + $size ? $size : $upload['size'][$index], + $upload['type'][$index], + $upload['error'][$index], + $index, + $content_range + ); + } + } else { + // param_name is a single object identifier like "file", + // $upload is a one-dimensional array: + $files[] = $this->handle_file_upload( + isset($upload['tmp_name']) ? $upload['tmp_name'] : null, + $file_name ? $file_name : (isset($upload['name']) ? + $upload['name'] : null), + $size ? $size : (isset($upload['size']) ? + $upload['size'] : $this->get_server_var('CONTENT_LENGTH')), + isset($upload['type']) ? + $upload['type'] : $this->get_server_var('CONTENT_TYPE'), + isset($upload['error']) ? $upload['error'] : null, + null, + $content_range + ); + } + } + $response = array($this->options['param_name'] => $files); + return $this->generate_response($response, $print_response); + } + + public function delete($print_response = true) { + $file_names = $this->get_file_names_params(); + if (empty($file_names)) { + $file_names = array($this->get_file_name_param()); + } + $response = array(); + foreach ($file_names as $file_name) { + $file_path = $this->get_upload_path($file_name); + $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path); + if ($success) { + foreach ($this->options['image_versions'] as $version => $options) { + if (!empty($version)) { + $file = $this->get_upload_path($file_name, $version); + if (is_file($file)) { + unlink($file); + } + } + } + } + $response[$file_name] = $success; + } + return $this->generate_response($response, $print_response); + } + + protected function basename($filepath, $suffix = null) { + $splited = preg_split('/\//', rtrim ($filepath, '/ ')); + return substr(basename('X'.$splited[count($splited)-1], $suffix), 1); + } +} \ No newline at end of file diff --git a/src/Scores/Validate/IpInNetwork.php b/src/Scores/Validate/IpInNetwork.php new file mode 100644 index 0000000..ed770e2 --- /dev/null +++ b/src/Scores/Validate/IpInNetwork.php @@ -0,0 +1,632 @@ +Accepts an array with options. Also adds the error messages to the parent's message templates.

+ * @example

List of allow options and their use: + * $options argument must be an array and allows two key/value pairs for this class and passes on any remaining + * values to the parent class Zend_Validate_Ip. If key 'network' exists it will pass on the value to method + * setNetworkNotation and for key 'throw' to setThrow4Notation.

+ * @see Zend_Validate_Ip::__construct() + * @see Scores_Validate_IpInNetwork::setNetworkNotation() + * @see Scores_Validate_IpInNetwork::setThrow4Notation() + * @param array $options + * @return void + */ + public function __construct($options = array()) + { + if (!empty($options) && is_array($options)) { + if (array_key_exists('throw', $options)) { + $this->setThrow4Notation($options['throw']); + unset($options['throw']); + } + if (array_key_exists('network', $options)) { + $this->setNetworkNotation($options['network']); + unset($options['network']); + } + } + + $this->setMessages(array()); + + parent::__construct($options); + } + + /** + * (non-PHPdoc) + * @see Zend_Validate_Abstract::setMessages() + */ + public function setMessages(array $messages) + { + $newMessages = array( + self::MISSING_NETWORK => 'No valid network has been given to validate against', + self::INVALID_NETWORK => 'The network is not an accepted format', + self::NOT_IN_NETWORK => "The ip '%value%' does not match the provided 32 network", + self::LOW_IN_NETWORK => "The ip '%value%' is lower in range than the provided network", + self::HIGH_IN_NETWORK => "The ip '%value%' is higher in range than the provided network", + ); + + foreach ($newMessages as $messageKey => $messageString) { + if (!isset($this->_messageTemplates[$messageKey])) { + $this->_messageTemplates[$messageKey] = $messageString; + } elseif (!empty($messages) && array_key_exists($messageKey, $messages)) { + $this->_messageTemplates[$messageKey] = $messages[$messageKey]; + unset($messages[$messageKey]); + } + } + + empty($messages) || parent::setMessages($messages) ; + + return $this; + } + + /** + * (non-PHPdoc) + * @see Zend_Validate_Ip::isValid() + */ + public function isValid($value) + { + if (true === parent::isValid($value)) { + $notation = $this->_getNotation(); + if (!empty($notation)) { + // a valid notation has been set + $network = $this->_getNetwork(); + if (!empty($network)) { + if (true === $this->_validateIpInNetwork($value)) { + return true; + } + } else { + if (true === $this->_validateIpInRange($value)) { + return true; + } + } + // NOTE: Errors are only available in regards to the value (ip address) and not the network/netmask (notation) + $errors = $this->getErrors(); + if (empty($errors)) { + $this->_error(self::NOT_IN_NETWORK); + } + } else { + $this->_error(self::MISSING_NETWORK); + } + } + + return false; + } + + /** + * Validates the IP in a given network + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/14 16:34:00 CST + * @author aw + * @desc

Takes the CIDR and network (IP) address and validates the given IP address against it. Sets the appropriate + * errors if the IP is not a match for the network.

+ * @param string $ip + * @return bool + */ + protected function _validateIpInNetwork($ip) + { + $netmask = $this->getCidr(); + $network = $this->_getNetwork(); + + // lets get this out of the way first + if (32 === $netmask) { + // this network has to match the IP + if ($network === $ip) { + return true; + } else { + $this->_error(self::NOT_IN_NETWORK); + return false; + } + } + + // get the unsigned integers for the IP and network address + $ip_addr_uDec = $this->_makeUnsignedAddress($ip); + $lNetwork_uDec = $this->_makeUnsignedAddress($network); + + // let verify the IP against the lower end of the range + if ($ip_addr_uDec < $lNetwork_uDec) { + // the ip is below the network range + $this->_error(self::LOW_IN_NETWORK); + return false; + } + + // well then, finally verify the IP against the uppoer end of the range + + // add the decimal representation of the netmask to the network IP + $netmask_uDec1 = $netmask < 31 ? pow(2, (32-$netmask)) - 1 : 1 ; + $netmask_uDec = pow(2, 32-$netmask) - 1 ; + $uNetwork_uDec = $lNetwork_uDec + $netmask_uDec; + + if ($ip_addr_uDec > $uNetwork_uDec) { + // the ip is above the network range + $this->_error(self::HIGH_IN_NETWORK); + return false; + } + + return true; + } + + /** + * Validates the IP in a given range + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/16 13:06:00 CST + * @author aw + * @desc

Takes the "from" and "to" (IP) address and validates the given IP address against it. Sets the appropriate + * errors if the IP is not within the defined range.

+ * @param string $ip + * @return bool + */ + protected function _validateIpInRange($ip) + { + $uInt_Ip = $this->_makeUnsignedAddress($ip); + + if (is_numeric($this->_rangeFrom) && $uInt_Ip >= $this->_rangeFrom) { + if ($uInt_Ip <= $this->_rangeTo) { + return true; + } elseif (is_numeric($this->_rangeTo)) { + $this->_error(self::HIGH_IN_NETWORK); + return false; + } + } elseif (is_numeric($this->_rangeFrom)) { + $this->_error(self::LOW_IN_NETWORK); + return false; + } + + $this->_error(self::MISSING_NETWORK); + return false; + } + + /** + * Set the network (notation) to the properties + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/14 13:43:00 CST + * @author aw + * @desc

The network is usually a notation with a network/netmask combination. The method uses two methods to validate + * the netmask and the network address. If the notation is a range fromIPAddress-toIPAddress the netmask and network address + * are ignored. The isValid() will then attempt to validate the value within the range and not the network segment.

+ * string $notation network/address (128.0.0.0/24) (128.0.0.0/255.255.255.0) or (128.0.0.0-128.0.0.255) + * @return object|false Awd_Validate_IpInNetwork + */ + public function setNetworkNotation($notation) + { + $network = false !== strpos($notation, '/') ? $this->_evaluateNetmask($notation) : false ; + if (false !== $network) { + // a valid CIDR/netmask has been found + if (true === parent::isValid($network)) { + if ($this->_validateNetwork($network)) { + $this->_network = $network; + $this->_notation = $notation; + + return $this; + } + } else { + $this->_invalidNetwork(__LINE__); + } + } elseif (false !== strpos($notation, '-')) { + // the notation is looking like a from-to IP range + if (true === $this->_validateRange($notation)) { + $this->_notation = $notation; + + return $this; + } + } + + return false; + } + + /** + * Sets the value for _throw property + * + * @since Version 0.1.36 + * @version 0.1.35 2012/01/17 08:23:00 CST + * @author aw + * @desc

The value determines if the application will throw an exception or trigger an E_USER_WARNING if + * an error was found in the submitted network notation. The default is false.

+ * @throws E_USER_WARNING if the argument is not of type bool + * bool $throw + * @return object Awd_Validate_IpInNetwork + */ + public function setThrow4Notation($throw = false) + { + if (!is_bool($throw)) { + $msg = '[AWD] Programming error: The argument is not a boolean value'; + trigger_error($msg, E_USER_WARNING); + } + + + $this->_throw = $throw; + return $this; + } + + /** + * Gets the value for _throw property + * + * @since Version 0.1.36 + * @version 0.1.35 2012/01/17 08:27:00 CST + * @author aw + * @desc

The value determines if the application will throw an exception or trigger an E_USER_WARNING if + * an error was found in the submitted network notation. The default is false.

+ * @return bool + */ + public function getThrow4Notation() + { + return (bool) $this->_throw; + } + + /** + * Gets the network (notation) as it has been set if valid + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/14 16:08:00 CST + * @author aw + * @desc

If empty the network (notation) was either not set or not valid. Hence, this method can be used to + * verify if setting a network range or notation was successful with the constructor.

+ * @return string + */ + public function getNetworkNotation() + { + return (string) $this->_getNotation(); + } + + /** + * Protected method to gets the network (notation) as it has been set if valid + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/14 16:08:00 CST + * @author aw + * @desc

Note that the notation is only available when it passed the internal validation. Internally (protected) + * the network represents the network (IP) address whereas the notation is the full string as set when is valid. + * The notation is a representation of network range or network/mask. This method essentially returns internally + * (protected) the same result as the public method getNetworkNotation().

+ * @return string|null + */ + protected function _getNotation() + { + return empty($this->_notation) ? null : (string) $this->_notation ; + } + + /** + * Gets the network address from the notation if a valid address and mask has been set + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/14 16:18:00 CST + * @author aw + * @desc

Note that internally (protected) the network represents the network (IP) address extracted from the + * "network notation", i.e. a representation of network range or network/mask. If the notation was not valid or a + * network range has been set this value will be empty.

+ * @return string + */ + protected function _getNetwork() + { + return (string) $this->_network; + } + + /** + * Gets the CIDR from the notation if a valid address and mask has been set + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/14 16:26:00 CST + * @author aw + * @desc

The CIDR has been extracted from the "network notation", i.e. a representation of network/mask or + * network/CIDR. If the notation was not valid or a network range has been set this value will be empty.

+ * @return int + */ + public function getCidr() + { + return (int) $this->_cidr; + } + + /** + * Evaluates the netmask from a notation + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/15 10:12:00 CST + * @author aw + * @desc

The notation is usually set as a {network/CIDR} or {network/netmask} notation. This method examines + * the string following a slash. A CIDR mask will be verified for its number whereas a netmask is passed to + * another method _validateNetmask() for validation and if valid converted into a CIDR representation. In + * either case if the value is valid the remaining network (IP) address is returned or false on failure.

+ * @throws Calls method _invalidNetwork() when a failure is detected + * @param string $notation + * @return string|bool (false) + */ + protected function _evaluateNetmask($notation) + { + // split the notation in network and netmask information + list($network, $netmask) = explode('/', $notation, 2); + if (is_numeric($netmask)) { + // does look like a CIDR netmask + $between = new Zend_Validate_Between(array('min'=>1, 'max'=>32)); + if (true === $between->isValid($netmask)) { + $this->_cidr = (int) $netmask; + return $network; + } else { + $error_msgs = $between->getMessages(); + if (!empty($error_msgs) && is_array($error_msgs)) { + $msg = array_shift($error_msgs); + } else { + // fallback, should not really be an option + $msg = sprintf('The netmask [ %s ] is not a valid option', $netmask); + } + + // oops, this CIDR is not a valid range + return $this->_invalidNetwork(__LINE__.' - '.$msg); + } + } elseif (!empty($netmask)) { + // looks more like 32-bit (like 255.255.255.0) format + if (true === ($line = $this->_validateNetmask($netmask))) { + return $network; + } + + return $this->_invalidNetwork($line); + } + + return $this->_invalidNetwork(__LINE__); + } + + /** + * Validates a 32-bit netmask + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/16 10:34:00 CST + * @author aw + * @desc

A netmask is a decimal representation of 32-bit string where the beginning sequence is a complete + * set of 1 (one) followed by a complete set of 0 (zero). If valid the netmask string will be a CIDR numeric + * value and set to the proected property _cidr. If not valid the returned value is the line plus the index if + * the failure is in one of the segments.

+ * @param string $netmask + * @return true|string + */ + protected function _validateNetmask($netmask) + { + $classes = explode('.', $netmask); + if (4 !== count($classes)) { + return __LINE__; + } + + $cidr = 0; + $end = false; + foreach ($classes as $index => $segment) { + if (!is_numeric($segment)) { + return __LINE__; + } elseif (0 === (int) $segment) { + $end = true; // all following segment have to be 0 (zero) as well + continue; + } + $matches = array(); + + // evaluate the binary representation of the segment + $bin = decbin($segment); + if (8 !== strlen($bin) || 0 === preg_match('/^([1]{1,8})([0]*)$/', decbin($segment), $matches)) { + if (8 !== strlen($bin)) { + // this segment is not a complete byte (8 bits) i.e. a value below 128 + return __LINE__.':'.++$index; // NOTE: Index begins at 0 (zero) + } + // this segment is a complete byte (8 bits), i.e. a value above 128, but not a valid binary mask (like 11110000) + return __LINE__.':'.++$index; // NOTE: Index begins at 0 (zero) + } elseif (true === $end) { + // a mask was found in the previous segment; therefore, this segment should be 0 (zero) + return __LINE__.':'.++$index; // NOTE: Index begins at 0 (zero) + } + $len = strlen($matches[1]); + if ($len < 8) { + $end = true; + } + $cidr += $len; + } + + $this->_cidr = $cidr; + return true; + } + + /** + * Validates the network address in a subnet notation + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/16 10:34:00 CST + * @author aw + * @desc

The network address in a CIDR or subnet mask notation is the base of the assigned block. + * Because the size of the block is specified by the CIDR or subnet mask the base of a network address + * has to fit and match into the block size. This method evaluates the block size and then validates + * if the base of network address fits into the assigned block. If not valid the line plus the index + * of the failed segment is sent to method _invalidNetwork() triggering or throwing an error.

+ * @param string $network + * @return true|string + */ + protected function _validateNetwork($network) + { + $cidr = $this->getCidr(); + $class = $cidr / 8; + + // an integer indicates a classful (unicast) network + if (is_int($class)) { + $iClass = $class; + $maskBits = 0; + } else { + $iClass = (int) floor($class); + $maskBits = (int) 8 - ($cidr - ($iClass * 8)); + $hosts = (int) pow(2, $maskBits); // number of usable hosts in a subnet + } + + $segments = explode('.', $network); + // Note: $segments index begins at 0 (zero) and $iClass is the last complete segment in the netmask (8 bits (255)) + // It is irrelevant but just to clarify for $iClass: 1 = Class A, 2 = Class B, 3 = Class C + + $complete = false; + // check all segments following the last complete class and because we have to check for + // subnetting in the _follow_ class we do NOT add 1 to $iClass as the index in $segments + for ($index = $iClass; $index < 4; $index++) { + $subNetwork = (int) $segments[$index]; + + if (0 === $maskBits) { + // this class has no subnets (aka classful network) + // all 0 (zero) are expected as (sub)network numbers + if (0 !== $subNetwork) { + return $this->_invalidNetwork(__LINE__.':'.++$index); // NOTE: Index begins at 0 (zero) + } + continue; + } else { + // this class has subnets (aka a classless (subnetted) network) + if (true === $complete) { + // for all following networks 0 (zero) is expected as (sub)network number + if (0 !== $subNetwork) { + return $this->_invalidNetwork(__LINE__.':'.++$index); // NOTE: Index begins at 0 (zero) + } + continue; + } + $complete = true; + + // the (sub)network must be a fact or hosts(/subnets) + $block = $subNetwork / $hosts; + if (is_int($block)) { + // all clear + // NOTE: We do NOT return yet because we may have to verify any following segments + continue; + } else { + return $this->_invalidNetwork(__LINE__.':'.++$index.':'.$hosts); // NOTE: Index begins at 0 (zero) + } + } + } + + return true; + } + + /** + * Validates a network range with a "from-to" IP address notation + * + * @since Version 0.1.36 + * @version 0.1.35 2012/01/16 12:44:00 CST + * @author aw + * @desc

A network range can be any difference (or equal) between two valid IP addresses. The method will even switch the + * values if the "to" is lower than the "from" address.

+ * @param string $range + * @return bool + */ + protected function _validateRange($range) + { + list($from, $to) = explode('-', $range); // Note: we do NOT care if more IP ranges have been set, i.e. the range would be invalid + + if (false === ($uInt_from = $this->_makeUnsignedAddress($from)) || false === ($uInt_to = $this->_makeUnsignedAddress($to))) { + return $this->_invalidNetwork(__LINE__); // at least one of the addresses is not a valid IP address + } + + if ($uInt_from <= $uInt_to) { + $this->_rangeFrom = $uInt_from; + $this->_rangeTo = $uInt_to; + } else { + // the range is not in the correct order + $this->_rangeFrom = $uInt_to; + $this->_rangeTo = $uInt_from; + } + + return true; + } + + /** + * Converts an IP address into an unsigned decimal number (see ATTENTION note for returned value) + * + * @since Version 0.1.36 + * @version 0.1.35 2012/01/16 12:31:00 CST + * @author aw + * @desc

Uses php function ip2long() to convert the IP into a signed value first and then returns the value with + * sprintf($u). ATTENTION: Function sprintf returns this value as a string and typecasting will not produce the expected + * result for IP addresses above 128.0.0.0. Do not typecast this value to an integer!

+ * @param string $ip + * @return string + */ + private function _makeUnsignedAddress($ip) + { + if (false === ($ip_addr_long = ip2long($ip))) { + // not a valid IP address + return false; + } + + // Note ip2long creates signed integers + // a positive number means the address is in the lower half < 128 (0nnn nnnn.) + // a negative number means the address is in the upper half >= 128 (1nnn nnnn.) + // 127.255.255.255 = 2147483647 + // 128.0.0.1 = -2147483647 + // 128.0.0.0 = -2147483648 + + // convert to unsigned decimal number + return sprintf('%u', $ip_addr_long); + } + + /** + * Triggers an error warning or throws an exception + * + * @since Version 0.1.36 + * @version 0.1.36 2012/01/15 11:54:00 CST + * @author aw + * @desc

The error message contains the argument which is usually the line where the error occured. The calling method + * may add additional information to the line number.

+ * @throws E_USER_WARNING If the _throw property is false (default) + * @throws Exception If the _throw property is true + * @param string|int $line + * @return bool (false) + */ + private function _invalidNetwork($line) + { + $error_msg = 'The provided network information is not a recognized format [#'.$line.']'; + $this->_error(self::INVALID_NETWORK, $error_msg); + $msg = '[SCORES] Application error: '.$error_msg; + if (false === $this->_throw) { + trigger_error($msg, E_USER_WARNING); + return false; + } else { + throw new Exception($msg); + } + } +} diff --git a/src/Scores/Validate/IpInNetwork.txt b/src/Scores/Validate/IpInNetwork.txt new file mode 100644 index 0000000..b7a6f2b --- /dev/null +++ b/src/Scores/Validate/IpInNetwork.txt @@ -0,0 +1,39 @@ +This validator class will test an IP against a provide network notation. The +network notation can be a network range, or network address with CIDR or 32-bit +decimal subnet mask notation. Note that the main validation method always uses +the CIDR notation, i.e a bitmask will be converted into a CIDR. + + +Examples for network notations +------------------------------ +Network Range: +************** +128.0.0.12-128.0.0.19 +true for all IP addresses inclusively in this range (i.e. from .12 to .19) + +CIDR notation: +************** +128.0.0.8/30 +block with 4 hosts +true for IP addresses from .8-.11 (i.e. .8, .9, .10, .11) + +Subnet mask notation: +********************* +128.0.0.8/255.255.255.252 +same as CIDR notation + +Special Notes: +-------------- +1) The network notation is validated, i.e. you have to pass a valid network and +CIDR or subnet mask combination. For the network range the two values must be +valid IP addresses. + +2) A CIDR notation of /32, subnet mask /255.255.255.255 or a range with two +equal addresses will match for one host, i.e. the result is true if the network +address or the range addresses are identical to the IP address + +3) The network notation or a range has to be set prior to calling isValid() as +is custom with all Zend validators. The notation can be set when instantiating +the object as an array and 'network' as the index. The setter method is +setNetworkNotation($notation) and expects a string as the argument. + \ No newline at end of file diff --git a/src/Scores/Wkhtml/Pdf.php b/src/Scores/Wkhtml/Pdf.php new file mode 100644 index 0000000..377b1e8 --- /dev/null +++ b/src/Scores/Wkhtml/Pdf.php @@ -0,0 +1,53 @@ +wkhtml = $c->profil->wkhtmltopdf->path; + } + + /** + * Défini les options supplémentaires à l'execution de wkhtmltopdf + * -n, --disable-javascript Do not allow webpages to run javascript. + * --disable-internal-links Do no make local links + * --disable-external-links Do no make links to remote web pages + * --user-style-sheet Specify a user style sheet, to load with every page. + * --print-media-type Use print media-type instead of screen. + * --header-left|right + * @param string $name + * @param string $value + */ + public function setOptions($name, $value = '') + { + $this->options[$name] = $value; + } + + /** + * Imprime un fichier HTML en PDF avec l'utilitaire wkhtmltopdf + * @param string $fileIn + * @param string $fileOut + * @return string Nom du fichier + */ + public function exec($fileIn, $fileOut = '') + { + if (empty($fileOut)) {$fileOut = str_replace('.html', '.pdf', $fileIn); } + if(file_exists($fileOut)){ unlink($fileOut); } + + $options = '--disable-internal-links'; + if ( count($this->options) ) + { + foreach ( $this->options as $name => $value ) + { + $options.= ' --'.$name; + if ($value!= '') $options.= ' "'.$value.'"'; + } + } + + $cmd = $this->wkhtml.' '.$options.' "'.$fileIn.'" "'.$fileOut.'"'; + exec( $cmd ); + return $fileOut; + } +} \ No newline at end of file diff --git a/src/Scores/Ws/Discover.php b/src/Scores/Ws/Discover.php new file mode 100644 index 0000000..82e6a1e --- /dev/null +++ b/src/Scores/Ws/Discover.php @@ -0,0 +1,84 @@ +serviceWsdl = $wsdl; + $this->serviceOptions = $options; + $this->setStructure(); + } + + public function getStructure() + { + return $this->serviceStructure; + } + + public function getStructureParam() + { + return $this->serviceStructureTypes; + } + + protected function setStructure() + { + $client = new Zend_Soap_Client( + $this->serviceWsdl, + $this->serviceOptions + ); + $this->serviceFunctions = $client->getFunctions(); + $this->serviceTypes = $client->getTypes(); + + foreach ($this->serviceFunctions as $func) { + $this->setFunction($func); + } + + foreach ($this->serviceTypes as $type) { + $this->setType($type); + } + } + + protected function setFunction($func) + { + if (preg_match('/[^\s]+\s([^\s]+)\((.*)\)/', $func, $matches)) { + $funcName = $matches[1]; + $funcParams = $matches[2]; + $this->serviceStructure[$funcName] = array(); + if (preg_match_all('/([^\s]+)\s([^\s]+),?/', $funcParams, $mParams)) { + $nbParams = count($mParams[0]); + for ($i=0;$i<$nbParams;$i++) { + $type = $mParams[1][$i]; + $name = $mParams[2][$i]; + $this->serviceStructure[$funcName][$i] = array( + 'name' => $name, + 'type' => $type + ); + } + } + } + } + + protected function setType($type) + { + $type = str_replace("\n", '', $type); + if (preg_match('/struct\s([^\s]+)\s\{(.*)\}$/m', $type, $matches)) { + $struct = trim($matches[1]); + $params = trim($matches[2]); + preg_match_all('/([^\s]+)\s([^\s]+);/', $params, $paramsMatches); + $nbParams = count($paramsMatches[0]); + $this->serviceStructureTypes[$struct] = array(); + for ($i=0; $i<$nbParams;$i++) { + $this->serviceStructureTypes[$struct][$i] = array( + 'name' => $paramsMatches[2][$i], + 'type' => $paramsMatches[1][$i], + ); + } + } + } +} diff --git a/src/Scores/Ws/Doc.php b/src/Scores/Ws/Doc.php new file mode 100644 index 0000000..943e6af --- /dev/null +++ b/src/Scores/Ws/Doc.php @@ -0,0 +1,181 @@ +serviceClass = $serviceClass; + $this->classmap = $classmap; + require_once $path . 'Service.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 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.= ''.$ref[2].''; + break; + case 'mysql': + $urlMysql = $view->url(array( + 'controller' => 'ref', + 'action' => 'table', + 'q' => $ref[3], + ), null, true); + $comment.= ''.$ref[2].''; + break; + } + $comment.= ', '; + } + } + $paramElement = array( + 'name' => $name, + 'type' => $type, + 'description' => trim($comment) + ); + } + $paramsElement[] = $paramElement; + } + $typesElement[$className] = $paramsElement; + } + $this->serviceTypes = $typesElement; + } + } +} diff --git a/src/Scores/Ws/Exception.php b/src/Scores/Ws/Exception.php new file mode 100644 index 0000000..f12b749 --- /dev/null +++ b/src/Scores/Ws/Exception.php @@ -0,0 +1,4 @@ +setName('soapform'); + $this->setAction('/demo/requete'); + $this->setMethod('post'); + $this->addElement('text', 'siret', array( + 'filters' => array('StringTrim'), + 'validators' => array( + array('stringLength', false, array(9, 14)), + array('NotEmpty', true), + ), + 'label' => 'Siret : ', + 'required' => 'true', + ) + ); + $this->addElement('submit', 'submit', array( + 'label' => 'Envoyez', + )); + } +} diff --git a/src/Scores/Ws/Server.php b/src/Scores/Ws/Server.php new file mode 100644 index 0000000..89736fc --- /dev/null +++ b/src/Scores/Ws/Server.php @@ -0,0 +1,1102 @@ + "Afficher les anciens NAF", + 'NACE' => "Afficher les codes NACES", + 'NEWS' => "Afficher les news Google©", + 'MAPPY' => "Afficher les façades d'immeubles", + 'CARTES' => "Afficher les cartes et les plans", + 'VOIRSURV' => "Afficher les entités sous surveillances", + 'DEMANDEREF' => "Demande de référence par defaut", + 'RECHREF' => "Afficher le formulaire de recherche par référence", + ); + + /** + * List logs for facturation + * @var array + */ + protected $logs = array( + 'identite' => array( + 'label' => "Identité" + ), + 'liens' => array( + 'label' => "Liens Inter-Entreprise" + ), + 'etablissements' => array( + 'label' => "Etablissements" + ), + 'dirigeants' => array( + 'label' => "Dirigeants" + ), + 'annonces' => array( + 'label' => "Annonces légales", + ), + 'indiscore' => array( + 'label' => "Indiscore", + ), + 'indiscorep' => array( + 'label' => "Indiscore+", + ), + 'indiscore2' => array( + 'label' => "Rapport", + ), + 'indiscore2p' => array( + 'label' => "Rapport avec suivi", + ), + 'indiscore3' => array( + 'label' => "Rapport complet", + ), + 'indiscore3p' => array( + 'label' => "Rapport complet avec suivi", + ), + 'evenements' => array( + 'label' => "Modifications Insee", + ), + 'tva' => array( + 'label' => "Numéro de TVA intracommunautaire", + ), + 'infosreg' => array( + 'label' => "Informations réglementées", + ), + 'bourse' => array( + 'label' => "Information boursière" + ), + 'bilan' => array( + 'label' => "Liasse fiscale", + ), + 'sirenExiste' => array( + 'label' => "Controle du SIREN", + ), + 'ratios' => array( + 'label' => "Ratios", + ), + 'rapport1' => array( + 'label' => "Rapport complet 1", + ), + 'rapport2' => array( + 'label' => "Rapport complet 2", + ), + 'rapport3' => array( + 'label' => "Rapport complet 3", + ), + 'banque' => array( + 'label' => "Relations banquaires", + ), + 'competences' => array( + 'label' => "Competences territoriales", + ), + 'privdetail' => array( + 'label' => "Détails des privilèges", + ), + 'privcumul' => array( + 'label' => "Privilèges cumulés", + ), + 'conventions' => array( + 'label' => "Conventions collectives", + ), + 'marques' => array( + 'label' => "Marques déposés", + ), + 'kbis' => array( + 'label' => "Extrait RCS", + ), + 'dirigeantsop' => array( + 'label' => "Dirigeants opérationels", + ), + 'groupesarbo' => array( + 'label' => "Arborescence de groupes", + ), + 'groupeinfos' => array( + 'label' => "Informations groupe", + ), + 'valorisation' => array( + 'label' => "Valorisation", + ), + 'rnvp' => array( + 'label' => "Normalisation postale", + ), + ); + + /** + * List of error code send as SoapFault + * @var unknown_type + */ + public $listError = array( + '0000' => "Erreur indeterminé", + '0900' => "Identifiant ou mot de passe incorrect", + '0901' => "Accès WS non autorisé pour cet utilisateur", + '0902' => "Méthode non autorisée dans votre profil", + '0903' => "Période d'accès au service invalide", + '0904' => "Adresse IP Invalide", + '0905' => "Accès environnement de test non autorisé", + '0906' => "Erreur configuration utilisateur", + '1010' => "Siren invalide", + '1011' => "Identifiant invalide", + '1020' => "Siren inexistant", + '1021' => "Type d'identifiant inexistant", + '1030' => "Aucun résultat pour ce siren en base", + '3000' => "Service disponible", + '9000' => "Service S&D indisponible", + '9001' => "Service partenaire indisponible", + '9002' => "Méthode provisoirement indisponible", + '9003' => "Version du service désactivé", + '9004' => "Version du service inexistant", + '9010' => "Fichier indisponible", + '9020' => "Requête incorrecte", + ); + + /** + * PDO Connection with Doctrine + * @var \Doctrine\DBAL\Connection + */ + protected $conn; + + /** + * Logger + * @var \Monolog\Logger + */ + protected $logger; + + /** + * Server SOAP + * Document/Literal Wrapped - WS-I Compliant + */ + public function __construct() + { + $this->conn = Zend_Registry::get('doctrine'); + + if (Zend_Registry::isRegistered('logger')) { + $this->logger = Zend_Registry::get('logger'); + } + + $this->listeDroits = include APPLICATION_PATH . '/../library/Scores/Account/Access.php'; + $this->listeCategory = include APPLICATION_PATH . '/../library/Scores/Account/Category.php'; + } + + /** + * Send SoapFault with code and messade define + * @param string $code + * @throws SoapFault + */ + protected function sendError($code) + { + $message = 'Erreur inconnue'; + if (array_key_exists($code, $this->listError)) { + $message = $this->listError[$code]; + } + throw new SoapFault($code, $message); + exit; + } + + /** + * Enregistre l'appel utilisateur à une méthode + * @param $service + * @param $siret + * @param $ref + * @return void + */ + protected function wsLog($service, $siret = '', $ref = '') + { + //Is it a test + if ($this->User->clientTest=='Oui' || $this->User->typeCompte=='TEST') { + $test = 1; + } else { + $test = 0; + } + + $siren = 0; + if (strlen($siret) == 14) { + $siren = substr($siret, 0, 9); + $nic = substr($siret, 9, 5); + } elseif (strlen($siret) == 9) { + $siren = $siret; + $nic = ''; + } + + // Set data by default + $dataInsert = array( + 'login' => $this->User->login, + 'page' => $service, + 'params' => $ref, + 'idClient' => $this->User->idClient, + 'test' => $test, + 'actifInsee' => 0, + 'source' => 0, + 'raisonSociale' => '', + 'cp' => '', + 'ville' => '', + 'ipClient' => $this->User->ipConnexion, + ); + + $pageRS = array( + 'identite', + 'greffe_bilans', + 'greffe_actes', + 'liens', + 'dirigeants', + 'etablissements', + 'dirigeantsOp', + 'kbis', + 'indiscore', + 'indiscore2', + 'indiscore3', + 'rapport2', + 'rapport3' + ); + + if (intval($siren)!=0) { + $dataInsert['siren'] = $siren; + $dataInsert['nic'] = $nic; + } + + if (intval($siren)!=0 && in_array($service, $pageRS)) { + $qb = $this->conn->createQueryBuilder(); + $qb->select(array('e.siren', 'e.nic', 'e.actif', 'e.siege', 'e.raisonSociale', + 'e.adr_cp', 'e.adr_ville', 'e.source', 'COUNT(r.siren) AS nb')) + ->from('jo.etablissements', 'e') + ->where('e.siren = :siren')->setParameter('siren', $siren) + ->rightJoin('e', 'jo.rncs_entrep', 'r', 'e.siren = r.siren'); + + if (intval($siren) > 1000 && intval($nic) > 9) { + $qb->andWhere('e.nic = :nic')->setParameter('nic', $nic); + } elseif (intval($siren) == 0 && $ref > 0) { + $qb->andWhere('e.id = :id')->setParameter('id', $ref); + } elseif (intval($siren) > 1000) { + $qb->andWhere('e.siege = 1')->orderBy('e.actif', 'DESC')->orderBy('e.nic', 'DESC'); + } else { + return; + } + + try { + $stmt = $qb->execute(); + if ($stmt->rowCount() > 0) { + $result = $stmt->fetch(\PDO::FETCH_OBJ); + $dataInsert['raisonSociale'] = $result->raisonSociale; + $dataInsert['cp'] = $result->adr_cp; + $dataInsert['ville'] = $result->adr_ville; + $dataInsert['source'] = $result->source; + if ($result->actif == 0) { + $dataInsert['actifInsee'] = 0; + } elseif (intval($siren) > 1000) { + $dataInsert['actifInsee'] = 1; + if ($result->nb > 0) { + $dataInsert['source'] = 5; + } + } + } + } catch (\Doctrine\DBAL\DBALException $e) { + } + } + + try { + $this->conn->insert('sdv1.logs', $dataInsert); + } catch (\Doctrine\DBAL\DBALException $e) { + } + } + + /** + * Authenticate with SoapHeader, Optional (Authentication could be done by sending HTTP Basic header - see the doc) + * @param string $username + * @param string $password + * @throws SoapFault + */ + public function authenticate($username = null, $password = null) + { + if ($this->authenticated === false) { + if (empty($username)) { + /** + * @todo : Digest auth + */ + $this->authMethod = 'basic'; + $username = $_SERVER['PHP_AUTH_USER']; + $password = $_SERVER['PHP_AUTH_PW']; + } else { + /** + * Auth Header in client + * $ns = 'auth'; + * //Create our Auth Object to pass to the SOAP service with our values + * $auth = new StdClass(); + * $auth->username = 'yourlogin'; + * $auth->password = 'yourpassword'; + * $creds = new SoapVar($auth, SOAP_ENC_OBJECT); + * + * //The 2nd variable, 'authenticate' is a method that exists inside of the SOAP service (you must create it, see next example) + * $authenticate = new SoapHeader($ns, 'authenticate', $creds, false); + * + * $client->__setSoapHeaders($authenticate); + * + */ + $this->authMethod = 'soapheader'; + } + + /** + * With proxy get the original IP + * $request->getClientIp(true); + * Si IP Proxy regarder la valeur HTTP_X_FORWARDED_FOR + */ + $ip = $_SERVER['REMOTE_ADDR']; + if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && in_array($ip, $this->listProxyIp)) { + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } + + /** + * Lors d'une demande d'authentification depuis une application on garde l'IP en mémoire, + * c'est donc celle là qu'il faut utiliser. + */ + if ($this->authIp !== null) { + $ip = $this->authIp; + } + + /** + * Check authentication from the database + */ + $this->authenticated = $this->checkAuth($username, $password, $ip); + if ($this->authenticated === false) { + $this->sendError('0900'); + } elseif (is_string($this->authenticated)) { + $this->sendError($this->authenticated); + } + } + } + + /** + * Check permission + * @param string $perm + */ + protected function permission($perm) + { + if (!$this->checkPerm($perm)) { + $this->sendError('0902'); + } + } + + /** + * Check if user has the right to access WebService + * @throws SoapFault + */ + protected function checkAccesWS() + { + //Vérifier que l'utilisateur à le droit accesWS (clients/utilisateurs) + $accesWs = $this->User->accesWS; + if ($accesWs) { + $this->sendError('0901'); + } + } + + /** + * Check if the user has the right to acces this functionality + * @param string $perm + * @throws SoapFault + */ + protected function checkPerm($perm) + { + $output = false; + $droits = $this->User->droits; + if (is_array($droits)) { + if (in_array(strtolower($perm), $droits)) { + $output = true; + } + } else { + if (preg_match('/\b'.$perm.'\b/i', $droits)) { + $output = true; + } + } + + return $output; + } + + /** + * Check if the user could edit data + */ + protected function checkEdition() + { + if ($this->User->idClient == 1) { + return true; + } + + if ($this->checkPerm('edition')) { + return true; + } + + return false; + } + + + /** + * checkAuth + * @param string $login + * @param string $password + * @param string $ipConnexion + * @return mixed + */ + protected function checkAuth($login, $password, $ip) + { + if (empty($login)) { + $this->sendError('0900'); + } + + /** + * User information + */ + try { + $qb = $this->conn->createQueryBuilder(); + $qb->select(array( + 'u.login', 'u.id', 'u.email', 'u.password', 'u.idClient', 'u.typeCompte', 'u.actif', + 'u.filtre_ip', 'u.profil', 'u.civilite', 'u.nom', 'u.prenom', 'u.tel', 'u.fax', + 'u.mobile', 'u.pref', 'u.rechRefType', 'u.profil', 'u.nombreConnexions', + 'u.dateDerniereConnexion', 'u.droits', 'u.referenceParDefaut', 'u.nbReponses', 'u.lang', + 'u.formatMail', 'u.dateDebutCompte', 'u.dateFinCompte', 'u.accesWS', 'u.acceptationCGU', + 'c.droits AS droitsClients', 'c.test AS clientTest', 'c.typeScore', 'c.timeout', + 's.Service AS serviceCode', 'v.version')) + ->from('sdv1.utilisateurs', 'u') + ->join('u', 'sdv1.clients', 'c', 'u.idClient = c.id') + ->leftJoin('u', 'sdv1.utilisateurs_service', 's', 'u.login=s.login') + ->leftJoin('u', 'sdv1.clients_version', 'v', 'u.idClient=v.clientId') + ->where('u.actif = 1')->andWhere('u.deleted = 0')->andWhere("c.actif = 'Oui'"); + + /** + * Connexion avec login = email + */ + if (strstr($login, '@') !== false) { + $qb->andWhere('u.email = :email')->setParameter('email', $login); + } + /** + * Connexion standard + */ + else { + $qb->andWhere('u.login = :login')->setParameter('login', $login); + } + $stmt = $qb->execute(); + } catch (\Doctrine\DBAL\DBALException $e) { + } + + /** + * No user, deleted or disable + */ + if ($stmt->rowCount() == 0) { + return false; + } + + /** + * Multiple compte + */ + if ($stmt->rowCount() > 1) { + return '0906'; + } + + /** + * Get Data + */ + try { + $result = $stmt->fetch(\PDO::FETCH_OBJ); + } catch (\Doctrine\DBAL\DBALException $e) { + if ($this->logger != null) { + $this->logger->error("AUTH : ".$e->getMessage()); + } + return '0000'; + } + + /** + * Date de debut de compte + */ + if (!empty($result->dateDebutCompte) && $result->dateDebutCompte!='0000-00-00') { + $today = mktime(0, 0, 0, date('m'), date('d'), date('Y')); + $dateDebutCompte = mktime(0, 0, 0, substr($result->dateDebutCompte, 5, 2), substr($result->dateDebutCompte, 8, 2), substr($result->dateDebutCompte, 0, 4)); + if ($today < $dateDebutCompte) { + return '0903'; + } + } + + /** + * Date de fin de compte + */ + if (!empty($result->dateFinCompte) && $result->dateFinCompte!='0000-00-00') { + $today = mktime(0, 0, 0, date('m'), date('d'), date('Y')); + $dateFinCompte = mktime(0, 0, 0, substr($result->dateFinCompte, 5, 2), substr($result->dateFinCompte, 8, 2), substr($result->dateFinCompte, 0, 4)); + if ($today > $dateFinCompte) { + return '0903'; + } + } + + /** + * Service fallback + */ + if ($result->serviceCode === null) { + $result->serviceCode = 'DEFAULT'; + } + + /** + * Select authentication version + */ + if ($result->version == 2) { + $authResult = $this->authV2($result, $password, $ip); + } else { + $authResult = $this->authV1($result, $password, $ip); + } + + $this->authLog($result->login, $authResult, $ip); + + return $authResult; + } + + /** + * Authentification v1 + * @param object $userInfos + * @param string $password + * @param string $ip + * @return string|boolean + */ + protected function authV1($userInfos, $password, $ip) + { + /** + * Acces WS, block access to other apps + */ + if ($userInfos->accesWS == 1 && $userInfos->idClient != 1) { + // --- Webservice user don't need access to others apps + if (in_array($ip, $this->listApplicationIp)) { + return '0901'; + } elseif ($ip != '127.0.0.1') { + + // --- For customized version, check user is in the good service + $clients = include APPLICATION_PATH . '/../library/WsScore/Clients/ClientsConfig.php'; + $wsClients = array(); + foreach ($clients as $section => $params) { + if ($params['actif']) { + if (count($params['idClient']) > 0) { + foreach ($params['idClient'] as $idClient) { + $wsClients[$idClient] = $section; + } + } + } + } + if (array_key_exists($userInfos->idClient, $wsClients) && ($this->serviceClient === false + || strtolower($this->serviceClientName) != $wsClients[$userInfos->idClient])) { + return '0901'; + } + } + } + + /** + * Protect staging environment + * - No webservice access + * - Not in production + * - Not idClient 1 or 147 + */ + if (APPLICATION_ENV=='staging' && !in_array($userInfos->idClient, array(1, 147)) && $userInfos->accesWS==0) { + return '0905'; + } + + /** + * IP Validation + * Get an array of IP and IP range + * 192.168.3.5-192.68.3.10;192.168.3.*;192.168.3.10 + */ + + if (!in_array($ip, $this->listApplicationIp)) { + if (!empty($userInfos->filtre_ip)) { + $filtreIp = explode(';', trim($userInfos->filtre_ip, ';')); + if (count($filtreIp)>0) { + + // Extranet + if (substr($password, 0, 7)=='iponly:') { + $ipToValidate = substr($password, 7); + } + // WebService + else { + $ipToValidate = $ip; + } + + //Validation + $overallIpValidate = false; + foreach ($filtreIp as $filtre) { + if (strpos($filtre, '*')) { + $filtre = str_replace('*', '0', $filtre) . '-' . str_replace('*', '255', $filtre); + } + // Is it a range ? + if (strpos($filtre, '-')) { + $validateIp = new Scores_Validate_IpInNetwork(); + $validateIp->setNetworkNotation($filtre); + $overallIpValidate = $validateIp->isValid($ipToValidate); + } + // Ip only + else { + if ($filtre === $ipToValidate) { + $overallIpValidate = true; + } + } + // Break foreach + if ($overallIpValidate === true) { + break; + } + } + + // Exit with error + if ($overallIpValidate === false) { + return '0904'; + } + } + } + } + + // Check password with database informations + if ($userInfos->password == $password //password sent in clear + || md5($userInfos->password) == $password //password sent with md5 + || md5($userInfos->login.'|'.$userInfos->password) == $password //password sent concat with login and crypt by md5 + || substr($password, 0, 7) == 'iponly:' + ) { + + //Timeout + $timeout = $userInfos->timeout; + if ($timeout==0) { + $timeout = 1800; + } + + //Infos utilisateur + $this->User = new stdClass(); + $this->User->login = $userInfos->login; + $this->User->id = $userInfos->id; + $this->User->civilite = $userInfos->civilite; + $this->User->nom = $userInfos->nom; + $this->User->prenom = $userInfos->prenom; + $this->User->tel = $userInfos->tel; + $this->User->fax = $userInfos->fax; + $this->User->mobile = $userInfos->mobile; + $this->User->email = $userInfos->email; + $this->User->typeCompte = $userInfos->typeCompte; + $this->User->idClient = $userInfos->idClient; + $this->User->serviceCode = $userInfos->serviceCode; + $this->User->filtre_ip = $userInfos->filtre_ip; + $this->User->ipConnexion = $ip; + $this->User->pref = $userInfos->pref; + $this->User->rechRefType = $userInfos->rechRefType; + $this->User->profil = $userInfos->profil; + $this->User->nombreConnexions = $userInfos->nombreConnexions; + $this->User->dateDerniereConnexion = $userInfos->dateDerniereConnexion; + // Droits + $this->User->droits = array(); + $droits = explode(" ", $userInfos->droits); + if (count($droits) > 0) { + foreach ($droits as $droits) { + $this->User->droits[] = $droits; + } + } else { + //Inclure les droits du service ? + } + $this->User->droitsClients = $userInfos->droitsClients; + $this->User->timeout = $timeout; + $this->User->clientTest = $userInfos->clientTest; + $this->User->typeScore = $userInfos->typeScore; + $this->User->nbReponses = $userInfos->nbReponses; + $this->User->lang = $userInfos->lang; + $this->User->formatMail = $userInfos->formatMail; + $this->User->referenceParDefaut = $userInfos->referenceParDefaut; + $this->User->dateDebutCompte = $userInfos->dateDebutCompte; + $this->User->dateFinCompte = $userInfos->dateFinCompte; + $this->User->acceptationCGU = $userInfos->acceptationCGU; + $this->User->version = $userInfos->version; + + return true; + } + + return false; + } + + /** + * Authentification v2 + * @param object $userInfos + * @param string $credential + * @param string $ip + * @return string|boolean + */ + protected function authV2($userInfos, $credential, $ip) + { + $result = null; + try { + $sql = "SELECT * FROM sdv1.clients_services + WHERE IdClient = :client AND Code = :service"; + $stmt = $this->conn->prepare($sql); + $stmt->bindValue('client', $userInfos->idClient); + $stmt->bindValue('service', $userInfos->serviceCode); + $stmt->execute(); + if ($stmt->rowCount() > 0) { + $result = $stmt->fetch(\PDO::FETCH_OBJ); + } + } catch (\Doctrine\DBAL\DBALException $e) { + } + + // Aucun service + if ($result === null) { + return '0906'; + } + + // Service inactif + if ($result->Active == 0) { + return '0906'; + } + + // Block WebService User on Apps + if ($result->AppWebservice == 1 && $this->authApp !== null && $userInfos->idClient != 1) { + return '0901'; + } + + // WebService customize version + if ($result->AppWebservice == 1) { + // For customized version, check user is in the good service + $clients = include APPLICATION_PATH . '/../library/WsScore/Clients/ClientsConfig.php'; + foreach ($clients as $section => $params) { + if ($params['actif']) { + $wsClients[$params['idClient']] = $section; + } + } + if (array_key_exists($userInfos->idClient, $wsClients) + && ($this->serviceClient == false + || strtolower($this->serviceClientName) != $wsClients[$userInfos->idClient])) { + return '0901'; + } + } + + // Infos utilisateur + $this->User = new stdClass(); + $this->User->login = $userInfos->login; + $this->User->id = $userInfos->id; + $this->User->civilite = $userInfos->civilite; + $this->User->nom = $userInfos->nom; + $this->User->prenom = $userInfos->prenom; + $this->User->tel = $userInfos->tel; + $this->User->fax = $userInfos->fax; + $this->User->mobile = $userInfos->mobile; + $this->User->email = $userInfos->email; + $this->User->typeCompte = $userInfos->typeCompte; + $this->User->idClient = $userInfos->idClient; + $this->User->serviceCode = $userInfos->serviceCode; + $this->User->ipConnexion = $ip; + $this->User->pref = $userInfos->pref; + $this->User->rechRefType = $userInfos->rechRefType; + $this->User->profil = $userInfos->profil; + // Droits + $this->User->droits = array(); + $droits = explode(" ", $userInfos->droits); + if (count($droits) > 0) { + foreach ($droits as $droits) { + $this->User->droits[] = $droits; + } + } + $this->User->clientTest = $userInfos->clientTest; + $this->User->typeScore = $userInfos->typeScore; + $this->User->nbReponses = $userInfos->nbReponses; + $this->User->lang = $userInfos->lang; + $this->User->formatMail = $userInfos->formatMail; + $this->User->referenceParDefaut = $userInfos->referenceParDefaut; + $this->User->dateDebutCompte = $userInfos->dateDebutCompte; + $this->User->dateFinCompte = $userInfos->dateFinCompte; + $this->User->acceptationCGU = $userInfos->acceptationCGU; + $this->User->version = $userInfos->version; + + // Add Service Parameter to user definition + $this->User->typeScore = $result->TypeScore; + $this->User->timeout = $result->Timeout; + + /** + * Type de connexion + * userPassword => Vérifier le mot de passe + * userPasswordCrypt => Vérifier le mot de passe crypté + * userIP => Vérifier uniquement l'utilisateur et son IP de connexion + */ + switch ($result->TypeAcces) { + case 'userPassword': + if ($this->authIP($ip) === false) { + return '0904'; + } + if ($this->authPassword($userInfos, $credential) === true) { + if (count($this->User->droits) > 0) { + $this->User->droits = $this->getAccessList( + $userInfos->idClient, + $userInfos->serviceCode + ); + } + return true; + } + break; + case 'userPasswordCrypt': + if ($this->authIP($ip) === false) { + return '0904'; + } + if ($this->authPasswordCrypt($userInfos, $credential) === true) { + if (count($this->User->droits) > 0) { + $this->User->droits = $this->getAccessList( + $userInfos->idClient, + $userInfos->serviceCode + ); + } + return true; + } + break; + case 'userIP': + if (substr($credential, 0, 7) == 'iponly:') { + $ip = substr($credential, 7); + if ($this->authIP($ip) === true) { + if (count($this->User->droits) > 0) { + $this->User->droits = $this->getAccessList( + $userInfos->idClient, + $userInfos->serviceCode + ); + } + return true; + } + } + break; + } + + return false; + } + + /** + * Check password + * @todo : + * Check how password is check + * md5 => standard method md5 ( login | password ) + * key => get associated key with crypt method + * cert => get associated certificat + * @param unknown $userInfos + * @param unknown $password + * @return boolean + */ + protected function authPassword($userInfos, $password) + { + if (md5($userInfos->login.'|'.$userInfos->password) == $password) { + return true; + } + + if (md5($userInfos->password) == $password) { + return true; + } + + if ($userInfos->password == $password) { + return true; + } + + return false; + } + + /** + * Check password + * @param object $userInfos + * @param string $password + */ + protected function authPasswordCrypt($userInfos, $password) + { + if (substr($password, 0, 4) == '$2y$' + && strlen($password) == 60 + && $password == $userInfos->password) { + return true; + } + + if (password_verify($password, $userInfos->password) === true) { + return true; + } + + return false; + } + + /** + * Check ip + * @param string $ip + * @return string + */ + protected function authIP($ip) + { + //Check IP + if (!in_array($ip, $this->listApplicationIp)) { + try { + $sql = "SELECT IP FROM sdv1.clients_services_ip + WHERE IdClient = :client AND Service = :service"; + $stmt = $this->conn->prepare($sql); + $stmt->bindValue('client', $this->User->idClient); + $stmt->bindValue('service', $this->User->serviceCode); + $stmt->execute(); + if ($stmt->rowCount() > 0) { + $ipResult = $stmt->fetchAll(\PDO::FETCH_OBJ); + //Validation + $overallIpValidate = false; + foreach ($ipResult->IP as $filtre) { + if (trim($filtre) != '') { + // Is it a range ? + if (strpos($filtre, '-')) { + $validateIp = new Scores_Validate_IpInNetwork(); + $validateIp->setNetworkNotation($filtre); + $overallIpValidate = $validateIp->isValid($ip); + } + // Ip only + else { + if ($filtre === $ip) { + $overallIpValidate = true; + } + } + // Break foreach + if ($overallIpValidate === true) { + break; + } + } + } + // Exit with error + if ($overallIpValidate === false) { + return '0904'; + } + } + } catch (\Doctrine\DBAL\DBALException $e) { + } + } + } + + /** + * Log les erreurs d'authentification + * @param mixed $result + * @param string $ip + * @return void + */ + protected function authLog($login, $result, $ip) + { + $authenticate = null; + if ($result === false) { + $authenticate = 'KO'; + } elseif (is_string($result)) { + $authenticate = $result; + } + if ($authenticate !== null) { + $data = array( + 'login' => $login, + 'authenticate' => $authenticate, + 'ip' => $ip, + 'dateInsert' => date('YmdHis'), + ); + try { + $this->conn->insert('sdv1.utilisateurs_auth_log', $data); + } catch (\Doctrine\DBAL\DBALException $e) { + } + } + } + + /** + * Get Service Access List + * @param int $clientId + * @param string $serviceCode + * @return array + */ + protected function getAccessList($clientId, $serviceCode) + { + $list = array(); + try { + $sql = "SELECT Acces FROM sdv1.clients_services_droits + WHERE IdClient = :client AND Service = :service"; + $stmt = $this->conn->prepare($sql); + $stmt->bindValue('client', $this->User->idClient); + $stmt->bindValue('service', $this->User->serviceCode); + $stmt->execute(); + if ($stmt->rowCount() > 0) { + $accesResult = $stmt->fetchAll(\PDO::FETCH_OBJ); + foreach ($accesResult as $row) { + $list[] = $row->Acces; + } + } + } catch (\Doctrine\DBAL\DBALException $e) { + } + + return $list; + } + + protected function trigger($event, $args) + { + //Est ce que l'utilisateur à un trigger + + //Pour chaque trigger - Executer l'action + } +} diff --git a/src/Scores/Ws/Trigger.php b/src/Scores/Ws/Trigger.php new file mode 100644 index 0000000..0819586 --- /dev/null +++ b/src/Scores/Ws/Trigger.php @@ -0,0 +1,131 @@ +event = $event; + $this->userInfos = $userInfos; + $this->conn = Zend_Registry::get('doctrine'); + } + + /** + * Check if we have a trigger to execute + * @return number + */ + protected function hasTrigger() + { + if ($this->userInfos['Service'] === null) { + $service = 'default'; + } + + $sql = "SELECT * FROM sdv1.clients_services_trigger + WHERE idClient=:client AND service=:service AND (login=:login OR login='')"; + $stmtNb = 0; + try { + $stmt = $this->conn->prepare($sql); + $stmt->execute(); + $stmtNb = $stmt->rowCount(); + } catch (\Doctrine\DBAL\DBALException $e) { + if ($this->logger !== null) { + $this->logger->error($e->getMessage()); + } + } + if ($stmtNb > 0) { + while ($item = $stmt->fetch(PDO::FETCH_OBJ)) { + $tmp->action = $item->action; + $tmp->params = json_decode($item->actionParams, true); + $this->events[] = $tmp; + } + } + + return $stmtNb; + } + + /** + * Execute all triggers after hasTrigger + * @param array $args + * @return boolean + */ + protected function executeAllTrigger($args) + { + if (count($this->events)>0) { + foreach ($this->events as $action) { + $args = array_merge($args, $action->params); + switch ($action->action) { + case 'surveillance': + return $this->surveillance($args); + break; + } + } + } + } + + /** + * Mise en surveillance automatique + * @param array $args + * source, siren, ... + * @return boolean + */ + protected function surveillance($args) + { + if (!array_key_exists('source', $args)) { + return false; + } + + if (!array_key_exists('siren', $args)) { + return false; + } + + if (!array_key_exists('nic', $args)) { + return false; + } + + if (empty(trim($this->userInfos['email']))) { + return false; + } + + if (array_key_exists('ref', $args)) { + $ref = $args['ref']; + } + + try { + $this->conn->insert('jo.surveillances_site', array( + 'source' => $args['source'], + 'login' => $this->userInfos['login'], + 'email' => $this->userInfos['email'], + 'siren' => $args['siren'], + 'nic' => $args['nic'], + 'ref' => $ref, + 'encoursClient' => 0, + 'rs' => $args['Nom'], + 'cp' => $args['CP'], + 'ville' => $args['Ville'], + 'dateAjout' => date('Y-m-d'), + 'dateSuppr' => 0, + )); + return true; + } catch (\Doctrine\DBAL\DBALException $e) { + if ($this->logger !== null) { + $this->logger->error($e->getMessage()); + } + } + + return false; + } +}