2019-08-12 22:19:24 +02:00
< ? php
/* Copyright ( C ) 2017 Laurent Destailleur < eldy @ users . sourceforge . net >
2024-09-05 16:05:37 +02:00
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
2019-08-12 22:19:24 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2019-08-12 22:19:24 +02:00
*/
/**
* \file htdocs / core / lib / website2 . lib . php
* \ingroup website
* \brief Library for website module ( rare functions not required for execution of website )
*/
/**
* Save content of a page on disk
*
* @ param string $filemaster Full path of filename master . inc . php for website to generate
* @ return boolean True if OK
*/
function dolSaveMasterFile ( $filemaster )
{
// Now generate the master.inc.php page
2024-01-23 20:13:27 +01:00
dol_syslog ( " We regenerate the master.inc.php file " );
2019-08-12 22:19:24 +02:00
dol_delete_file ( $filemaster );
$mastercontent = '<?php' . " \n " ;
2019-11-13 19:35:02 +01:00
$mastercontent .= '// File generated to link to the master file - DO NOT MODIFY - It is just an include' . " \n " ;
2020-05-06 04:32:48 +02:00
$mastercontent .= " if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { \n " ;
$mastercontent .= " if (! defined('USEEXTERNALSERVER')) define('USEEXTERNALSERVER', 1); \n " ;
$mastercontent .= " require_once ' " . DOL_DOCUMENT_ROOT . " /master.inc.php'; \n " ;
$mastercontent .= " } \n " ;
2019-11-13 19:35:02 +01:00
$mastercontent .= '?>' . " \n " ;
2019-08-12 22:19:24 +02:00
$result = file_put_contents ( $filemaster , $mastercontent );
2023-02-17 19:30:50 +01:00
dolChmod ( $filemaster );
2019-08-12 22:19:24 +02:00
2022-05-12 00:52:28 +02:00
return $result ;
2019-08-12 22:19:24 +02:00
}
/**
2021-01-24 13:27:52 +01:00
* Save an alias page on disk ( A page that include the reference page ) .
* It saves file into the root directory but also into language subdirectory .
2019-08-12 22:19:24 +02:00
*
* @ param string $filealias Full path of filename to generate
* @ param Website $object Object website
* @ param WebsitePage $objectpage Object websitepage
* @ return boolean True if OK
2020-02-21 11:36:16 +01:00
* @ see dolSavePageContent ()
2019-08-12 22:19:24 +02:00
*/
function dolSavePageAlias ( $filealias , $object , $objectpage )
{
2021-04-01 19:48:15 +02:00
// Now create the .tpl file
2024-03-30 03:33:36 +01:00
dol_syslog ( " dolSavePageAlias We regenerate the alias page filealias= " . $filealias . " and a wrapper into all language subdirectories " );
2019-08-12 22:19:24 +02:00
$aliascontent = '<?php' . " \n " ;
2019-11-13 19:35:02 +01:00
$aliascontent .= " // File generated to wrap the alias page - DO NOT MODIFY - It is just a wrapper to real page \n " ;
$aliascontent .= 'global $dolibarr_main_data_root;' . " \n " ;
2025-01-28 16:02:23 +01:00
$aliascontent .= 'if (empty($dolibarr_main_data_root)) $res=include \'./page' . $objectpage -> id . '.tpl.php\'; ' ;
$aliascontent .= 'else $res=include $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page' . $objectpage -> id . '.tpl.php\';' . " \n " ;
$aliascontent .= 'if ($res === false) { http_response_code(500); print \'Failed to make include\'; }' . " \n " ;
2019-11-13 19:35:02 +01:00
$aliascontent .= '?>' . " \n " ;
2019-08-12 22:19:24 +02:00
$result = file_put_contents ( $filealias , $aliascontent );
2020-04-11 16:34:59 +02:00
if ( $result === false ) {
dol_syslog ( " Failed to write file " . $filealias , LOG_WARNING );
}
2023-02-17 19:30:50 +01:00
dolChmod ( $filealias );
2019-08-12 22:19:24 +02:00
2021-01-24 13:27:52 +01:00
// Save also alias into language subdirectory if it is not a main language
2020-02-21 11:36:16 +01:00
if ( $objectpage -> lang && in_array ( $objectpage -> lang , explode ( ',' , $object -> otherlang ))) {
$dirname = dirname ( $filealias );
$filename = basename ( $filealias );
2021-01-26 13:38:41 +01:00
$filealiassub = $dirname . '/' . $objectpage -> lang . '/' . $filename ;
2020-02-21 11:36:16 +01:00
2024-03-30 03:33:36 +01:00
dol_mkdir ( $dirname . '/' . $objectpage -> lang , DOL_DATA_ROOT );
2020-02-21 11:36:16 +01:00
$aliascontent = '<?php' . " \n " ;
$aliascontent .= " // File generated to wrap the alias page - DO NOT MODIFY - It is just a wrapper to real page \n " ;
$aliascontent .= 'global $dolibarr_main_data_root;' . " \n " ;
2025-01-28 16:02:23 +01:00
$aliascontent .= 'if (empty($dolibarr_main_data_root)) $res=include \'../page' . $objectpage -> id . '.tpl.php\'; ' ;
$aliascontent .= 'else $res=include $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page' . $objectpage -> id . '.tpl.php\';' . " \n " ;
$aliascontent .= 'if ($res === false) { http_response_code(500); print \'Failed to make include\'; }' . " \n " ;
2020-02-21 11:36:16 +01:00
$aliascontent .= '?>' . " \n " ;
2021-01-26 13:38:41 +01:00
$result = file_put_contents ( $filealiassub , $aliascontent );
2020-04-11 16:34:59 +02:00
if ( $result === false ) {
2021-01-26 13:38:41 +01:00
dol_syslog ( " Failed to write file " . $filealiassub , LOG_WARNING );
2020-04-11 16:34:59 +02:00
}
2023-02-17 19:30:50 +01:00
dolChmod ( $filealiassub );
2021-03-01 20:37:16 +01:00
} elseif ( empty ( $objectpage -> lang ) || ! in_array ( $objectpage -> lang , explode ( ',' , $object -> otherlang ))) {
// Save also alias into all language subdirectories if it is a main language
2023-11-27 11:39:32 +01:00
if ( ! getDolGlobalString ( 'WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR' ) && ! empty ( $object -> otherlang )) {
2021-01-24 14:31:29 +01:00
$dirname = dirname ( $filealias );
$filename = basename ( $filealias );
foreach ( explode ( ',' , $object -> otherlang ) as $sublang ) {
2021-04-10 00:31:20 +02:00
// Avoid to erase main alias file if $sublang is empty string
2023-12-04 12:05:28 +01:00
if ( empty ( trim ( $sublang ))) {
continue ;
}
2021-01-26 13:38:41 +01:00
$filealiassub = $dirname . '/' . $sublang . '/' . $filename ;
2021-01-24 14:31:29 +01:00
$aliascontent = '<?php' . " \n " ;
$aliascontent .= " // File generated to wrap the alias page - DO NOT MODIFY - It is just a wrapper to real page \n " ;
$aliascontent .= 'global $dolibarr_main_data_root;' . " \n " ;
2025-01-28 16:02:23 +01:00
$aliascontent .= 'if (empty($dolibarr_main_data_root)) $res=include \'../page' . $objectpage -> id . '.tpl.php\'; ' ;
$aliascontent .= 'else $res=include $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page' . $objectpage -> id . '.tpl.php\';' . " \n " ;
$aliascontent .= 'if ($res === false) { http_response_code(500); print \'Failed to make include\'; }' . " \n " ;
2021-01-24 14:31:29 +01:00
$aliascontent .= '?>' . " \n " ;
2024-06-06 15:27:59 +02:00
dol_mkdir ( $dirname . '/' . $sublang );
2021-01-26 13:38:41 +01:00
$result = file_put_contents ( $filealiassub , $aliascontent );
2021-01-24 14:31:29 +01:00
if ( $result === false ) {
2021-01-26 13:38:41 +01:00
dol_syslog ( " Failed to write file " . $filealiassub , LOG_WARNING );
2021-01-24 14:31:29 +01:00
}
2023-02-17 19:30:50 +01:00
dolChmod ( $filealiassub );
2021-01-24 14:31:29 +01:00
}
}
}
2021-01-24 13:27:52 +01:00
2023-12-04 12:05:28 +01:00
return ( $result ? true : false );
2019-08-12 22:19:24 +02:00
}
/**
2021-01-24 13:27:52 +01:00
* Save content of a page on disk ( page name is generally ID_of_page . php ) .
* Page contents are always saved into " root " directory . Only aliases pages saved with dolSavePageAlias () can be in root or language subdir .
2019-08-12 22:19:24 +02:00
*
* @ param string $filetpl Full path of filename to generate
* @ param Website $object Object website
* @ param WebsitePage $objectpage Object websitepage
2021-04-01 19:48:15 +02:00
* @ param int $backupold 1 = Make a backup of old page
2019-08-12 22:19:24 +02:00
* @ return boolean True if OK
2020-02-21 11:36:16 +01:00
* @ see dolSavePageAlias ()
2019-08-12 22:19:24 +02:00
*/
2021-04-01 19:48:15 +02:00
function dolSavePageContent ( $filetpl , Website $object , WebsitePage $objectpage , $backupold = 0 )
2019-08-12 22:19:24 +02:00
{
2024-01-23 20:13:27 +01:00
global $db ;
2019-08-12 22:19:24 +02:00
// Now create the .tpl file (duplicate code with actions updatesource or updatecontent but we need this to save new header)
2021-12-04 00:24:59 +01:00
dol_syslog ( " dolSavePageContent We regenerate the tpl page filetpl= " . $filetpl );
2019-08-12 22:19:24 +02:00
2020-03-20 16:30:45 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2021-04-01 19:48:15 +02:00
2021-12-04 00:24:59 +01:00
if ( dol_is_file ( $filetpl )) {
if ( $backupold ) {
2024-05-14 11:25:03 +02:00
$result = archiveOrBackupFile ( $filetpl );
2021-12-04 00:24:59 +01:00
if ( ! $result ) {
return false ;
}
} else {
dol_delete_file ( $filetpl );
2021-04-01 19:48:15 +02:00
}
}
2019-08-12 22:19:24 +02:00
$shortlangcode = '' ;
2021-02-23 22:03:23 +01:00
if ( $objectpage -> lang ) {
$shortlangcode = substr ( $objectpage -> lang , 0 , 2 ); // en_US or en-US -> en
}
if ( empty ( $shortlangcode )) {
2025-01-11 14:14:05 +01:00
// Take the language of website
2021-02-23 22:03:23 +01:00
$shortlangcode = substr ( $object -> lang , 0 , 2 ); // en_US or en-US -> en
}
2019-11-13 19:35:02 +01:00
2024-05-21 20:13:39 +02:00
if ( ! empty ( $objectpage -> type_container ) && in_array ( $objectpage -> type_container , array ( 'library' , 'service' ))) {
$originalcontentonly = 1 ;
2024-01-23 20:13:27 +01:00
}
2024-05-21 20:13:39 +02:00
$tplcontent = '' ;
if ( ! isset ( $originalcontentonly )) {
2025-01-22 16:28:05 +01:00
// If we want to generate a page with some code to manage PHP content
2024-05-21 20:13:39 +02:00
$tplcontent .= " <?php // BEGIN PHP \n " ;
$tplcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;' . " \n " ;
$tplcontent .= " if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { \n " ;
$tplcontent .= ' $pathdepth = count(explode(\'/\', $_SERVER[\'SCRIPT_NAME\'])) - 2;' . " \n " ;
$tplcontent .= ' require_once ($pathdepth ? str_repeat(\'../\', $pathdepth) : \'./\').\'master.inc.php\';' . " \n " ;
$tplcontent .= " } // Not already loaded \n " ;
$tplcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php'; \n " ;
$tplcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php'; \n " ;
$tplcontent .= " ob_start(); \n " ;
2025-01-28 19:01:38 +01:00
$tplcontent .= " try { \n " ;
2024-05-21 20:13:39 +02:00
$tplcontent .= " // END PHP ?> \n " ;
if ( getDolGlobalString ( 'WEBSITE_FORCE_DOCTYPE_HTML5' )) {
$tplcontent .= " <!DOCTYPE html> \n " ;
}
2025-01-11 14:14:05 +01:00
// If a language was forced on page, we use it, else we use the lang of visitor else the lang of web site
$tplcontent .= '<html' . ( $objectpage -> lang ? ' lang="' . substr ( $objectpage -> lang , 0 , 2 ) . '"' : '<?php echo $weblangs->shortlang ? \' lang="\'.$weblangs->shortlang.\'"\' : \'\' ?>' ) . '>' . " \n " ;
2024-05-21 20:13:39 +02:00
$tplcontent .= '<head>' . " \n " ;
2025-01-22 16:31:41 +01:00
$tplcontent .= '<title>' . dol_string_nohtmltag ( $objectpage -> title , 1 , 'UTF-8' ) . '</title>' . " \n " ;
2024-05-21 20:13:39 +02:00
$tplcontent .= '<meta charset="utf-8">' . " \n " ;
$tplcontent .= '<meta http-equiv="content-type" content="text/html; charset=utf-8" />' . " \n " ;
$tplcontent .= '<meta name="robots" content="index, follow" />' . " \n " ;
$tplcontent .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">' . " \n " ;
2025-01-22 16:31:41 +01:00
$tplcontent .= '<meta name="keywords" content="' . dol_string_nohtmltag ( $objectpage -> keywords , 1 , 'UTF-8' ) . '" />' . " \n " ;
$tplcontent .= '<meta name="title" content="' . dol_string_nohtmltag ( $objectpage -> title , 1 , 'UTF-8' ) . '" />' . " \n " ;
$tplcontent .= '<meta name="description" content="' . dol_string_nohtmltag ( $objectpage -> description , 1 , 'UTF-8' ) . '" />' . " \n " ;
2024-05-21 20:13:39 +02:00
$tplcontent .= '<meta name="generator" content="' . DOL_APPLICATION_TITLE . ' ' . DOL_VERSION . ' (https://www.dolibarr.org)" />' . " \n " ;
2025-01-22 16:28:05 +01:00
$tplcontent .= '<meta name="dolibarr:pageid" content="' . (( int ) $objectpage -> id ) . '" />' . " \n " ;
2024-05-21 20:13:39 +02:00
// Add favicon
2025-01-12 18:19:32 +01:00
if ( in_array ( $objectpage -> type_container , array ( 'page' , 'blogpost' ))) {
2024-05-21 20:13:39 +02:00
$tplcontent .= '<link rel="icon" type="image/png" href="/favicon.png" />' . " \n " ;
2019-12-07 13:09:55 +01:00
}
2021-04-18 13:45:46 +02:00
2025-01-22 21:13:26 +01:00
$listofaltlang = $object -> otherlang ;
2025-01-22 16:28:05 +01:00
// Note: $object is website, $objectpage is website page
2024-05-21 20:13:39 +02:00
if ( $object -> virtualhost ) {
2025-01-26 21:14:13 +01:00
// Add the link of the canonical reference
2025-01-22 21:13:26 +01:00
$canonicalurladdidlang = '' ;
if ( $objectpage -> lang ) { // A language is forced on the page, it means we may have other language files with hard links into properties of page
2025-01-22 16:28:05 +01:00
$canonicalurl = (( $objectpage -> id == $object -> fk_default_home ) ? '/' : (( $shortlangcode != substr ( $object -> lang , 0 , 2 ) ? '/' . $shortlangcode : '' ) . '/' . $objectpage -> pageurl . '.php' ));
2025-01-26 17:42:43 +01:00
} else { // No language forced, it means the canonical is the one with params making url unique
2025-01-22 16:28:05 +01:00
$canonicalurl = '/' . $objectpage -> pageurl . '.php' ;
2025-01-22 21:13:26 +01:00
if ( $object -> lang && $listofaltlang ) {
2025-01-22 16:28:05 +01:00
// Add parameter ID required to be unique/canonical
2025-01-26 17:42:43 +01:00
$canonicalurladdidlang = '?__SEO_CANONICAL_URL_PARAMS__' ;
2025-01-26 21:14:13 +01:00
$canonicalurladdidlang .= '&l=__SEO_CANONICAL_LANG__' ;
2025-01-22 16:28:05 +01:00
} else {
// Add parameter ID required to be unique/canonical
2025-01-26 17:42:43 +01:00
$canonicalurladdidlang = '?__SEO_CANONICAL_URL_PARAMS__' ;
2019-12-07 16:59:35 +01:00
}
}
2021-04-18 13:45:46 +02:00
2025-01-22 21:13:26 +01:00
$tplcontent .= '<link rel="canonical" href="<?php echo $website->virtualhost; ?>' . $canonicalurl . $canonicalurladdidlang . '" />' . " \n " ;
2021-04-18 13:45:46 +02:00
2025-01-22 21:13:26 +01:00
// Add the link of alternate translation reference
if ( $listofaltlang ) { // If website has other languages to support
if ( $objectpage -> lang ) { // A language is forced on the page, it means we may have other language files with hard links into properties of page
// Add page "translation of"
$translationof = $objectpage -> fk_page ;
if ( $translationof ) {
$tmppage = new WebsitePage ( $db );
$tmppage -> fetch ( $translationof );
if ( $tmppage -> id > 0 ) {
2025-01-22 16:28:05 +01:00
$tmpshortlangcode = '' ;
2025-01-22 21:13:26 +01:00
if ( $tmppage -> lang ) {
$tmpshortlangcode = preg_replace ( '/[_-].*$/' , '' , $tmppage -> lang ); // en_US or en-US -> en
}
if ( empty ( $tmpshortlangcode )) {
$tmpshortlangcode = preg_replace ( '/[_-].*$/' , '' , $object -> lang ); // en_US or en-US -> en
2025-01-22 16:28:05 +01:00
}
if ( $tmpshortlangcode != $shortlangcode ) {
2025-01-22 21:13:26 +01:00
$tplcontent .= '<link rel="alternate" hreflang="' . $tmpshortlangcode . '" href="<?php echo $website->virtualhost; ?>' . ( $object -> fk_default_home == $tmppage -> id ? '/' : (( $tmpshortlangcode != substr ( $object -> lang , 0 , 2 )) ? '/' . $tmpshortlangcode : '' ) . '/' . $tmppage -> pageurl . '.php' ) . '" />' . " \n " ;
2025-01-22 16:28:05 +01:00
}
}
}
2025-01-22 21:13:26 +01:00
// Add "has translation pages"
$sql = " SELECT rowid as id, lang, pageurl from " . MAIN_DB_PREFIX . 'website_page where fk_page IN (' . $db -> sanitize ( $objectpage -> id . ( $translationof ? " , " . $translationof : '' )) . " ) " ;
$resql = $db -> query ( $sql );
if ( $resql ) {
$num_rows = $db -> num_rows ( $resql );
if ( $num_rows > 0 ) {
while ( $obj = $db -> fetch_object ( $resql )) {
$tmpshortlangcode = '' ;
if ( $obj -> lang ) {
$tmpshortlangcode = preg_replace ( '/[_-].*$/' , '' , $obj -> lang ); // en_US or en-US -> en
}
if ( $tmpshortlangcode != $shortlangcode ) {
$tplcontent .= '<link rel="alternate" hreflang="' . $tmpshortlangcode . '" href="<?php echo $website->virtualhost; ?>' . ( $object -> fk_default_home == $obj -> id ? '/' : (( $tmpshortlangcode != substr ( $object -> lang , 0 , 2 ) ? '/' . $tmpshortlangcode : '' )) . '/' . $obj -> pageurl . '.php' ) . '" />' . " \n " ;
}
}
}
} else {
dol_print_error ( $db );
}
// Add myself
$tplcontent .= '<?php if ($_SERVER["PHP_SELF"] == "' . (( $object -> fk_default_home == $objectpage -> id ) ? '/' : (( $shortlangcode != substr ( $object -> lang , 0 , 2 )) ? '/' . $shortlangcode : '' )) . '/' . $objectpage -> pageurl . '.php") { ?>' . " \n " ;
$tplcontent .= '<link rel="alternate" hreflang="' . $shortlangcode . '" href="<?php echo $website->virtualhost; ?>' . (( $object -> fk_default_home == $objectpage -> id ) ? '/' : (( $shortlangcode != substr ( $object -> lang , 0 , 2 )) ? '/' . $shortlangcode : '' ) . '/' . $objectpage -> pageurl . '.php' ) . '" />' . " \n " ;
2024-05-21 20:13:39 +02:00
2025-01-22 21:13:26 +01:00
$tplcontent .= '<?php } ?>' . " \n " ;
2025-01-26 17:42:43 +01:00
} else { // No language forced, it means the canonical is the one withparams making url unique
2025-01-22 21:13:26 +01:00
$canonicalurl = '/' . $objectpage -> pageurl . '.php' ;
$arrayofaltlang = explode ( ',' , $listofaltlang );
2025-01-22 21:21:29 +01:00
2025-01-22 21:13:26 +01:00
foreach ( $arrayofaltlang as $altlang ) {
// Add parameter ID required to be unique/canonical
2025-01-26 17:42:43 +01:00
$canonicalurladdidlang = '?__SEO_CANONICAL_URL_PARAMS__' ;
$canonicalurladdidlang .= '&l=' . $altlang ;
2025-01-22 21:13:26 +01:00
$tplcontent .= '<link rel="alternate" hreflang="' . $altlang . '" href="<?php echo $website->virtualhost; ?>' . $canonicalurl . $canonicalurladdidlang . '" />' . " \n " ;
}
2025-01-22 21:21:29 +01:00
$tmpshortlangcode = preg_replace ( '/[_-].*$/' , '' , $object -> lang ); // en_US or en-US -> en
2025-01-26 17:42:43 +01:00
$canonicalurladdidlang = '?__SEO_CANONICAL_URL_PARAMS__' ;
$canonicalurladdidlang .= '&l=' . $tmpshortlangcode ;
2025-01-22 21:21:29 +01:00
$tplcontent .= '<link rel="alternate" hreflang="' . $tmpshortlangcode . '" href="<?php echo $website->virtualhost; ?>' . $canonicalurl . $canonicalurladdidlang . '" />' . " \n " ;
2025-01-22 21:13:26 +01:00
}
2025-01-22 16:28:05 +01:00
}
2024-05-21 20:13:39 +02:00
}
2025-01-22 21:13:26 +01:00
2024-05-21 20:13:39 +02:00
// Add manifest.json. Do we have to add it only on home page ?
$tplcontent .= '<?php if ($website->use_manifest) { print \'<link rel="manifest" href="/manifest.json.php" />\'."\n"; } ?>' . " \n " ;
2025-01-28 20:01:46 +01:00
// Add HTML headers (must be before the Add of the common CSS and js). The common js may content javascript using jquery or a framework loaded by the HTML header.
2024-05-21 20:13:39 +02:00
$tplcontent .= '<!-- Include HTML header from common file -->' . " \n " ;
$tplcontent .= '<?php if (file_exists(DOL_DATA_ROOT."/website/".$websitekey."/htmlheader.html")) include DOL_DATA_ROOT."/website/".$websitekey."/htmlheader.html"; ?>' . " \n " ;
$tplcontent .= '<!-- Include HTML header from page header block -->' . " \n " ;
$tplcontent .= preg_replace ( '/<\/?html>/ims' , '' , $objectpage -> htmlheader ) . " \n " ;
2025-01-28 20:01:46 +01:00
// Add css
2025-01-28 20:08:04 +01:00
$tplcontent .= '<!-- Include link to common CSS file -->' . " \n " ;
2025-01-28 20:01:46 +01:00
$tplcontent .= '<link rel="stylesheet" href="/styles.css.php?website=<?php echo $websitekey; ?>" type="text/css" />' . " \n " ;
// Add js
2025-01-28 20:08:04 +01:00
$tplcontent .= '<!-- Include link to common JS file -->' . " \n " ;
2025-01-28 20:01:46 +01:00
$tplcontent .= '<script nonce="' . getNonce () . '" async src="/javascript.js.php?website=<?php echo $websitekey; ?>"></script>' . " \n " ;
2024-05-21 20:13:39 +02:00
$tplcontent .= '</head>' . " \n " ;
2025-01-28 20:01:46 +01:00
// Page content
2025-01-28 19:01:38 +01:00
$tplcontent .= '<!-- File content defined in Dolibarr website module editor -->' . " \n " ;
2024-05-21 20:13:39 +02:00
$tplcontent .= '<body id="bodywebsite" class="bodywebsite bodywebpage-' . $objectpage -> ref . '">' . " \n " ;
$tplcontent .= $objectpage -> content . " \n " ;
$tplcontent .= '</body>' . " \n " ;
$tplcontent .= '</html>' . " \n " ;
$tplcontent .= '<?php // BEGIN PHP' . " \n " ;
2025-01-28 19:01:38 +01:00
$tplcontent .= '} catch(Exception $e) { print $e->getMessages(); }' . " \n " ;
2025-01-22 16:28:05 +01:00
$tplcontent .= '$tmp = ob_get_contents(); ob_end_clean();' . " \n " ; // replace with ob_get_clean ?
2025-01-26 17:42:43 +01:00
$tplcontent .= " // Now fix the content for SEO or multilanguage \n " ;
2025-01-22 16:28:05 +01:00
// Old method for custom SEO
2024-09-04 23:14:25 +02:00
if ( strpos ( $objectpage -> content , '$__PAGE__KEYWORDS__' ) !== false ) {
2025-01-28 01:05:12 +01:00
$tplcontent .= '$tmp = preg_replace("/^<meta name=\"keywords\" content=\".*?\" \/>/ms", "<meta name=\"keywords\" content=\"" . dolPrintHTMLForAttribute($__PAGE__KEYWORDS__ ?? "", 1) . "\" />", $tmp);' . " \n " ;
2025-01-26 17:42:43 +01:00
}
if ( strpos ( $objectpage -> content , '$__PAGE__TITLE__' ) !== false ) {
2025-01-28 01:05:12 +01:00
$tplcontent .= '$tmp = preg_replace("/^<title>.*?<\/title>/ms", "<title>" . dolPrintHTMLForAttribute($__PAGE__TITLE__ ?? "", 1) . "</title>", $tmp);' . " \n " ;
$tplcontent .= '$tmp = preg_replace("/^<meta name=\"title\" content=\".*?\" \/>/ms", "<meta name=\"title\" content=\"" . dolPrintHTMLForAttribute($__PAGE__TITLE__ ?? "", 1) . "\" />", $tmp);' . " \n " ;
2024-09-04 23:14:25 +02:00
}
if ( strpos ( $objectpage -> content , '$__PAGE__DESC__' ) !== false ) {
2025-01-28 01:05:12 +01:00
$tplcontent .= '$tmp = preg_replace("/^<meta name=\"description\" content=\".*?\" \/>/ms", "<meta name=\"description\" content=\"" . dolPrintHTMLForAttribute($__PAGE__DESC__ ?? "", 1) . "\" />", $tmp);' . " \n " ;
2024-09-04 23:14:25 +02:00
}
2025-01-22 16:28:05 +01:00
// New method for custom SEO
2025-01-26 20:52:16 +01:00
if ( strpos ( $objectpage -> content , 'define("__SEO_PAGE_LANG__"' ) !== false ) {
2025-01-26 21:27:44 +01:00
$tmpshortlangcode = preg_replace ( '/[_-].*$/' , '' , $object -> lang ); // en_US or en-US -> en
$tplcontent .= '$tmp = preg_replace("/^<html lang=\"[a-z]+\"/ms", "<html lang=\"" . dolPrintHTMLForAttribute(defined("__SEO_PAGE_LANG__") ? preg_replace(\'/\[_-\].*$/\', "", constant("__SEO_PAGE_LANG__")) : (empty($weblangs->shortlang) ? "' . $tmpshortlangcode . '" : $weblangs->shortlang), 1) . "\"", $tmp);' . " \n " ;
2025-01-26 20:52:16 +01:00
}
2025-01-22 18:48:03 +01:00
if ( strpos ( $objectpage -> content , 'define("__SEO_PAGE_KEYWORDS__"' ) !== false ) {
2025-01-26 20:39:54 +01:00
$tplcontent .= '$tmp = preg_replace("/^<meta name=\"keywords\" content=\".*?\" \/>/ms", "<meta name=\"keywords\" content=\"" . dolPrintHTMLForAttribute(constant("__SEO_PAGE_KEYWORDS__"), 1) . "\" />", $tmp);' . " \n " ;
2025-01-26 17:42:43 +01:00
}
if ( strpos ( $objectpage -> content , 'define("__SEO_PAGE_TITLE__"' ) !== false ) {
2025-01-26 20:39:54 +01:00
$tplcontent .= '$tmp = preg_replace("/^<title>.*?<\/title>/ms", "<title>" . dolPrintHTMLForAttribute(constant("__SEO_PAGE_TITLE__"), 1) . "</title>", $tmp);' . " \n " ;
$tplcontent .= '$tmp = preg_replace("/^<meta name=\"title\" content=\".*?\" \/>/ms", "<meta name=\"title\" content=\"" . dolPrintHTMLForAttribute(constant("__SEO_PAGE_TITLE__"), 1) . "\" />", $tmp);' . " \n " ;
2025-01-22 16:28:05 +01:00
}
2025-01-22 18:48:03 +01:00
if ( strpos ( $objectpage -> content , 'define("__SEO_PAGE_DESC__"' ) !== false ) {
2025-01-26 20:39:54 +01:00
$tplcontent .= '$tmp = preg_replace("/^<meta name=\"description\" content=\".*?\" \/>/ms", "<meta name=\"description\" content=\"" . dolPrintHTMLForAttribute(constant("__SEO_PAGE_DESC__"), 1) . "\" />", $tmp);' . " \n " ;
2025-01-26 17:42:43 +01:00
}
if ( empty ( $objectpage -> lang )) { // We may need to use param into the canonical url
2025-01-26 20:37:41 +01:00
$tplcontent .= 'defined("__SEO_CANONICAL_URL_PARAMS__") ? ($tmp = preg_replace("/__SEO_CANONICAL_URL_PARAMS__/", dolPrintHTMLForAttributeUrl(constant("__SEO_CANONICAL_URL_PARAMS__")), $tmp)) : ($tmp = preg_replace("/\?__SEO_CANONICAL_URL_PARAMS__\"/", "", preg_replace("/\?__SEO_CANONICAL_URL_PARAMS__&/", "?", $tmp)));' . " \n " ;
2025-01-26 21:14:13 +01:00
$tmpshortlangcode = preg_replace ( '/[_-].*$/' , '' , $object -> lang ); // en_US or en-US -> en
$tplcontent .= '$tmp = preg_replace("/__SEO_CANONICAL_LANG__/", (defined("__SEO_PAGE_LANG__") ? preg_replace(\'/\[_-\].*$/\', "", constant("__SEO_PAGE_LANG__")) : (empty($weblangs->shortlang) ? "' . $tmpshortlangcode . '" : $weblangs->shortlang)), $tmp);' . " \n " ;
2025-01-22 16:28:05 +01:00
}
2025-01-26 17:42:43 +01:00
$tplcontent .= " // Now output the generated page content \n " ;
2025-01-22 16:28:05 +01:00
$tplcontent .= 'dolWebsiteOutput($tmp, "html", ' . (( int ) $objectpage -> id ) . '); dolWebsiteIncrementCounter(' . (( int ) $object -> id ) . ', "' . $objectpage -> type_container . '", ' . (( int ) $objectpage -> id ) . ');' . " \n " ;
2024-05-21 20:13:39 +02:00
$tplcontent .= " // END PHP ?> \n " ;
} else {
2024-07-03 01:53:37 +02:00
$tplcontent .= " <?php // BEGIN PHP \n " ;
$tplcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;' . " \n " ;
$tplcontent .= " if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { \n " ;
$tplcontent .= ' $pathdepth = count(explode(\'/\', $_SERVER[\'SCRIPT_NAME\'])) - 2;' . " \n " ;
$tplcontent .= ' require_once ($pathdepth ? str_repeat(\'../\', $pathdepth) : \'./\').\'master.inc.php\';' . " \n " ;
$tplcontent .= " } // Not already loaded \n " ;
$tplcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php'; \n " ;
$tplcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php'; \n " ;
$tplcontent .= " // END PHP ?> \n " ;
2024-05-21 20:13:39 +02:00
$tplcontent .= $objectpage -> content ;
2020-05-19 00:50:30 +02:00
}
2019-08-12 22:19:24 +02:00
//var_dump($filetpl);exit;
$result = file_put_contents ( $filetpl , $tplcontent );
2023-02-17 19:30:50 +01:00
dolChmod ( $filetpl );
2019-08-12 22:19:24 +02:00
2021-01-24 13:27:52 +01:00
return $result ;
2019-08-12 22:19:24 +02:00
}
/**
2021-05-20 10:34:49 +02:00
* Save content of the index . php and / or the wrapper . php page
2019-08-12 22:19:24 +02:00
*
* @ param string $pathofwebsite Path of website root
* @ param string $fileindex Full path of file index . php
2021-05-20 10:34:49 +02:00
* @ param string $filetpl File tpl the index . php page redirect to ( used only if $fileindex is provided )
2019-08-12 22:19:24 +02:00
* @ param string $filewrapper Full path of file wrapper . php
2022-05-12 00:52:28 +02:00
* @ param Website $object Object website
2019-08-12 22:19:24 +02:00
* @ return boolean True if OK
*/
2022-05-12 00:52:28 +02:00
function dolSaveIndexPage ( $pathofwebsite , $fileindex , $filetpl , $filewrapper , $object = null )
2019-08-12 22:19:24 +02:00
{
2024-01-23 20:13:27 +01:00
global $db ;
2019-08-12 22:19:24 +02:00
2019-11-13 19:35:02 +01:00
$result1 = false ;
$result2 = false ;
2019-08-12 22:19:24 +02:00
dol_mkdir ( $pathofwebsite );
2020-05-23 13:10:33 +02:00
if ( $fileindex ) {
dol_delete_file ( $fileindex );
$indexcontent = '<?php' . " \n " ;
$indexcontent .= " // BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper. \n " ;
$indexcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;' . " \n " ;
$indexcontent .= " if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load master if not already loaded \n " ;
2022-08-31 22:14:20 +02:00
$indexcontent .= 'if (!empty($_GET[\'pageref\']) || !empty($_GET[\'pagealiasalt\']) || !empty($_GET[\'pageid\'])) {' . " \n " ;
2020-05-23 13:10:33 +02:00
$indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php'; \n " ;
$indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php'; \n " ;
$indexcontent .= ' redirectToContainer($_GET[\'pageref\'], $_GET[\'pagealiasalt\'], $_GET[\'pageid\']);' . " \n " ;
$indexcontent .= " } \n " ;
$indexcontent .= " include_once './ " . basename ( $filetpl ) . " ' \n " ;
$indexcontent .= '// END PHP ?>' . " \n " ;
$result1 = file_put_contents ( $fileindex , $indexcontent );
2023-02-17 19:30:50 +01:00
dolChmod ( $fileindex );
2022-05-12 00:52:28 +02:00
2022-05-12 01:37:20 +02:00
if ( is_object ( $object ) && $object -> fk_default_home > 0 ) {
2022-05-12 01:38:46 +02:00
$objectpage = new WebsitePage ( $db );
2022-05-12 00:52:28 +02:00
$objectpage -> fetch ( $object -> fk_default_home );
// Create a version for sublanguages
if ( empty ( $objectpage -> lang ) || ! in_array ( $objectpage -> lang , explode ( ',' , $object -> otherlang ))) {
2023-11-27 11:39:32 +01:00
if ( ! getDolGlobalString ( 'WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR' ) && is_object ( $object ) && ! empty ( $object -> otherlang )) {
2022-05-12 00:52:28 +02:00
$dirname = dirname ( $fileindex );
foreach ( explode ( ',' , $object -> otherlang ) as $sublang ) {
// Avoid to erase main alias file if $sublang is empty string
2023-12-04 12:05:28 +01:00
if ( empty ( trim ( $sublang ))) {
continue ;
}
2022-05-12 00:52:28 +02:00
$fileindexsub = $dirname . '/' . $sublang . '/index.php' ;
// Same indexcontent than previously but with ../ instead of ./ for master and tpl file include/require_once.
$relpath = '..' ;
$indexcontent = '<?php' . " \n " ;
$indexcontent .= " // BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper. \n " ;
$indexcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;' . " \n " ;
$indexcontent .= " if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once ' " . $relpath . " /master.inc.php'; } // Load master if not already loaded \n " ;
2022-08-31 22:14:20 +02:00
$indexcontent .= 'if (!empty($_GET[\'pageref\']) || !empty($_GET[\'pagealiasalt\']) || !empty($_GET[\'pageid\'])) {' . " \n " ;
2022-05-12 00:52:28 +02:00
$indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php'; \n " ;
$indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php'; \n " ;
$indexcontent .= ' redirectToContainer($_GET[\'pageref\'], $_GET[\'pagealiasalt\'], $_GET[\'pageid\']);' . " \n " ;
$indexcontent .= " } \n " ;
$indexcontent .= " include_once ' " . $relpath . " / " . basename ( $filetpl ) . " ' \n " ; // use .. instead of .
$indexcontent .= '// END PHP ?>' . " \n " ;
$result = file_put_contents ( $fileindexsub , $indexcontent );
if ( $result === false ) {
dol_syslog ( " Failed to write file " . $fileindexsub , LOG_WARNING );
}
2023-02-17 19:30:50 +01:00
dolChmod ( $fileindexsub );
2022-05-12 00:52:28 +02:00
}
}
}
}
2020-05-23 21:07:47 +02:00
} else {
2020-05-23 13:10:33 +02:00
$result1 = true ;
2020-03-21 19:37:09 +01:00
}
2019-08-12 22:19:24 +02:00
2020-05-23 13:10:33 +02:00
if ( $filewrapper ) {
dol_delete_file ( $filewrapper );
$wrappercontent = file_get_contents ( DOL_DOCUMENT_ROOT . '/website/samples/wrapper.php' );
2019-08-12 22:19:24 +02:00
2020-05-23 13:10:33 +02:00
$result2 = file_put_contents ( $filewrapper , $wrappercontent );
2023-02-17 19:30:50 +01:00
dolChmod ( $filewrapper );
2020-05-23 13:10:33 +02:00
} else {
$result2 = true ;
2020-03-21 19:37:09 +01:00
}
2019-08-12 22:19:24 +02:00
2020-03-21 19:37:09 +01:00
return ( $result1 && $result2 );
2019-08-12 22:19:24 +02:00
}
/**
* Save content of a page on disk
*
* @ param string $filehtmlheader Full path of filename to generate
* @ param string $htmlheadercontent Content of file
* @ return boolean True if OK
*/
function dolSaveHtmlHeader ( $filehtmlheader , $htmlheadercontent )
{
2024-01-23 20:13:27 +01:00
global $pathofwebsite ;
2019-08-12 22:19:24 +02:00
dol_syslog ( " Save html header into " . $filehtmlheader );
dol_mkdir ( $pathofwebsite );
$result = file_put_contents ( $filehtmlheader , $htmlheadercontent );
2023-02-17 19:30:50 +01:00
dolChmod ( $filehtmlheader );
2019-08-12 22:19:24 +02:00
2019-08-14 16:28:41 +02:00
return $result ;
2019-08-12 22:19:24 +02:00
}
/**
* Save content of a page on disk
*
* @ param string $filecss Full path of filename to generate
* @ param string $csscontent Content of file
* @ return boolean True if OK
*/
function dolSaveCssFile ( $filecss , $csscontent )
{
2024-01-23 20:13:27 +01:00
global $pathofwebsite ;
2019-08-12 22:19:24 +02:00
dol_syslog ( " Save css file into " . $filecss );
dol_mkdir ( $pathofwebsite );
$result = file_put_contents ( $filecss , $csscontent );
2023-02-17 19:30:50 +01:00
dolChmod ( $filecss );
2019-08-12 22:19:24 +02:00
2019-08-14 16:28:41 +02:00
return $result ;
2019-08-12 22:19:24 +02:00
}
/**
2020-06-03 00:46:09 +02:00
* Save content of a page on disk . For example into documents / website / mywebsite / javascript . js . php file .
2019-08-12 22:19:24 +02:00
*
* @ param string $filejs Full path of filename to generate
* @ param string $jscontent Content of file
* @ return boolean True if OK
*/
function dolSaveJsFile ( $filejs , $jscontent )
{
2024-01-23 20:13:27 +01:00
global $pathofwebsite ;
2019-08-12 22:19:24 +02:00
dol_syslog ( " Save js file into " . $filejs );
dol_mkdir ( $pathofwebsite );
$result = file_put_contents ( $filejs , $jscontent );
2023-02-17 19:30:50 +01:00
dolChmod ( $filejs );
2019-08-12 22:19:24 +02:00
2019-08-14 16:28:41 +02:00
return $result ;
2019-08-12 22:19:24 +02:00
}
/**
* Save content of a page on disk
*
* @ param string $filerobot Full path of filename to generate
* @ param string $robotcontent Content of file
* @ return boolean True if OK
*/
function dolSaveRobotFile ( $filerobot , $robotcontent )
{
2024-01-23 20:13:27 +01:00
global $pathofwebsite ;
2019-08-12 22:19:24 +02:00
dol_syslog ( " Save robot file into " . $filerobot );
dol_mkdir ( $pathofwebsite );
$result = file_put_contents ( $filerobot , $robotcontent );
2023-02-17 19:30:50 +01:00
dolChmod ( $filerobot );
2019-08-12 22:19:24 +02:00
2019-08-14 16:28:41 +02:00
return $result ;
2019-08-12 22:19:24 +02:00
}
/**
* Save content of a page on disk
*
* @ param string $filehtaccess Full path of filename to generate
* @ param string $htaccess Content of file
* @ return boolean True if OK
*/
function dolSaveHtaccessFile ( $filehtaccess , $htaccess )
{
2024-01-23 20:13:27 +01:00
global $pathofwebsite ;
2019-08-12 22:19:24 +02:00
dol_syslog ( " Save htaccess file into " . $filehtaccess );
dol_mkdir ( $pathofwebsite );
$result = file_put_contents ( $filehtaccess , $htaccess );
2023-02-17 19:30:50 +01:00
dolChmod ( $filehtaccess );
2019-08-12 22:19:24 +02:00
2019-08-14 16:28:41 +02:00
return $result ;
2019-08-13 04:43:50 +02:00
}
/**
* Save content of a page on disk
*
* @ param string $file Full path of filename to generate
* @ param string $content Content of file
* @ return boolean True if OK
*/
function dolSaveManifestJson ( $file , $content )
{
2024-01-23 20:13:27 +01:00
global $pathofwebsite ;
2019-08-13 04:43:50 +02:00
dol_syslog ( " Save manifest.js.php file into " . $file );
dol_mkdir ( $pathofwebsite );
$result = file_put_contents ( $file , $content );
2023-02-17 19:30:50 +01:00
dolChmod ( $file );
2019-08-13 04:43:50 +02:00
2019-08-14 16:28:41 +02:00
return $result ;
2019-08-12 22:19:24 +02:00
}
2019-08-15 00:55:47 +02:00
/**
* Save content of a page on disk
*
* @ param string $file Full path of filename to generate
* @ param string $content Content of file
* @ return boolean True if OK
*/
function dolSaveReadme ( $file , $content )
{
2024-01-23 20:13:27 +01:00
global $pathofwebsite ;
2019-08-15 00:55:47 +02:00
dol_syslog ( " Save README.md file into " . $file );
dol_mkdir ( $pathofwebsite );
$result = file_put_contents ( $file , $content );
2023-02-17 19:30:50 +01:00
dolChmod ( $file );
2019-08-15 00:55:47 +02:00
2022-05-12 00:52:28 +02:00
return $result ;
2019-08-15 00:55:47 +02:00
}
2019-08-12 22:19:24 +02:00
2022-09-03 19:02:42 +02:00
/**
* Save content of a page on disk
*
* @ param string $file Full path of filename to generate
* @ param string $content Content of file
* @ return boolean True if OK
*/
function dolSaveLicense ( $file , $content )
{
2024-01-23 20:13:27 +01:00
global $pathofwebsite ;
2022-09-03 19:02:42 +02:00
dol_syslog ( " Save LICENSE file into " . $file );
dol_mkdir ( $pathofwebsite );
$result = file_put_contents ( $file , $content );
2023-02-17 19:30:50 +01:00
dolChmod ( $file );
2022-09-03 19:02:42 +02:00
return $result ;
}
2019-08-12 22:19:24 +02:00
/**
2019-08-15 01:58:22 +02:00
* Show list of themes . Show all thumbs of themes / skins
2019-08-12 22:19:24 +02:00
*
2020-12-05 15:35:52 +01:00
* @ param Website $website Object website to load the template into
2019-08-12 22:19:24 +02:00
* @ return void
*/
function showWebsiteTemplates ( Website $website )
{
2024-02-09 17:54:57 +01:00
global $conf , $langs , $form , $user ;
2019-08-12 22:19:24 +02:00
2024-12-29 20:14:21 +01:00
// We want only one directory for dir of website templates. If an external module need to provide a template, the template must be copied into this directory
// when module is enabled.
2019-11-13 19:35:02 +01:00
$dirthemes = array ( '/doctemplates/websites' );
2019-08-12 22:19:24 +02:00
2019-11-13 19:35:02 +01:00
$colspan = 2 ;
2019-08-12 22:19:24 +02:00
2020-06-19 10:36:19 +02:00
print '<!-- For website template import -->' . " \n " ;
2019-11-05 21:24:41 +01:00
print '<table class="noborder centpercent">' ;
2019-08-12 22:19:24 +02:00
// Title
2020-04-13 22:52:34 +02:00
print '<tr class="liste_titre"><th class="titlefield">' ;
Qual: Apply automatic phan fixes (deprecations, unneeded imports) (#28154)
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
2024-02-13 21:46:12 +01:00
print $form -> textwithpicto ( $langs -> trans ( " Templates " ), $langs -> trans ( " ThemeDir " ) . ' : ' . implode ( " , " , $dirthemes ));
2022-10-09 15:52:37 +02:00
print ' ' ;
2024-01-23 14:17:14 +01:00
print '<a href="' . $_SERVER [ " PHP_SELF " ] . '?website=' . urlencode ( $website -> ref ) . '&importsite=1" rel="noopener noreferrer external">' ;
2022-10-09 15:52:37 +02:00
print img_picto ( '' , 'refresh' );
print '</a>' ;
2020-04-13 22:52:34 +02:00
print '</th>' ;
2019-08-12 22:19:24 +02:00
print '<th class="right">' ;
2019-11-13 19:35:02 +01:00
$url = 'https://www.dolistore.com/43-web-site-templates' ;
2021-11-22 02:35:55 +01:00
print '<a href="' . $url . '" target="_blank" rel="noopener noreferrer external">' ;
2022-10-09 15:52:37 +02:00
print img_picto ( '' , 'globe' , 'class="pictofixedwidth"' ) . $langs -> trans ( 'DownloadMoreSkins' );
2019-08-12 22:19:24 +02:00
print '</a>' ;
print '</th></tr>' ;
print '<tr><td colspan="' . $colspan . '">' ;
2024-01-23 14:15:31 +01:00
print '<table class="nobordernopadding centpercent"><tr><td><div class="display-flex">' ;
2019-08-12 22:19:24 +02:00
2020-04-13 22:52:34 +02:00
if ( count ( $dirthemes )) {
$i = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $dirthemes as $dir ) {
2024-12-29 20:14:21 +01:00
$dirtheme = DOL_DATA_ROOT . $dir ;
2021-02-23 22:03:23 +01:00
if ( is_dir ( $dirtheme )) {
2020-04-13 22:52:34 +02:00
$handle = opendir ( $dirtheme );
2021-02-23 22:03:23 +01:00
if ( is_resource ( $handle )) {
while (( $subdir = readdir ( $handle )) !== false ) {
2024-02-12 01:54:15 +01:00
//var_dump($dirtheme.'/'.$subdir);
2024-12-29 20:14:21 +01:00
if ( dol_is_file ( $dirtheme . " / " . $subdir ) && substr ( $subdir , 0 , 1 ) != '.' && substr ( $subdir , 0 , 3 ) != 'CVS' && preg_match ( '/\.zip$/i' , $subdir )) {
2022-10-09 13:00:34 +02:00
$subdirwithoutzip = preg_replace ( '/\.zip$/i' , '' , $subdir );
2024-12-29 20:14:21 +01:00
$subdirwithoutzipwithoutver = preg_replace ( '/(_exp|_dev)$/i' , '' , $subdirwithoutzip );
2020-04-13 22:52:34 +02:00
2022-10-09 13:00:34 +02:00
// Disable not stable themes (dir ends with _exp or _dev)
2024-12-29 20:14:21 +01:00
if ( getDolGlobalInt ( 'MAIN_FEATURES_LEVEL' ) < 2 && preg_match ( '/_dev$/i' , $subdirwithoutzip )) {
2021-02-23 22:03:23 +01:00
continue ;
}
2024-12-29 20:14:21 +01:00
if ( getDolGlobalInt ( 'MAIN_FEATURES_LEVEL' ) < 1 && preg_match ( '/_exp$/i' , $subdirwithoutzip )) {
2021-02-23 22:03:23 +01:00
continue ;
}
2020-04-13 22:52:34 +02:00
2024-01-23 14:15:31 +01:00
print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px; margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;">' ;
2020-04-13 22:52:34 +02:00
2022-10-09 13:00:34 +02:00
$templatedir = $dirtheme . " / " . $subdir ;
2024-12-29 20:14:21 +01:00
$file = $dirtheme . " / " . $subdirwithoutzipwithoutver . " .jpg " ;
$url = DOL_URL_ROOT . '/viewimage.php?modulepart=doctemplateswebsite&file=' . $subdirwithoutzipwithoutver . " .jpg " ;
2020-04-13 22:52:34 +02:00
2021-02-23 22:03:23 +01:00
if ( ! file_exists ( $file )) {
$url = DOL_URL_ROOT . '/public/theme/common/nophoto.png' ;
}
2020-04-13 22:52:34 +02:00
2024-12-29 20:14:21 +01:00
$originalimgfile = basename ( $file );
2022-10-09 13:00:34 +02:00
$entity = $conf -> entity ;
$modulepart = 'doctemplateswebsite' ;
$cache = '' ;
$title = $file ;
2020-04-13 22:52:34 +02:00
2022-10-09 13:00:34 +02:00
$ret = '' ;
2024-12-29 20:14:21 +01:00
$urladvanced = getAdvancedPreviewUrl ( $modulepart , $originalimgfile , 1 , '&entity=' . $entity );
2021-02-23 22:03:23 +01:00
if ( ! empty ( $urladvanced )) {
$ret .= '<a class="' . $urladvanced [ 'css' ] . '" target="' . $urladvanced [ 'target' ] . '" mime="' . $urladvanced [ 'mime' ] . '" href="' . $urladvanced [ 'url' ] . '">' ;
} else {
2024-12-29 20:14:21 +01:00
$ret .= '<a href="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . urlencode ( $modulepart ) . '&entity=' . (( int ) $entity ) . '&file=' . urlencode ( $originalimgfile ) . '&cache=' . (( int ) $cache ) . '">' ;
2021-02-23 22:03:23 +01:00
}
2022-10-09 13:00:34 +02:00
print $ret ;
print '<img class="img-skinthumb shadow" src="' . $url . '" border="0" alt="' . $title . '" title="' . $title . '" style="margin-bottom: 5px;">' ;
print '</a>' ;
print '<br>' ;
print $subdir ;
print '<br>' ;
print '<span class="opacitymedium">' . dol_print_size ( dol_filesize ( $dirtheme . " / " . $subdir ), 1 , 1 ) . ' - ' . dol_print_date ( dol_filemtime ( $templatedir ), 'dayhour' , 'tzuserrel' ) . '</span>' ;
2022-10-09 15:52:37 +02:00
if ( $user -> hasRight ( 'website' , 'delete' )) {
print ' <a href="' . $_SERVER [ " PHP_SELF " ] . '?action=deletetemplate&token=' . newToken () . '&website=' . urlencode ( $website -> ref ) . '&templateuserfile=' . urlencode ( $subdir ) . '">' . img_picto ( '' , 'delete' ) . '</a>' ;
}
2022-10-09 13:00:34 +02:00
print '<br><a href="' . $_SERVER [ " PHP_SELF " ] . '?action=importsiteconfirm&token=' . newToken () . '&website=' . urlencode ( $website -> ref ) . '&templateuserfile=' . urlencode ( $subdir ) . '" class="button">' . $langs -> trans ( " Load " ) . '</a>' ;
print '</div>' ;
$i ++ ;
2020-04-13 22:52:34 +02:00
}
2019-08-12 22:19:24 +02:00
}
2024-01-23 14:15:31 +01:00
print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>' ;
print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>' ;
print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>' ;
print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>' ;
print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>' ;
2019-08-12 22:19:24 +02:00
}
}
}
2020-05-21 15:05:19 +02:00
} else {
2020-04-13 22:52:34 +02:00
print '<span class="opacitymedium">' . $langs -> trans ( " None " ) . '</span>' ;
}
2019-08-12 22:19:24 +02:00
print '</div></td></tr></table>' ;
print '</td></tr>' ;
print '</table>' ;
}
2022-02-21 22:50:32 +01:00
/**
2023-02-11 14:09:00 +01:00
* Check a new string containing only php code ( including < php tag )
2024-12-18 15:54:48 +01:00
* - Block if user has no permission to change PHP code .
* - Block also if bad code found in the new string .
2022-02-21 22:50:32 +01:00
*
2024-04-23 11:06:53 +02:00
* @ param string $phpfullcodestringold PHP old string ( before the change ) . For example " <?php echo 'a' ?><php echo 'b' ?> "
2024-01-13 19:48:20 +01:00
* @ param string $phpfullcodestring PHP new string . For example " <?php echo 'a' ?><php echo 'c' ?> "
2022-02-21 22:50:32 +01:00
* @ return int Error or not
2024-07-23 16:37:58 +02:00
* @ see dolKeepOnlyPhpCode (), dol_eval () to see sanitizing rules that should be very close .
2022-02-21 22:50:32 +01:00
*/
2024-04-23 11:06:53 +02:00
function checkPHPCode ( & $phpfullcodestringold , & $phpfullcodestring )
2022-02-21 22:50:32 +01:00
{
2024-03-14 22:06:43 +01:00
global $langs , $user ;
2022-02-21 22:50:32 +01:00
$error = 0 ;
if ( empty ( $phpfullcodestringold ) && empty ( $phpfullcodestring )) {
return 0 ;
}
2024-05-06 15:16:08 +02:00
// First check permission
if ( $phpfullcodestringold != $phpfullcodestring ) {
if ( ! $error && ! $user -> hasRight ( 'website' , 'writephp' )) {
2022-02-21 22:50:32 +01:00
$error ++ ;
2024-05-06 15:16:08 +02:00
setEventMessages ( $langs -> trans ( " NotAllowedToAddDynamicContent " ), null , 'errors' );
2022-02-21 22:50:32 +01:00
}
}
2024-05-06 15:16:08 +02:00
2024-12-23 14:07:08 +01:00
$phpfullcodestringnew = $phpfullcodestring ;
2024-05-06 15:16:08 +02:00
// Then check forbidden commands
if ( ! $error ) {
2024-12-23 14:07:08 +01:00
if ( getDolGlobalString ( " WEBSITE_DISALLOW_DOLLAR_UNDERSCORE " )) {
$phpfullcodestring = preg_replace ( '/\$_COOKIE\[/' , '__DOLLARCOOKIE__' , $phpfullcodestring );
$phpfullcodestring = preg_replace ( '/\$_FILES\[/' , '__DOLLARFILES__' , $phpfullcodestring );
$phpfullcodestring = preg_replace ( '/\$_SESSION\[/' , '__DOLLARSESSION__' , $phpfullcodestring );
$forbiddenphpstrings = array ( '$$' , '$_' , '}[' );
} else {
$forbiddenphpstrings = array ( '$$' , '}[' );
}
//$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_FILES', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST', 'ReflectionFunction'));
2024-12-18 19:00:33 +01:00
$forbiddenphpstrings = array_merge ( $forbiddenphpstrings , array ( '_ENV' , 'ReflectionFunction' ));
2024-07-23 16:37:58 +02:00
$forbiddenphpfunctions = array ();
2024-12-18 19:00:33 +01:00
//$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("base64"."_"."decode", "rawurl"."decode", "url"."decode", "str"."_rot13", "hex"."2bin")); // name of forbidden functions are split to avoid false positive
2024-07-23 16:37:58 +02:00
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " override_function " , " session_id " , " session_create_id " , " session_regenerate_id " ));
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " get_defined_functions " , " get_defined_vars " , " get_defined_constants " , " get_declared_classes " ));
2024-12-18 19:00:33 +01:00
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " call_user_func " , " call_user_func_array " ));
2024-07-23 16:37:58 +02:00
//$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once"));
2024-05-06 15:16:08 +02:00
if ( ! getDolGlobalString ( 'WEBSITE_PHP_ALLOW_EXEC' )) { // If option is not on, we disallow functions to execute commands
2024-07-23 16:37:58 +02:00
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " exec " , " passthru " , " shell_exec " , " system " , " proc_open " , " popen " ));
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " dol_eval " , " executeCLI " , " verifCond " )); // native dolibarr functions
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " eval " , " create_function " , " assert " , " mb_ereg_replace " )); // function with eval capabilities
2024-05-06 15:16:08 +02:00
}
if ( ! getDolGlobalString ( 'WEBSITE_PHP_ALLOW_WRITE' )) { // If option is not on, we disallow functions to write files
2024-12-18 19:00:33 +01:00
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " dol_compress_dir " , " dol_decode " , " dol_delete_file " , " dol_delete_dir " , " dol_delete_dir_recursive " , " dol_copy " , " archiveOrBackupFile " )); // more dolibarr functions
2024-07-23 16:37:58 +02:00
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " fopen " , " file_put_contents " , " fputs " , " fputscsv " , " fwrite " , " fpassthru " , " mkdir " , " rmdir " , " symlink " , " touch " , " unlink " , " umask " ));
2024-05-06 15:16:08 +02:00
}
2024-12-18 19:00:33 +01:00
//$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include"));
2024-07-23 16:37:58 +02:00
$forbiddenphpmethods = array ( 'invoke' , 'invokeArgs' ); // Method of ReflectionFunction to execute a function
foreach ( $forbiddenphpstrings as $forbiddenphpstring ) {
2024-12-18 15:54:48 +01:00
if ( preg_match ( '/' . preg_quote ( $forbiddenphpstring , '/' ) . '/ims' , $phpfullcodestring )) {
2024-07-23 16:37:58 +02:00
$error ++ ;
setEventMessages ( $langs -> trans ( " DynamicPHPCodeContainsAForbiddenInstruction " , $forbiddenphpstring ), null , 'errors' );
break ;
}
}
2024-12-18 19:00:33 +01:00
/* replaced with next block
foreach ( $forbiddenphpfunctions as $forbiddenphpfunction ) { // Check "function(" but also "'function'(" and "function ("
if ( preg_match ( '/' . $forbiddenphpfunction . '[\'\s]*\(/ims' , $phpfullcodestring )) {
$error ++ ;
setEventMessages ( $langs -> trans ( " DynamicPHPCodeContainsAForbiddenInstruction " , $forbiddenphpfunction ), null , 'errors' );
break ;
}
} */
foreach ( $forbiddenphpfunctions as $forbiddenphpfunction ) { // Check "function" whatever is "function(" or "function'(" or "function (" or "function"
if ( preg_match ( '/\b' . $forbiddenphpfunction . '\b/ims' , $phpfullcodestring )) {
2024-05-06 15:16:08 +02:00
$error ++ ;
2024-12-18 15:54:48 +01:00
setEventMessages ( $langs -> trans ( " DynamicPHPCodeContainsAForbiddenInstruction " , $forbiddenphpfunction ), null , 'errors' );
2024-05-06 15:16:08 +02:00
break ;
}
}
2024-12-18 19:00:33 +01:00
2024-07-23 16:37:58 +02:00
foreach ( $forbiddenphpmethods as $forbiddenphpmethod ) {
2024-12-18 15:54:48 +01:00
if ( preg_match ( '/->' . $forbiddenphpmethod . '/ims' , $phpfullcodestring )) {
2024-07-23 16:37:58 +02:00
$error ++ ;
setEventMessages ( $langs -> trans ( " DynamicPHPCodeContainsAForbiddenInstruction " , $forbiddenphpmethod ), null , 'errors' );
break ;
}
}
2024-07-02 01:37:42 +02:00
}
2024-12-18 15:54:48 +01:00
// This char can be used to execute RCE for example by using echo `ls`
2024-07-02 01:37:42 +02:00
if ( ! $error ) {
2024-05-06 15:16:08 +02:00
$forbiddenphpchars = array ();
if ( ! getDolGlobalString ( 'WEBSITE_PHP_ALLOW_DANGEROUS_CHARS' )) { // If option is not on, we disallow functions to execute commands
$forbiddenphpchars = array ( " ` " );
}
foreach ( $forbiddenphpchars as $forbiddenphpchar ) {
2024-12-18 15:54:48 +01:00
if ( preg_match ( '/' . $forbiddenphpchar . '/ims' , $phpfullcodestring )) {
2024-05-06 15:16:08 +02:00
$error ++ ;
setEventMessages ( $langs -> trans ( " DynamicPHPCodeContainsAForbiddenInstruction " , $forbiddenphpchar ), null , 'errors' );
break ;
}
}
2024-07-02 01:37:42 +02:00
}
2024-12-18 15:54:48 +01:00
// Deny code to call a function obfuscated with comment, like "exec/*...*/ ('ls')";
2024-07-02 01:37:42 +02:00
if ( ! $error ) {
2024-12-18 15:54:48 +01:00
if ( preg_match ( '/\*\/\s*\(/ims' , $phpfullcodestring )) {
$error ++ ;
2024-12-18 18:06:08 +01:00
setEventMessages ( $langs -> trans ( " DynamicPHPCodeContainsAForbiddenInstruction " , " exec/*...*/ ('ls') " ), null , 'errors' );
2024-12-18 15:54:48 +01:00
}
}
// Deny dynamic functions '${a}(' or '$a[b](' => So we refuse '}(' and ']('
if ( ! $error ) {
if ( preg_match ( '/[}\]]\s*\(/ims' , $phpfullcodestring )) {
2022-02-21 22:50:32 +01:00
$error ++ ;
2024-05-06 15:16:08 +02:00
setEventMessages ( $langs -> trans ( " DynamicPHPCodeContainsAForbiddenInstruction " , '](' ), null , 'errors' );
}
2024-07-02 01:37:42 +02:00
}
2024-12-18 15:54:48 +01:00
// Deny dynamic functions '$xxx(' or '$xxx (' or '$xxx" ('
2024-07-02 01:37:42 +02:00
if ( ! $error ) {
2024-12-18 15:54:48 +01:00
if ( preg_match ( '/\$[a-z0-9_\-\/\*\"]+\s*\(/ims' , $phpfullcodestring )) {
2024-05-06 15:16:08 +02:00
$error ++ ;
setEventMessages ( $langs -> trans ( " DynamicPHPCodeContainsAForbiddenInstruction " , '$...(' ), null , 'errors' );
2022-02-21 22:50:32 +01:00
}
2022-02-25 01:49:38 +01:00
}
2022-02-21 22:50:32 +01:00
2024-12-18 19:00:33 +01:00
// No need to block $conf->global->aaa() because PHP try to run the method aaa of $conf->global and not the function into $conf->global->aaa.
2024-07-02 01:37:42 +02:00
2024-12-23 14:07:08 +01:00
// Then check if installmodules.lock does not block dynamic PHP code change.
if ( $phpfullcodestringold != $phpfullcodestringnew ) {
2022-11-29 18:01:27 +01:00
if ( ! $error ) {
$dolibarrdataroot = preg_replace ( '/([\\/]+)$/i' , '' , DOL_DATA_ROOT );
$allowimportsite = true ;
2023-02-11 15:39:16 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2022-11-29 18:01:27 +01:00
if ( dol_is_file ( $dolibarrdataroot . '/installmodules.lock' )) {
$allowimportsite = false ;
}
if ( ! $allowimportsite ) {
$error ++ ;
// Blocked by installmodules.lock
if ( getDolGlobalString ( 'MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US' )) {
// Show clean corporate message
$message = $langs -> trans ( 'InstallModuleFromWebHasBeenDisabledContactUs' );
} else {
// Show technical generic message
$message = $langs -> trans ( " InstallModuleFromWebHasBeenDisabledByFile " , $dolibarrdataroot . '/installmodules.lock' );
}
setEventMessages ( $message , null , 'errors' );
}
}
2022-02-21 22:50:32 +01:00
}
return $error ;
}