Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • PHP
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cLinkcheckerSearchLinks
  • LinkcheckerRepair

Functions

  • cCatPerm
  • checkLinks
  • getGroupIDs
  • linksort
  • searchFrontContentLinks
  • url_is_image
  • url_is_uri
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * This is the tests backend page for the linkchecker plugin.
  4:  *
  5:  * @package Plugin
  6:  * @subpackage Linkchecker
  7:  * @author Frederic Schneider
  8:  * @copyright four for business AG <www.4fb.de>
  9:  * @license http://www.contenido.org/license/LIZENZ.txt
 10:  * @link http://www.4fb.de
 11:  * @link http://www.contenido.org
 12:  */
 13: 
 14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 15: 
 16: // Checks all links without front_content.php
 17: function checkLinks() {
 18:     global $auth, $cfg, $cronjob, $db, $aErrors, $lang;
 19:     global $aSearchIDInfosArt, $aSearchIDInfosCat, $aSearchIDInfosCatArt, $aSearchIDInfosNonID;
 20: 
 21:     $sSearch = '';
 22: 
 23:     if (count($aSearchIDInfosArt) > 0) { // Checks idarts
 24: 
 25:         for ($i = 0; $i < count($aSearchIDInfosArt); $i++) {
 26: 
 27:             if ($i == 0) {
 28:                 $sSearch = cSecurity::toInteger($aSearchIDInfosArt[$i]['id']);
 29:             } else {
 30:                 $sSearch .= ", " . cSecurity::toInteger($aSearchIDInfosArt[$i]['id']);
 31:             }
 32:         }
 33: 
 34:         // SQL query, please note: integer cast some lines before!
 35:         $sql = "SELECT idart, online FROM " . $cfg['tab']['art_lang'] . " WHERE idart IN (" . $sSearch . ")";
 36:         $db->query($sql);
 37: 
 38:         // Check articles
 39:         $aFind = array();
 40: 
 41:         while ($db->nextRecord()) {
 42:             $aFind[$db->f("idart")] = array(
 43:                 "online" => $db->f("online")
 44:             );
 45:         }
 46: 
 47:         for ($i = 0; $i < count($aSearchIDInfosArt); $i++) {
 48: 
 49:             if (isset($aFind[$aSearchIDInfosArt[$i]['id']]) && $aFind[$aSearchIDInfosArt[$i]['id']]['online'] == 0) {
 50:                 $aErrors['art'][] = array_merge($aSearchIDInfosArt[$i], array(
 51:                     "error_type" => "offline"
 52:                 ));
 53:             } elseif (!isset($aFind[$aSearchIDInfosArt[$i]['id']])) {
 54:                 $aErrors['art'][] = array_merge($aSearchIDInfosArt[$i], array(
 55:                     "error_type" => "unknown"
 56:                 ));
 57:             }
 58:         }
 59:     }
 60: 
 61:     if (count($aSearchIDInfosCat) > 0) { // Checks idcats
 62: 
 63:         for ($i = 0; $i < count($aSearchIDInfosCat); $i++) {
 64: 
 65:             if ($i == 0) {
 66:                 $sSearch = cSecurity::toInteger($aSearchIDInfosCat[$i]['id']);
 67:             } else {
 68:                 $sSearch .= ", " . cSecurity::toInteger($aSearchIDInfosCat[$i]['id']);
 69:             }
 70:         }
 71: 
 72:         // SQL query, please note: integer cast some lines before!
 73:         $sql = "SELECT idcat, startidartlang, visible FROM " . $cfg['tab']['cat_lang'] . " WHERE idcat IN (" . $sSearch . ") AND idlang = '" . cSecurity::toInteger($lang) . "'";
 74:         $db->query($sql);
 75: 
 76:         // Check categories
 77:         $aFind = array();
 78: 
 79:         while ($db->nextRecord()) {
 80:             $aFind[$db->f("idcat")] = array(
 81:                 "online" => $db->f("visible"),
 82:                 "startidart" => $db->f("startidartlang")
 83:             );
 84:         }
 85: 
 86:         for ($i = 0; $i < count($aSearchIDInfosCat); $i++) {
 87: 
 88:             if (is_array($aFind[$aSearchIDInfosCat[$i]['id']]) && $aFind[$aSearchIDInfosCat[$i]['id']]['startidart'] == 0) {
 89:                 $aErrors['cat'][] = array_merge($aSearchIDInfosCat[$i], array(
 90:                     "error_type" => "startart"
 91:                 ));
 92:             } elseif (is_array($aFind[$aSearchIDInfosCat[$i]['id']]) && $aFind[$aSearchIDInfosCat[$i]['id']]['online'] == 0) {
 93:                 $aErrors['cat'][] = array_merge($aSearchIDInfosCat[$i], array(
 94:                     "error_type" => "offline"
 95:                 ));
 96:             } elseif (!is_array($aFind[$aSearchIDInfosCat[$i]['id']])) {
 97:                 $aErrors['cat'][] = array_merge($aSearchIDInfosCat[$i], array(
 98:                     "error_type" => "unknown"
 99:                 ));
100:             }
101: 
102:             if (is_array($aFind[$aSearchIDInfosCat[$i]['id']]) && $aFind[$aSearchIDInfosCat[$i]['id']]['startidart'] != 0) {
103: 
104:                 $sql = "SELECT idart FROM " . $cfg['tab']['art_lang'] . " WHERE idartlang = '" . cSecurity::toInteger($aFind[$aSearchIDInfosCat[$i]['id']]['startidart']) . "' AND online = '1'";
105:                 $db->query($sql);
106: 
107:                 if ($db->numRows() == 0) {
108:                     $aErrors['cat'][] = array_merge($aSearchIDInfosCat[$i], array(
109:                         "error_type" => "startart"
110:                     ));
111:                 }
112:             }
113:         }
114:     }
115: 
116:     if (count($aSearchIDInfosCatArt) > 0) { // Checks idcatarts
117: 
118:         for ($i = 0; $i < count($aSearchIDInfosCatArt); $i++) {
119: 
120:             if ($i == 0) {
121:                 $sSearch = cSecurity::toInteger($aSearchIDInfosCatArt[$i]['id']);
122:             } else {
123:                 $sSearch .= ", " . cSecurity::toInteger($aSearchIDInfosCatArt[$i]['id']);
124:             }
125:         }
126: 
127:         // SQL query, please note: integer cast some lines before!
128:         $sql = "SELECT idcatart FROM " . $cfg['tab']['cat_art'] . " WHERE idcatart IN (" . $sSearch . ")";
129:         $db->query($sql);
130: 
131:         // Check articles
132:         $aFind = array();
133: 
134:         while ($db->nextRecord()) {
135:             $aFind[] = $db->f("idcatart");
136:         }
137: 
138:         for ($i = 0; $i < count($aSearchIDInfosCatArt); $i++) {
139: 
140:             if (!in_array($aSearchIDInfosCatArt[$i]['id'], $aFind)) {
141:                 $aErrors['art'][] = array_merge($aSearchIDInfosCatArt[$i], array(
142:                     "error_type" => "unknown"
143:                 ));
144:             }
145:         }
146:     }
147: 
148:     if (count($aSearchIDInfosNonID) != 0) { // Checks other links (e. g. http,
149:                                             // www, dfbs)
150: 
151:         // Select userrights (is the user admin or sysadmin?)
152:         $sql = "SELECT username FROM " . $cfg['tab']['user'] . " WHERE user_id='" . cSecurity::toInteger($auth->auth['uid']) . "' AND perms LIKE '%admin%'";
153:         $db->query($sql);
154: 
155:         if ($db->numRows() > 0 || $cronjob == true) { // User is admin when he
156:                                                       // is or when he run the
157:                                                       // cronjob
158:             $iAdmin = true;
159:         }
160: 
161:         $frontendPath = cRegistry::getFrontendPath();
162:         $frontendURL = cRegistry::getFrontendUrl();
163: 
164:         for ($i = 0; $i < count($aSearchIDInfosNonID); $i++) {
165:             if (!filter_var($aSearchIDInfosNonID[$i]['url'], FILTER_VALIDATE_URL) && !url_is_image($aSearchIDInfosNonID[$i]['url'])) {
166:                 $aErrors['others'][] = array_merge($aSearchIDInfosNonID[$i], array(
167:                     "error_type" => "invalidurl"
168:                 ));
169:             } elseif (url_is_uri($aSearchIDInfosNonID[$i]['url'])) {
170:                 if (cString::getPartOfString($aSearchIDInfosNonID[$i]['url'], 0, cString::getStringLength($aSearchIDInfosNonID[$i]['url'])) == $frontendURL) {
171:                     $iPing = @cFileHandler::exists(str_replace($frontendURL, $frontendPath, $aSearchIDInfosNonID[$i]['url']));
172:                 } else {
173:                     $iPing = @fopen($aSearchIDInfosNonID[$i]['url'], 'r');
174:                 }
175: 
176:                 if (!$iPing) {
177: 
178:                     if (url_is_image($aSearchIDInfosNonID[$i]['url'])) {
179:                         $aErrors['docimages'][] = array_merge($aSearchIDInfosNonID[$i], array(
180:                             "error_type" => "unknown"
181:                         ));
182:                     } else {
183:                         $aErrors['others'][] = array_merge($aSearchIDInfosNonID[$i], array(
184:                             "error_type" => "unknown"
185:                         ));
186:                     }
187:                 }
188:             } elseif (cString::getPartOfString($aSearchIDInfosNonID[$i]['url'], cString::getStringLength($aSearchIDInfosNonID[$i]['url']) - 5, 5) == ".html") {
189: 
190:                 $iPing = @cFileHandler::exists($frontendURL . $aSearchIDInfosNonID[$i]['url']);
191: 
192:                 if (!$iPing) {
193:                     $aErrors['art'][] = array_merge($aSearchIDInfosNonID[$i], array(
194:                         "error_type" => "unknown"
195:                     ));
196:                 }
197:             } elseif (cString::getPartOfString($aSearchIDInfosNonID[$i]['url'], 0, 20) == "dbfs.php?file=" . cApiDbfs::PROTOCOL_DBFS . "/") {
198: 
199:                 $sDBurl = cString::getPartOfString($aSearchIDInfosNonID[$i]['url'], 20, cString::getStringLength($aSearchIDInfosNonID[$i]['url']));
200: 
201:                 $iPos = cString::findLastPos($sDBurl, '/');
202:                 $sDirname = cString::getPartOfString($sDBurl, 0, $iPos);
203:                 $sFilename = cString::getPartOfString($sDBurl, $iPos + 1);
204: 
205:                 // Check dbfs
206:                 $sql = "SELECT iddbfs FROM " . $cfg['tab']['dbfs'] . " WHERE dirname IN('" . cSecurity::escapeDB($sDirname, $db) . "', '" . conHtmlEntityDecode($sDirname) . "', '" . cSecurity::escapeDB($sDirname, $db) . "') AND filename = '" . cSecurity::escapeDB($sFilename, $db) . "'";
207:                 $db->query($sql);
208: 
209:                 if ($db->numRows() == 0) {
210:                     $aErrors['docimages'][] = array_merge($aSearchIDInfosNonID[$i], array(
211:                         "error_type" => "dbfs"
212:                     ));
213:                 }
214:             } else {
215: 
216:                 if (!cFileHandler::exists($frontendPath . $aSearchIDInfosNonID[$i]['url'])) {
217: 
218:                     if (url_is_image($aSearchIDInfosNonID[$i]['url'])) {
219:                         $aErrors['docimages'][] = array_merge($aSearchIDInfosNonID[$i], array(
220:                             "error_type" => "unknown"
221:                         ));
222:                     } else {
223:                         $aErrors['others'][] = array_merge($aSearchIDInfosNonID[$i], array(
224:                             "error_type" => "unknown"
225:                         ));
226:                     }
227:                 }
228:             }
229:         }
230:     }
231: 
232:     return $aErrors;
233: }
234: 
235: // Searchs front_content.php-links
236: function searchFrontContentLinks($sValue, $iArt, $sArt, $iCat, $sCat) {
237:     global $aSearchIDInfosArt, $aSearchIDInfosCat, $aSearchIDInfosCatArt, $aWhitelist;
238: 
239:     // detect urls with parameter idart
240:     $matches = array();
241:     if (preg_match_all('/(?!file|ftp|http|ww)front_content.php\?idart=([0-9]*)/i', $sValue, $matches)) {
242:         for ($i = 0; $i < count($matches[0]); $i++) {
243:             if (!in_array($matches[0][$i], $aWhitelist)) {
244:                 $aSearchIDInfosArt[] = array(
245:                     "id" => $matches[1][$i],
246:                     "url" => $matches[0][$i],
247:                     "idart" => $iArt,
248:                     "nameart" => $sArt,
249:                     "idcat" => $iCat,
250:                     "namecat" => $sCat,
251:                     "urltype" => "intern"
252:                 );
253:             }
254:         }
255:     }
256: 
257:     // detect urls with parameter idcat
258:     $matches = array();
259:     if (preg_match_all('/(?!file|ftp|http|ww)front_content.php\?idcat=([0-9]*)/i', $sValue, $matches)) {
260:         for ($i = 0; $i < count($matches[0]); $i++) {
261:             if (!in_array($matches[0][$i], $aWhitelist)) {
262:                 $aSearchIDInfosCat[] = array(
263:                     "id" => $matches[1][$i],
264:                     "url" => $matches[0][$i],
265:                     "idart" => $iArt,
266:                     "nameart" => $sArt,
267:                     "idcat" => $iCat,
268:                     "namecat" => $sCat,
269:                     "urltype" => "intern"
270:                 );
271:             }
272:         }
273:     }
274: 
275:     // detect urls with parameter idcatart
276:     $matches = array();
277:     if (preg_match_all('/(?!file|ftp|http|ww)front_content.php\?idcatart=([0-9]*)/i', $sValue, $matches)) { // idcatart
278:         for ($i = 0; $i < count($matches[0]); $i++) {
279:             if (!in_array($matches[0][$i], $aWhitelist)) {
280:                 $aSearchIDInfosCatArt[] = array(
281:                     "id" => $matches[1][$i],
282:                     "url" => $matches[0][$i],
283:                     "idart" => $iArt,
284:                     "nameart" => $sArt,
285:                     "idcat" => $iCat,
286:                     "namecat" => $sCat,
287:                     "urltype" => "intern"
288:                 );
289:             }
290:         }
291:     }
292: }
293: 
294: /**
295:  * Class searchLinks
296:  * TODO: Linkchecker should uses completely a class system. This is only a first step!
297:  */
298: class cLinkcheckerSearchLinks
299: {
300: 
301:     private $mode = '';
302: 
303:     /**
304:      * searchLinks constructor.
305:      */
306:     public function __construct() {
307:         $this->setMode("text");
308:     }
309: 
310:     /**
311:      * Setter method for mode
312:      * mode:
313:      * - text (standard)
314:      * - redirect
315:      *
316:      * @param $mode
317:      * @return mixed
318:      */
319:     public function setMode($mode) {
320:         return $this->mode = cSecurity::toString($mode);
321:     }
322: 
323:     /**
324:      * Old searchLinks function
325:      * TODO: Optimize this function!
326:      *
327:      * @param string $value
328:      * @param int $idart
329:      * @param string $nameart
330:      * @param int $idcat
331:      * @param string $namecat
332:      * @param int $idlang
333:      * @param int $idartlang
334:      * @param int $idcontent
335:      * @todo Do not use global!
336:      * @return array
337:      */
338:     public function search($value, $idart, $nameart, $idcat, $namecat, $idlang, $idartlang, $idcontent = 0) {
339:         global $aUrl, $aSearchIDInfosNonID, $aWhitelist;
340: 
341:         // Extern URL
342:         if (preg_match_all('~(?:(?:action|data|href|src)=["\']((?:file|ftp|http|ww)[^\s]*)["\'])~i', $value, $aMatches) && $_GET['mode'] != 1) {
343: 
344:             for ($i = 0; $i < count($aMatches[1]); $i++) {
345: 
346:                 if (!in_array($aMatches[1][$i], $aWhitelist)) {
347:                     $aSearchIDInfosNonID[] = array(
348:                         "url" => $aMatches[1][$i],
349:                         "idart" => $idart,
350:                         "nameart" => $nameart,
351:                         "idcat" => $idcat,
352:                         "namecat" => $namecat,
353:                         "idcontent" => $idcontent,
354:                         "idartlang" => $idartlang,
355:                         "lang" => $idlang,
356:                         "urltype" => "extern"
357:                     );
358:                 }
359:             }
360:         }
361: 
362:         // Redirect
363:         if ($this->mode == "redirect" && (preg_match('!(' . preg_quote($aUrl['cms']) . '[^\s]*)!i', $value, $aMatches) || (preg_match('~(?:file|ftp|http|ww)[^\s]*~i', $value, $aMatches) && $_GET['mode'] != 1)) && (cString::findFirstPosCI($value, 'front_content.php') === false) && !in_array($aMatches[0], $aWhitelist)) {
364:             $aSearchIDInfosNonID[] = array(
365:                 "url" => $aMatches[0],
366:                 "idart" => $idart,
367:                 "nameart" => $nameart,
368:                 "idcat" => $idcat,
369:                 "namecat" => $namecat,
370:                 "idcontent" => 0,
371:                 "idartlang" => $idartlang,
372:                 "lang" => $idlang,
373:                 "urltype" => "unknown",
374:                 "redirect" => true
375:             );
376:         }
377: 
378:         // Intern URL
379:         if (preg_match_all('~(?:(?:action|data|href|src)=["\'])(?!file://)(?!ftp://)(?!http://)(?!https://)(?!ww)(?!mailto)(?!\#)(?!/\#)([^"\']+)(?:["\'])~i', $value, $aMatches) && $_GET['mode'] != 2) {
380: 
381:             for ($i = 0; $i < count($aMatches[1]); $i++) {
382: 
383:                 if (cString::findFirstPos($aMatches[1][$i], "front_content.php") === false && !in_array($aMatches[1][$i], $aWhitelist)) {
384:                     $aSearchIDInfosNonID[] = array(
385:                         "url" => $aMatches[1][$i],
386:                         "idart" => $idart,
387:                         "nameart" => $nameart,
388:                         "idcat" => $idcat,
389:                         "namecat" => $namecat,
390:                         "idcontent" => $idcontent,
391:                         "idartlang" => $idartlang,
392:                         "lang" => $idlang,
393:                         "urltype" => "intern"
394:                     );
395:                 }
396:             }
397:         }
398: 
399:         return $aSearchIDInfosNonID;
400:     }
401: }
402: ?>
CMS CONTENIDO 4.10.0 API documentation generated by ApiGen 2.8.0