aboutsummaryrefslogtreecommitdiffhomepage
path: root/inc/poche
diff options
context:
space:
mode:
Diffstat (limited to 'inc/poche')
-rwxr-xr-xinc/poche/Database.class.php14
-rw-r--r--inc/poche/Language.class.php3
-rwxr-xr-xinc/poche/Poche.class.php96
-rwxr-xr-xinc/poche/Routing.class.php2
-rw-r--r--inc/poche/Template.class.php6
-rwxr-xr-xinc/poche/Tools.class.php22
-rw-r--r--inc/poche/WallabagEBooks.class.php8
-rwxr-xr-xinc/poche/config.inc.default.php8
-rw-r--r--inc/poche/pochePictures.php2
9 files changed, 86 insertions, 75 deletions
diff --git a/inc/poche/Database.class.php b/inc/poche/Database.class.php
index 2c80b64b..f6ba4708 100755
--- a/inc/poche/Database.class.php
+++ b/inc/poche/Database.class.php
@@ -23,12 +23,18 @@ class Database {
23 { 23 {
24 switch (STORAGE) { 24 switch (STORAGE) {
25 case 'sqlite': 25 case 'sqlite':
26 // Check if /db is writeable
27 if ( !is_writable(STORAGE_SQLITE) || !is_writable(dirname(STORAGE_SQLITE))) {
28 die('An error occured: "db" directory must be writeable for your web server user!');
29 }
26 $db_path = 'sqlite:' . STORAGE_SQLITE; 30 $db_path = 'sqlite:' . STORAGE_SQLITE;
27 $this->handle = new PDO($db_path); 31 $this->handle = new PDO($db_path);
28 break; 32 break;
29 case 'mysql': 33 case 'mysql':
30 $db_path = 'mysql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB; 34 $db_path = 'mysql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB . ';charset=utf8mb4';
31 $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD); 35 $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD, array(
36 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4',
37 ));
32 break; 38 break;
33 case 'postgres': 39 case 'postgres':
34 $db_path = 'pgsql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB; 40 $db_path = 'pgsql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB;
@@ -113,10 +119,10 @@ class Database {
113 $query = $this->executeQuery($sql, array()); 119 $query = $this->executeQuery($sql, array());
114 } 120 }
115 121
116 public function install($login, $password) 122 public function install($login, $password, $email = '')
117 { 123 {
118 $sql = 'INSERT INTO users ( username, password, name, email) VALUES (?, ?, ?, ?)'; 124 $sql = 'INSERT INTO users ( username, password, name, email) VALUES (?, ?, ?, ?)';
119 $params = array($login, $password, $login, ' '); 125 $params = array($login, $password, $login, $email);
120 $query = $this->executeQuery($sql, $params); 126 $query = $this->executeQuery($sql, $params);
121 127
122 $sequence = ''; 128 $sequence = '';
diff --git a/inc/poche/Language.class.php b/inc/poche/Language.class.php
index 8d3912f5..420f2fb9 100644
--- a/inc/poche/Language.class.php
+++ b/inc/poche/Language.class.php
@@ -18,6 +18,7 @@ class Language
18 'cs_CZ.utf8' => 'čeština', 18 'cs_CZ.utf8' => 'čeština',
19 'de_DE.utf8' => 'German', 19 'de_DE.utf8' => 'German',
20 'en_EN.utf8' => 'English', 20 'en_EN.utf8' => 'English',
21 'en_US.utf8' => 'English (US)',
21 'es_ES.utf8' => 'Español', 22 'es_ES.utf8' => 'Español',
22 'fa_IR.utf8' => 'فارسی', 23 'fa_IR.utf8' => 'فارسی',
23 'fr_FR.utf8' => 'Français', 24 'fr_FR.utf8' => 'Français',
@@ -110,4 +111,4 @@ class Language
110 Tools::emptyCache(); 111 Tools::emptyCache();
111 Tools::redirect('?view=config'); 112 Tools::redirect('?view=config');
112 } 113 }
113} \ No newline at end of file 114}
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php
index a49413f2..27d6f4a6 100755
--- a/inc/poche/Poche.class.php
+++ b/inc/poche/Poche.class.php
@@ -74,12 +74,13 @@ class Poche
74 /** 74 /**
75 * Creates a new user 75 * Creates a new user
76 */ 76 */
77 public function createNewUser($username, $password) 77 public function createNewUser($username, $password, $email = "")
78 { 78 {
79 if (!empty($username) && !empty($password)){ 79 if (!empty($username) && !empty($password)){
80 $newUsername = filter_var($username, FILTER_SANITIZE_STRING); 80 $newUsername = filter_var($username, FILTER_SANITIZE_STRING);
81 $email = filter_var($email, FILTER_SANITIZE_STRING);
81 if (!$this->store->userExists($newUsername)){ 82 if (!$this->store->userExists($newUsername)){
82 if ($this->store->install($newUsername, Tools::encodeString($password . $newUsername))) { 83 if ($this->store->install($newUsername, Tools::encodeString($password . $newUsername), $email)) {
83 Tools::logm('The new user ' . $newUsername . ' has been installed'); 84 Tools::logm('The new user ' . $newUsername . ' has been installed');
84 $this->messages->add('s', sprintf(_('The new user %s has been installed. Do you want to <a href="?logout">logout ?</a>'), $newUsername)); 85 $this->messages->add('s', sprintf(_('The new user %s has been installed. Do you want to <a href="?logout">logout ?</a>'), $newUsername));
85 Tools::redirect(); 86 Tools::redirect();
@@ -313,6 +314,8 @@ class Poche
313 314
314 switch ($view) 315 switch ($view)
315 { 316 {
317 case 'about':
318 break;
316 case 'config': 319 case 'config':
317 $dev_infos = $this->_getPocheVersion('dev'); 320 $dev_infos = $this->_getPocheVersion('dev');
318 $dev = trim($dev_infos[0]); 321 $dev = trim($dev_infos[0]);
@@ -387,7 +390,7 @@ class Poche
387 $this->pagination->page_links('?view=' . $view . '?search=' . $search . '&sort=' . $_SESSION['sort'] . '&' )); 390 $this->pagination->page_links('?view=' . $view . '?search=' . $search . '&sort=' . $_SESSION['sort'] . '&' ));
388 $tpl_vars['page_links'] = $page_links; 391 $tpl_vars['page_links'] = $page_links;
389 $tpl_vars['nb_results'] = $count; 392 $tpl_vars['nb_results'] = $count;
390 $tpl_vars['search_term'] = $search; 393 $tpl_vars['searchterm'] = $search;
391 } 394 }
392 break; 395 break;
393 case 'view': 396 case 'view':
@@ -524,6 +527,14 @@ class Poche
524 $longlastingsession = isset($_POST['longlastingsession']); 527 $longlastingsession = isset($_POST['longlastingsession']);
525 $passwordTest = ($isauthenticated) ? $user['password'] : Tools::encodeString($password . $login); 528 $passwordTest = ($isauthenticated) ? $user['password'] : Tools::encodeString($password . $login);
526 Session::login($user['username'], $user['password'], $login, $passwordTest, $longlastingsession, array('poche_user' => new User($user))); 529 Session::login($user['username'], $user['password'], $login, $passwordTest, $longlastingsession, array('poche_user' => new User($user)));
530
531 # reload l10n
532 $language = $user['config']['language'];
533 @putenv('LC_ALL=' . $language);
534 setlocale(LC_ALL, $language);
535 bindtextdomain($language, LOCALE);
536 textdomain($language);
537
527 $this->messages->add('s', _('welcome to your wallabag')); 538 $this->messages->add('s', _('welcome to your wallabag'));
528 Tools::logm('login successful'); 539 Tools::logm('login successful');
529 Tools::redirect($referer); 540 Tools::redirect($referer);
@@ -551,42 +562,39 @@ class Poche
551 * import datas into your wallabag 562 * import datas into your wallabag
552 * @return boolean 563 * @return boolean
553 */ 564 */
554 public function import()
555 {
556 if (isset($_FILES['file'])) {
557 Tools::logm('Import stated: parsing file');
558
559 // assume, that file is in json format
560
561 $str_data = file_get_contents($_FILES['file']['tmp_name']);
562 $data = json_decode($str_data, true);
563 if ($data === null) {
564
565 // not json - assume html
566
567 $html = new simple_html_dom();
568 $html->load_file($_FILES['file']['tmp_name']);
569 $data = array();
570 $read = 0;
571 foreach(array('ol','ul') as $list) {
572 foreach($html->find($list) as $ul) {
573 foreach($ul->find('li') as $li) {
574 $tmpEntry = array();
575 $a = $li->find('a');
576 $tmpEntry['url'] = $a[0]->href;
577 $tmpEntry['tags'] = $a[0]->tags;
578 $tmpEntry['is_read'] = $read;
579 if ($tmpEntry['url']) {
580 $data[] = $tmpEntry;
581 }
582 }
583
584 // the second <ol/ul> is for read links
585 565
586 $read = ((sizeof($data) && $read) ? 0 : 1); 566 public function import() {
587 } 567
588 } 568 if ( isset($_FILES['file']) && $_FILES['file']['tmp_name'] ) {
569 Tools::logm('Import stated: parsing file');
570
571 // assume, that file is in json format
572 $str_data = file_get_contents($_FILES['file']['tmp_name']);
573 $data = json_decode($str_data, true);
574
575 if ( $data === null ) {
576 //not json - assume html
577 $html = new simple_html_dom();
578 $html->load_file($_FILES['file']['tmp_name']);
579 $data = array();
580 $read = 0;
581 foreach (array('ol','ul') as $list) {
582 foreach ($html->find($list) as $ul) {
583 foreach ($ul->find('li') as $li) {
584 $tmpEntry = array();
585 $a = $li->find('a');
586 $tmpEntry['url'] = $a[0]->href;
587 $tmpEntry['tags'] = $a[0]->tags;
588 $tmpEntry['is_read'] = $read;
589 if ($tmpEntry['url']) {
590 $data[] = $tmpEntry;
591 }
592 }
593 # the second <ol/ul> is for read links
594 $read = ((sizeof($data) && $read)?0:1);
589 } 595 }
596 }
597 }
590 598
591 // for readability structure 599 // for readability structure
592 600
@@ -629,9 +637,11 @@ class Poche
629 $this->messages->add('s', _('Articles inserted: ') . $i . _('. Please note, that some may be marked as "read".')); 637 $this->messages->add('s', _('Articles inserted: ') . $i . _('. Please note, that some may be marked as "read".'));
630 } 638 }
631 639
632 Tools::logm('Import of articles finished: ' . $i . ' articles added (w/o content if not provided).'); 640 Tools::logm('Import of articles finished: '.$i.' articles added (w/o content if not provided).');
633 } 641 }
634 642 else {
643 $this->messages->add('s', _('Did you forget to select a file?'));
644 }
635 // file parsing finished here 645 // file parsing finished here
636 // now download article contents if any 646 // now download article contents if any
637 // check if we need to download any content 647 // check if we need to download any content
@@ -750,8 +760,8 @@ class Poche
750 die(sprintf(_('User with this id (%d) does not exist.'), $user_id)); 760 die(sprintf(_('User with this id (%d) does not exist.'), $user_id));
751 } 761 }
752 762
753 if (!in_array($type, $allowed_types) || $token != $config['token']) { 763 if (!in_array($type, $allowed_types) || !isset($config['token']) || $token != $config['token']) {
754 die(_('Uh, there is a problem while generating feeds.')); 764 die(_('Uh, there is a problem while generating feed. Wrong token used?'));
755 } 765 }
756 766
757 $feed = new FeedWriter(RSS2); 767 $feed = new FeedWriter(RSS2);
@@ -802,4 +812,4 @@ class Poche
802 } 812 }
803 813
804 814
805} 815} \ No newline at end of file
diff --git a/inc/poche/Routing.class.php b/inc/poche/Routing.class.php
index 44b0e168..5acd08ba 100755
--- a/inc/poche/Routing.class.php
+++ b/inc/poche/Routing.class.php
@@ -157,4 +157,4 @@ class Routing
157 { 157 {
158 echo $this->wallabag->tpl->render($file, $vars); 158 echo $this->wallabag->tpl->render($file, $vars);
159 } 159 }
160} \ No newline at end of file 160}
diff --git a/inc/poche/Template.class.php b/inc/poche/Template.class.php
index b686f2ec..4d0bfdbb 100644
--- a/inc/poche/Template.class.php
+++ b/inc/poche/Template.class.php
@@ -24,7 +24,7 @@ class Template extends Twig_Environment
24 24
25 $themeDirectory = (is_null($pocheUser) ? DEFAULT_THEME : $pocheUser->getConfigValue('theme')); 25 $themeDirectory = (is_null($pocheUser) ? DEFAULT_THEME : $pocheUser->getConfigValue('theme'));
26 26
27 if ($themeDirectory === false) { 27 if ($themeDirectory === false || !is_dir(THEME . '/' . $themeDirectory)) {
28 $themeDirectory = DEFAULT_THEME; 28 $themeDirectory = DEFAULT_THEME;
29 } 29 }
30 30
@@ -181,7 +181,7 @@ class Template extends Twig_Environment
181 while (($theme = readdir($handle)) !== false) { 181 while (($theme = readdir($handle)) !== false) {
182 # Themes are stored in a directory, so all directory names are themes 182 # Themes are stored in a directory, so all directory names are themes
183 # @todo move theme installation data to database 183 # @todo move theme installation data to database
184 if (!is_dir(THEME . '/' . $theme) || in_array($theme, array('.', '..'))) { 184 if (!is_dir(THEME . '/' . $theme) || in_array($theme, array('.', '..', '_global'))) {
185 continue; 185 continue;
186 } 186 }
187 187
@@ -232,4 +232,4 @@ class Template extends Twig_Environment
232 Tools::emptyCache(); 232 Tools::emptyCache();
233 Tools::redirect('?view=config'); 233 Tools::redirect('?view=config');
234 } 234 }
235} \ No newline at end of file 235}
diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php
index 63137d76..f803e3b5 100755
--- a/inc/poche/Tools.class.php
+++ b/inc/poche/Tools.class.php
@@ -51,9 +51,14 @@ final class Tools
51 51
52 $serverport = (!isset($_SERVER["SERVER_PORT"]) 52 $serverport = (!isset($_SERVER["SERVER_PORT"])
53 || $_SERVER["SERVER_PORT"] == '80' 53 || $_SERVER["SERVER_PORT"] == '80'
54 || $_SERVER["SERVER_PORT"] == HTTP_PORT
54 || ($https && $_SERVER["SERVER_PORT"] == '443') 55 || ($https && $_SERVER["SERVER_PORT"] == '443')
55 || ($https && $_SERVER["SERVER_PORT"]==SSL_PORT) //Custom HTTPS port detection 56 || ($https && $_SERVER["SERVER_PORT"]==SSL_PORT) //Custom HTTPS port detection
56 ? '' : ':' . $_SERVER["SERVER_PORT"]); 57 ? '' : ':' . $_SERVER["SERVER_PORT"]);
58
59 if (isset($_SERVER["HTTP_X_FORWARDED_PORT"])) {
60 $serverport = ':' . $_SERVER["HTTP_X_FORWARDED_PORT"];
61 }
57 62
58 $scriptname = str_replace('/index.php', '/', $_SERVER["SCRIPT_NAME"]); 63 $scriptname = str_replace('/index.php', '/', $_SERVER["SCRIPT_NAME"]);
59 64
@@ -112,7 +117,7 @@ final class Tools
112 { 117 {
113 $views = array( 118 $views = array(
114 'install', 'import', 'export', 'config', 'tags', 119 'install', 'import', 'export', 'config', 'tags',
115 'edit-tags', 'view', 'login', 'error' 120 'edit-tags', 'view', 'login', 'error', 'about'
116 ); 121 );
117 122
118 return (in_array($view, $views) ? $view . '.twig' : 'home.twig'); 123 return (in_array($view, $views) ? $view . '.twig' : 'home.twig');
@@ -295,21 +300,6 @@ final class Tools
295 } 300 }
296 301
297 /** 302 /**
298 * Download the sqlite database
299 */
300 public static function downloadDb()
301 {
302 header('Content-Disposition: attachment; filename="poche.sqlite.gz"');
303 self::_status(200);
304
305 header('Content-Transfer-Encoding: binary');
306 header('Content-Type: application/octet-stream');
307 echo gzencode(file_get_contents(STORAGE_SQLITE));
308
309 exit;
310 }
311
312 /**
313 * Get the content for a given URL (by a call to FullTextFeed) 303 * Get the content for a given URL (by a call to FullTextFeed)
314 * 304 *
315 * @param Url $url 305 * @param Url $url
diff --git a/inc/poche/WallabagEBooks.class.php b/inc/poche/WallabagEBooks.class.php
index 2ddece61..bc40990b 100644
--- a/inc/poche/WallabagEBooks.class.php
+++ b/inc/poche/WallabagEBooks.class.php
@@ -124,7 +124,7 @@ class WallabagEpub extends WallabagEBooks
124 124
125 $fullTitle = "<h1> " . $this->bookTitle . "</h1>\n"; 125 $fullTitle = "<h1> " . $this->bookTitle . "</h1>\n";
126 126
127 $book->setCoverImage("Cover.png", file_get_contents("themes/baggy/img/apple-touch-icon-152.png"), "image/png", $fullTitle); 127 $book->setCoverImage("Cover.png", file_get_contents("themes/_global/img/appicon/apple-touch-icon-152.png"), "image/png", $fullTitle);
128 128
129 $cover = $content_start . '<div style="text-align:center;"><p>' . _('Produced by wallabag with PHPePub') . '</p><p>'. _('Please open <a href="https://github.com/wallabag/wallabag/issues" >an issue</a> if you have trouble with the display of this E-Book on your device.') . '</p></div>' . $bookEnd; 129 $cover = $content_start . '<div style="text-align:center;"><p>' . _('Produced by wallabag with PHPePub') . '</p><p>'. _('Please open <a href="https://github.com/wallabag/wallabag/issues" >an issue</a> if you have trouble with the display of this E-Book on your device.') . '</p></div>' . $bookEnd;
130 130
@@ -182,7 +182,7 @@ class WallabagMobi extends WallabagEBooks
182 182
183 # introduction 183 # introduction
184 $content->appendParagraph('<div style="text-align:center;" ><p>' . _('Produced by wallabag with PHPMobi') . '</p><p>'. _('Please open <a href="https://github.com/wallabag/wallabag/issues" >an issue</a> if you have trouble with the display of this E-Book on your device.') . '</p></div>'); 184 $content->appendParagraph('<div style="text-align:center;" ><p>' . _('Produced by wallabag with PHPMobi') . '</p><p>'. _('Please open <a href="https://github.com/wallabag/wallabag/issues" >an issue</a> if you have trouble with the display of this E-Book on your device.') . '</p></div>');
185 $content->appendImage(imagecreatefrompng("themes/baggy/img/apple-touch-icon-152.png")); 185 $content->appendImage(imagecreatefrompng("themes/_global/img/appicon/apple-touch-icon-152.png"));
186 $content->appendPageBreak(); 186 $content->appendPageBreak();
187 187
188 Tools::logm('Adding actual content...'); 188 Tools::logm('Adding actual content...');
@@ -221,7 +221,7 @@ class WallabagPDF extends WallabagEbooks
221 $intro = '<h1>' . $this->bookTitle . '</h1><div style="text-align:center;" > 221 $intro = '<h1>' . $this->bookTitle . '</h1><div style="text-align:center;" >
222 <p>' . _('Produced by wallabag with tcpdf') . '</p> 222 <p>' . _('Produced by wallabag with tcpdf') . '</p>
223 <p>'. _('Please open <a href="https://github.com/wallabag/wallabag/issues" >an issue</a> if you have trouble with the display of this E-Book on your device.') . '</p> 223 <p>'. _('Please open <a href="https://github.com/wallabag/wallabag/issues" >an issue</a> if you have trouble with the display of this E-Book on your device.') . '</p>
224 <img src="themes/baggy/img/apple-touch-icon-152.png" /></div>'; 224 <img src="themes/_global/img/appicon/apple-touch-icon-152.png" /></div>';
225 225
226 226
227 $pdf->writeHTMLCell(0, 0, '', '', $intro, 0, 1, 0, true, '', true); 227 $pdf->writeHTMLCell(0, 0, '', '', $intro, 0, 1, 0, true, '', true);
@@ -243,4 +243,4 @@ class WallabagPDF extends WallabagEbooks
243 $pdf->Output($this->bookFileName . '.pdf', 'FD'); 243 $pdf->Output($this->bookFileName . '.pdf', 'FD');
244 244
245 } 245 }
246} \ No newline at end of file 246}
diff --git a/inc/poche/config.inc.default.php b/inc/poche/config.inc.default.php
index 6f03af18..3eaee3a3 100755
--- a/inc/poche/config.inc.default.php
+++ b/inc/poche/config.inc.default.php
@@ -24,6 +24,8 @@
24################################################################################# 24#################################################################################
25# Do not trespass unless you know what you are doing 25# Do not trespass unless you know what you are doing
26################################################################################# 26#################################################################################
27// Change this if http is running on nonstandard port - i.e is behind cache proxy
28@define ('HTTP_PORT', 80);
27 29
28// Change this if not using the standart port for SSL - i.e you server is behind sslh 30// Change this if not using the standart port for SSL - i.e you server is behind sslh
29@define ('SSL_PORT', 443); 31@define ('SSL_PORT', 443);
@@ -42,11 +44,14 @@
42@define ('SHARE_MAIL', TRUE); 44@define ('SHARE_MAIL', TRUE);
43@define ('SHARE_SHAARLI', FALSE); 45@define ('SHARE_SHAARLI', FALSE);
44@define ('SHAARLI_URL', 'http://myshaarliurl.com'); 46@define ('SHAARLI_URL', 'http://myshaarliurl.com');
47@define ('SHARE_DIASPORA', FALSE);
48@define ('DIASPORA_URL', 'http://diasporapod.com'); # Don't add a / at the end
45@define ('FLATTR', TRUE); 49@define ('FLATTR', TRUE);
46@define ('FLATTR_API', 'https://api.flattr.com/rest/v2/things/lookup/?url='); 50@define ('FLATTR_API', 'https://api.flattr.com/rest/v2/things/lookup/?url=');
47@define ('NOT_FLATTRABLE', '0'); 51@define ('NOT_FLATTRABLE', '0');
48@define ('FLATTRABLE', '1'); 52@define ('FLATTRABLE', '1');
49@define ('FLATTRED', '2'); 53@define ('FLATTRED', '2');
54@define ('CARROT', FALSE);
50// display or not print link in article view 55// display or not print link in article view
51@define ('SHOW_PRINTLINK', '1'); 56@define ('SHOW_PRINTLINK', '1');
52// display or not percent of read in article view. Affects only default theme. 57// display or not percent of read in article view. Affects only default theme.
@@ -59,10 +64,9 @@
59@define ('LOCALE', ROOT . '/locale'); 64@define ('LOCALE', ROOT . '/locale');
60@define ('CACHE', ROOT . '/cache'); 65@define ('CACHE', ROOT . '/cache');
61 66
62@define ('PAGINATION', '10'); 67@define ('PAGINATION', '12');
63 68
64//limit for download of articles during import 69//limit for download of articles during import
65@define ('IMPORT_LIMIT', 5); 70@define ('IMPORT_LIMIT', 5);
66//delay between downloads (in sec) 71//delay between downloads (in sec)
67@define ('IMPORT_DELAY', 5); 72@define ('IMPORT_DELAY', 5);
68
diff --git a/inc/poche/pochePictures.php b/inc/poche/pochePictures.php
index 7a914f90..52394c70 100644
--- a/inc/poche/pochePictures.php
+++ b/inc/poche/pochePictures.php
@@ -33,7 +33,7 @@ final class Picture
33 } 33 }
34 34
35 if (self::_downloadPictures($absolute_path, $fullpath) === true) { 35 if (self::_downloadPictures($absolute_path, $fullpath) === true) {
36 $content = str_replace($matches[$i][2], $fullpath, $content); 36 $content = str_replace($matches[$i][2], Tools::getPocheUrl() . $fullpath, $content);
37 } 37 }
38 38
39 $processing_pictures[] = $absolute_path; 39 $processing_pictures[] = $absolute_path;