TYPO3 API  SVNRelease
class.tx_linkvalidator_tasks_validator.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 2010 - 2011 Michael Miousse (michael.miousse@infoglobe.ca)
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *
00017  *  This script is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *  GNU General Public License for more details.
00021  *
00022  *  This copyright notice MUST APPEAR in all copies of the script!
00023  ***************************************************************/
00024 
00025 /**
00026  * This class provides Scheduler plugin implementation.
00027  *
00028  * @author Michael Miousse <michael.miousse@infoglobe.ca>
00029  * @package TYPO3
00030  * @subpackage linkvalidator
00031  */
00032 class tx_linkvalidator_tasks_Validator extends tx_scheduler_Task {
00033 
00034     /**
00035      * @var integer
00036      */
00037     protected $sleepTime;
00038 
00039     /**
00040      * @var integer
00041      */
00042     protected $sleepAfterFinish;
00043 
00044     /**
00045      * @var integer
00046      */
00047     protected $countInARun;
00048 
00049     /**
00050      * Total number of broken links.
00051      *
00052      * @var integer
00053      */
00054     protected $totalBrokenLink = 0;
00055 
00056     /**
00057      * Total number of broken links from the last run.
00058      *
00059      * @var integer
00060      */
00061     protected $oldTotalBrokenLink = 0;
00062 
00063     /**
00064      * Mail template fetched from the given template file.
00065      *
00066      * @var string
00067      */
00068     protected $templateMail;
00069     
00070     /**
00071      * specific TSconfig for this task.
00072      *
00073      * @var array
00074      */
00075     protected $configuration = array();
00076 
00077     /**
00078      * Shows if number of result was diferent from the result of the last check or not.
00079      *
00080      * @var boolean
00081      */
00082     protected $dif;
00083 
00084     /**
00085      * Template to be used for the email.
00086      *
00087      * @var string
00088      */
00089     protected $emailTemplateFile;
00090 
00091     /**
00092      * Level of pages the task should check.
00093      *
00094      * @var integer
00095      */
00096     protected $depth;
00097 
00098     /**
00099      * UID of the start page for this task.
00100      *
00101      * @var integer
00102      */
00103     protected $page;
00104 
00105     /**
00106      * Email address to which an email report is sent.
00107      *
00108      * @var string
00109      */
00110     protected $email;
00111     
00112     /**
00113      * Only send an email, if new broken links were found.
00114      *
00115      * @var boolean
00116      */
00117     protected $emailOnBrokenLinkOnly;
00118 
00119     /**
00120      * Get the value of the protected property email.
00121      *
00122      * @return  string      Email address to which an email report is sent
00123      */
00124     public function getEmail() {
00125         return $this->email;
00126     }
00127     
00128     /**
00129      * Set the value of the private property email.
00130      *
00131      * @param  string       Email address to which an email report is sent
00132      * @return void
00133      */
00134     public function setEmail($email) {
00135         $this->email=$email;
00136     }
00137     
00138     /**
00139      * Get the value of the protected property emailOnBrokenLinkOnly.
00140      *
00141      * @return  boolean      Only send an email, if new broken links were found.
00142      */
00143     public function getEmailOnBrokenLinkOnly() {
00144         return $this->emailOnBrokenLinkOnly;
00145     }
00146     
00147     /**
00148      * Set the value of the private property emailOnBrokenLinkOnly.
00149      *
00150      * @param  boolean      Only send an email, if new broken links were found.
00151      * @return void
00152      */
00153     public function setEmailOnBrokenLinkOnly($emailOnBrokenLinkOnly) {
00154         $this->emailOnBrokenLinkOnly = $emailOnBrokenLinkOnly;
00155     }
00156     
00157     /**
00158      * Get the value of the protected property page.
00159      *
00160      * @return  integer      UID of the start page for this task.
00161      */
00162     public function getPage() {
00163         return $this->page;
00164     }
00165     
00166     /**
00167      * Set the value of the private property page.
00168      *
00169      * @param  integer      UID of the start page for this task.
00170      * @return void
00171      */
00172     public function setPage($page) {
00173         $this->page =$page;
00174     }
00175     
00176     /**
00177      * Get the value of the protected property depth.
00178      *
00179      * @return  integer     Level of pages the task should check.
00180      */
00181     public function getDepth() {
00182         return $this->depth;
00183     }
00184     
00185     /**
00186      * Set the value of the private property depth.
00187      *
00188      * @param  integer     Level of pages the task should check.
00189      * @return void
00190      */
00191     public function setDepth($depth) {
00192         $this->depth = $depth;
00193     }
00194     
00195     /**
00196      * Get the value of the protected property emailTemplateFile.
00197      *
00198      * @return  string    Template to be used for the email.
00199      */
00200     public function getEmailTemplateFile() {
00201         return $this->emailTemplateFile;
00202     }
00203     
00204     /**
00205      * Set the value of the private property emailTemplateFile.
00206      *
00207      * @param  string    Template to be used for the email.
00208      * @return void
00209      */
00210     public function setEmailTemplateFile($emailTemplateFile) {
00211         $this->emailTemplateFile = $emailTemplateFile;
00212     }
00213     
00214     /**
00215      * Get the value of the protected property configuration.
00216      *
00217      * @return  array    specific TSconfig for this task.
00218      */
00219     public function getConfiguration() {
00220         return $this->configuration;
00221     }
00222     
00223     /**
00224      * Set the value of the private property configuration.
00225      *
00226      * @param  array    specific TSconfig for this task.
00227      * @return void
00228      */
00229     public function setConfiguration($configuration) {
00230         $this->configuration = $configuration;
00231     }
00232     
00233     
00234     /**
00235      * Function executed from the Scheduler.
00236      *
00237      * @return  void
00238      */
00239     public function execute() {
00240         $this->setCliArguments();
00241         $successfullyExecuted = TRUE;
00242         if (!file_exists($file = t3lib_div::getFileAbsFileName($this->emailTemplateFile)) && !empty($this->email)) {
00243             throw new Exception(
00244                 $GLOBALS['LANG']->sL('LLL:EXT:linkvalidator/locallang.xml:tasks.error.invalidEmailTemplateFile'),
00245                 '1295476972'
00246             );
00247         }
00248         $htmlFile = t3lib_div::getURL($file);
00249         $this->templateMail = t3lib_parsehtml::getSubpart($htmlFile, '###REPORT_TEMPLATE###');
00250 
00251             // The array to put the content into
00252         $html = array();
00253         $pageSections = '';
00254         $this->dif = FALSE;
00255         $pageList = t3lib_div::trimExplode(',', $this->page, 1);
00256         if (is_array($pageList)) {
00257             foreach ($pageList as $page) {
00258                 $modTS = t3lib_BEfunc::getModTSconfig($page, 'mod.linkvalidator');
00259                 $parseObj = t3lib_div::makeInstance('t3lib_TSparser');
00260                 $parseObj->parse($this->configuration);
00261                 if(count($parseObj->errors) > 0){
00262                     $parseErrorMessage = $GLOBALS['LANG']->sL('LLL:EXT:linkvalidator/locallang.xml:tasks.error.invalidTSconfig') . '<br />';
00263                     foreach($parseObj->errors as $errorInfo){
00264                         $parseErrorMessage .= $errorInfo[0] . '<br />';
00265                     }
00266                     throw new Exception(
00267                         $parseErrorMessage,
00268                         '1295476989'
00269                     );
00270                 }
00271                 $TSconfig = $parseObj->setup;
00272                 $modTS = $modTS['properties'];
00273                 $overrideTs = $TSconfig['mod.']['tx_linkvalidator.'];
00274                 if (is_array($overrideTs)) {
00275                     $modTS = t3lib_div::array_merge_recursive_overrule($modTS, $overrideTs);
00276                 }
00277 
00278                     // get the searchFields from TCA
00279                 foreach ($GLOBALS['TCA'] as $tableName => $table) {
00280                     if (!empty($table['columns'])) {
00281                         foreach ($table['columns'] as $columnName => $column) {
00282                             if ($column['config']['type'] == 'text' || $column['config']['type'] == 'input') {
00283                                 if (!empty($column['config']['softref']) && (stripos($column['config']['softref'], "typolink")
00284                                         !== FALSE || stripos($column['config']['softref'], "url") !== FALSE)) {
00285 
00286                                     $searchFields[$tableName][] = $columnName;
00287                                 }
00288                             }
00289                         }
00290                     }
00291                 }
00292 
00293                     // get the searchFields from TypoScript
00294                 foreach ($modTS['searchFields.'] as $table => $fieldList) {
00295                     $fields = t3lib_div::trimExplode(',', $fieldList);
00296                     foreach ($fields as $field) {
00297                         if (is_array($searchFields[$table])) {
00298                             if (array_search($field, $searchFields[$table]) === FALSE) {
00299                                 $searchFields[$table][] = $field;
00300                             }
00301                         }
00302                     }
00303                 }
00304                 $linkTypes = t3lib_div::trimExplode(',', $modTS['linktypes'], 1);
00305                 if (is_array($linkTypes)) {
00306                     if (!empty($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])
00307                             && is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
00308                         foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $type => $value) {
00309                             if (in_array($type, $linkTypes)) {
00310                                 $array[$type] = 1;
00311                             }
00312                         }
00313                     }
00314                 }
00315                 $processor = t3lib_div::makeInstance('tx_linkvalidator_Processor');
00316                 $pageIds = $processor->extGetTreeList($page, $this->depth, 0, '1=1');
00317                 $pageIds .= $page;
00318                 $processor->init($searchFields, $pageIds);
00319                 if (!empty($this->email)) {
00320                     $oldLinkCounts = $processor->getLinkCounts($page);
00321                     $this->oldTotalBrokenLink += $oldLinkCounts['brokenlinkCount'];
00322                 }
00323 
00324                 $processor->getLinkStatistics($array, $modTS['checkhidden']);
00325 
00326                 if (!empty($this->email)) {
00327                     $linkCounts = $processor->getLinkCounts($page);
00328                     $this->totalBrokenLink += $linkCounts['brokenlinkCount'];
00329                     $pageSections .= $this->buildMail($page, $pageIds, $linkCounts, $oldLinkCounts);
00330                 }
00331 
00332             }
00333         }
00334         if ($this->totalBrokenLink != $this->oldTotalBrokenLink) {
00335             $this->dif = TRUE;
00336         }
00337         if ($this->totalBrokenLink > 0
00338             && (!$this->emailOnBrokenLinkOnly || $this->dif)
00339             && !empty($this->email)
00340         ) {
00341             $successfullyExecuted = $this->reportEmail($pageSections, $modTS);
00342         }
00343         return $successfullyExecuted;
00344     }
00345 
00346 
00347     /**
00348      * Build and send warning email when new broken links were found.
00349      *
00350      * @param   string      $pageSections: Content of page section
00351      * @param   string      $modTS: TSconfig array
00352      * @return  bool        TRUE if mail was sent, FALSE if or not
00353      */
00354     protected function reportEmail($pageSections, $modTS) {
00355         $content = t3lib_parsehtml::substituteSubpart($this->templateMail, '###PAGE_SECTION###', $pageSections);
00356         /** @var array $markerArray */
00357         $markerArray = array();
00358         /** @var array $validEmailList */
00359         $validEmailList = array();
00360         /** @var boolean $sendEmail */
00361         $sendEmail = TRUE;
00362 
00363         $markerArray['totalBrokenLink'] = $this->totalBrokenLink;
00364         $markerArray['totalBrokenLink_old'] = $this->oldTotalBrokenLink;
00365         $content = t3lib_parsehtml::substituteMarkerArray($content, $markerArray, '###|###', TRUE, TRUE);
00366 
00367         /** @var t3lib_mail_Message $mail */
00368         $mail = t3lib_div::makeInstance('t3lib_mail_Message');
00369         if (t3lib_div::validEmail($modTS['mail.']['fromemail'])) {
00370             $mail->setFrom(array($modTS['mail.']['fromemail'] => $modTS['mail.']['fromname']));
00371         } else {
00372             throw new Exception(
00373                 $GLOBALS['LANG']->sL('LLL:EXT:linkvalidator/locallang.xml:tasks.error.invalidFromEmail'),
00374                 '1295476760'
00375             );
00376         }
00377         if(t3lib_div::validEmail($modTS['mail.']['replytoemail'])) {
00378             $mail->setReplyTo(array($modTS['mail.']['replytoemail'] => $modTS['mail.']['replytoname']));
00379         }
00380 
00381         if(!empty($modTS['mail.']['subject'])) {
00382             $mail->setSubject($modTS['mail.']['subject']);
00383         } else {
00384             throw new Exception(
00385                 $GLOBALS['LANG']->sL('LLL:EXT:linkvalidator/locallang.xml:tasks.error.noSubject'),
00386                 '1295476808'
00387             );
00388         }
00389         if (!empty($this->email)) {
00390             $emailList = t3lib_div::trimExplode(',', $this->email);
00391             foreach ($emailList as $emailAdd) {
00392                 if (!t3lib_div::validEmail($emailAdd)) {
00393                     throw new Exception(
00394                         $GLOBALS['LANG']->sL('LLL:EXT:linkvalidator/locallang.xml:tasks.error.invalidToEmail'),
00395                         '1295476821'
00396                     );
00397                 } else {
00398                     $validEmailList[] = $emailAdd;
00399                 }
00400             }
00401         }
00402         if (is_array($validEmailList) && !empty($validEmailList)) {
00403             $mail->setTo($this->email);
00404         } else {
00405             $sendEmail = FALSE;
00406         }
00407 
00408         if($sendEmail) {
00409             $mail->setBody($content,'text/html');
00410             $mail->send();
00411         }
00412 
00413         return $sendEmail;
00414     }
00415 
00416 
00417     /**
00418      * Build the mail content.
00419      *
00420      * @param   int         $curPage: id of the current page
00421      * @param   string      $pageList: list of pages id
00422      * @param   array       $markerArray: array of markers
00423      * @param   array       $oldBrokenLink: markerarray with the number of link found
00424      * @return  string      Content of the mail
00425      */
00426     protected function buildMail($curPage, $pageList, $markerArray, $oldBrokenLink) {
00427         $pageSectionHTML = t3lib_parsehtml::getSubpart($this->templateMail, '###PAGE_SECTION###');
00428 
00429         if (is_array($markerArray)) {
00430             foreach ($markerArray as $markerKey => $markerValue) {
00431                 if (empty($oldBrokenLink[$markerKey])) {
00432                     $oldBrokenLink[$markerKey] = 0;
00433                 }
00434                 if ($markerValue != $oldBrokenLink[$markerKey]) {
00435                     $this->dif = TRUE;
00436                 }
00437                 $markerArray[$markerKey . '_old'] = $oldBrokenLink[$markerKey];
00438             }
00439         }
00440         $markerArray['title'] = t3lib_BEfunc::getRecordTitle('pages', t3lib_BEfunc::getRecord('pages', $curPage));
00441 
00442         $content = '';
00443         if ($markerArray['brokenlinkCount'] > 0) {
00444             $content = t3lib_parsehtml::substituteMarkerArray($pageSectionHTML, $markerArray, '###|###', TRUE, TRUE);
00445         }
00446         return $content;
00447     }
00448 
00449 
00450     /**
00451      * Simulate cli call with setting the required options to the $_SERVER['argv']
00452      *
00453      * @return  void
00454      * @access protected
00455      */
00456     protected function setCliArguments() {
00457         $_SERVER['argv'] = array(
00458             $_SERVER['argv'][0],
00459             'tx_link_scheduler_link',
00460             '0',
00461             '-ss',
00462             '--sleepTime',
00463             $this->sleepTime,
00464             '--sleepAfterFinish',
00465             $this->sleepAfterFinish,
00466             '--countInARun',
00467             $this->countInARun
00468         );
00469     }
00470 }
00471 
00472 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/linkvalidator/classes/tasks/class.tx_linkvalidator_tasks_validator.php'])) {
00473     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/linkvalidator/classes/tasks/class.tx_linkvalidator_tasks_validator.php']);
00474 }
00475 ?>