diff --git a/Dockerfile b/Dockerfile index c21fd015..2a4302cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ WORKDIR /app RUN composer install COPY . /app/ -RUN echo '=== Installing ===' && mkdir -p data/config && echo " data/config/auto_install.conf.php && php index.php && \ +RUN echo '=== Installing ===' && mkdir -p data/config && echo " data/config/auto_install.conf.php && php index.php && \ echo '=== Smoke Test ===' && php index.php get-page /post/list && \ echo '=== Unit Tests ===' && ./vendor/bin/phpunit --configuration tests/phpunit.xml && \ echo '=== Coverage ===' && ./vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text && \ diff --git a/core/_install.php b/core/_install.php deleted file mode 100644 index b1574960..00000000 --- a/core/_install.php +++ /dev/null @@ -1,229 +0,0 @@ - - - - - Shimmie Installation - - - - - - -
-

Install Error

-
-

Shimmie needs to be run via a web server with PHP support -- you - appear to be either opening the file from your hard disk, or your - web server is mis-configured and doesn't know how to handle PHP files.

-

If you've installed a web server on your desktop PC, you probably - want to visit the local web server.

-

-
-
-
-
-		
-

Install Error

-

Warning: Composer vendor folder does not exist!

-
-

Shimmie is unable to find the composer vendor directory.
- Have you followed the composer setup instructions found in the README? - -

If you are not intending to do any development with Shimmie, it is highly recommend you use one of the pre-packaged releases found on Github instead.

-
-
-
-
-			

Shimmie Installer

-

{$e->title}

-
- {$e->body} -

-
- -EOD; - exit($e->code); - } -} - -function ask_questions() -{ - $warnings = []; - $errors = []; - - if (check_gd_version() == 0 && check_im_version() == 0) { - $errors[] = " - No thumbnailers could be found - install the imagemagick - tools (or the PHP-GD library, if imagemagick is unavailable). - "; - } elseif (check_im_version() == 0) { - $warnings[] = " - The 'convert' command (from the imagemagick package) - could not be found - PHP-GD can be used instead, but - the size of thumbnails will be limited. - "; - } - - if (!function_exists('mb_strlen')) { - $errors[] = " - The mbstring PHP extension is missing - multibyte languages - (eg non-english languages) may not work right. - "; - } - - $drivers = PDO::getAvailableDrivers(); - if ( - !in_array(DatabaseDriver::MYSQL, $drivers) && - !in_array(DatabaseDriver::PGSQL, $drivers) && - !in_array(DatabaseDriver::SQLITE, $drivers) - ) { - $errors[] = " - No database connection library could be found; shimmie needs - PDO with either Postgres, MySQL, or SQLite drivers - "; - } - - $db_m = in_array(DatabaseDriver::MYSQL, $drivers) ? '' : ""; - $db_p = in_array(DatabaseDriver::PGSQL, $drivers) ? '' : ""; - $db_s = in_array(DatabaseDriver::SQLITE, $drivers) ? '' : ""; - - $warn_msg = $warnings ? "

Warnings

".implode("\n

", $warnings) : ""; - $err_msg = $errors ? "

Errors

".implode("\n

", $errors) : ""; - - print << -

Shimmie Installer

- -
- $warn_msg - $err_msg - -

Database Install

-
-
- - - - - - - - - - - - - - - - - - - - - - -
Type:
Host:
Username:
Password:
DB Name:
-
- -
- -

Help

- -

- Please make sure the database you have chosen exists and is empty.
- The username provided must have access to create tables within the database. -

-

- For SQLite the database name will be a filename on disk, relative to - where shimmie was installed. -

-

- Drivers can generally be downloaded with your OS package manager; - for Debian / Ubuntu you want php-pgsql, php-mysql, or php-sqlite. -

-
- -EOD; -} -?> - - diff --git a/core/install.php b/core/install.php new file mode 100644 index 00000000..269f222d --- /dev/null +++ b/core/install.php @@ -0,0 +1,359 @@ +Shimmie is unable to find the composer vendor directory.

+

Have you followed the composer setup instructions found in the + README?

+

If you are not intending to do any development with Shimmie, + it is highly recommend you use one of the pre-packaged releases + found on Github instead.

+ "); + } + + // Pull in necessary files + require_once "vendor/autoload.php"; + global $_tracer; + $_tracer = new EventTracer(); + + require_once "core/exceptions.php"; + require_once "core/cacheengine.php"; + require_once "core/dbengine.php"; + require_once "core/database.php"; + require_once "core/util.php"; + + $dsn = get_dsn(); + if($dsn) { + do_install($dsn); + } else { + ask_questions(); + } + +} + +function get_dsn() { + if (file_exists("data/config/auto_install.conf.php")) { + $dsn = null; + require_once "data/config/auto_install.conf.php"; + } elseif (@$_POST["database_type"] == DatabaseDriver::SQLITE) { + $id = bin2hex(random_bytes(5)); + $dsn = "sqlite:data/shimmie.{$id}.sqlite"; + } elseif (isset($_POST['database_type']) && isset($_POST['database_host']) && isset($_POST['database_user']) && isset($_POST['database_name'])) { + $dsn = "{$_POST['database_type']}:user={$_POST['database_user']};password={$_POST['database_password']};host={$_POST['database_host']};dbname={$_POST['database_name']}"; + } else { + $dsn = null; + } + return $dsn; +} + +function do_install($dsn) { + try { + create_dirs(); + create_tables(new Database($dsn)); + write_config($dsn); + } catch (InstallerException $e) { + exit_with_page($e->title, $e->body, $e->code); + } + +} + +function ask_questions() +{ + $warnings = []; + $errors = []; + + if (check_gd_version() == 0 && check_im_version() == 0) { + $errors[] = " + No thumbnailers could be found - install the imagemagick + tools (or the PHP-GD library, if imagemagick is unavailable). + "; + } elseif (check_im_version() == 0) { + $warnings[] = " + The 'convert' command (from the imagemagick package) + could not be found - PHP-GD can be used instead, but + the size of thumbnails will be limited. + "; + } + + if (!function_exists('mb_strlen')) { + $errors[] = " + The mbstring PHP extension is missing - multibyte languages + (eg non-english languages) may not work right. + "; + } + + $drivers = PDO::getAvailableDrivers(); + if ( + !in_array(DatabaseDriver::MYSQL, $drivers) && + !in_array(DatabaseDriver::PGSQL, $drivers) && + !in_array(DatabaseDriver::SQLITE, $drivers) + ) { + $errors[] = " + No database connection library could be found; shimmie needs + PDO with either Postgres, MySQL, or SQLite drivers + "; + } + + $db_m = in_array(DatabaseDriver::MYSQL, $drivers) ? '' : ""; + $db_p = in_array(DatabaseDriver::PGSQL, $drivers) ? '' : ""; + $db_s = in_array(DatabaseDriver::SQLITE, $drivers) ? '' : ""; + + $warn_msg = $warnings ? "

Warnings

".implode("\n

", $warnings) : ""; + $err_msg = $errors ? "

Errors

".implode("\n

", $errors) : ""; + + exit_with_page( + "Install Options", +<<Database Install +

+
+ + + + + + + + + + + + + + + + + + + + + + +
Type:
Host:
Username:
Password:
DB Name:
+
+ +
+ +

Help

+

+ Please make sure the database you have chosen exists and is empty.
+ The username provided must have access to create tables within the database. +

+

+ For SQLite the database name will be a filename on disk, relative to + where shimmie was installed. +

+

+ Drivers can generally be downloaded with your OS package manager; + for Debian / Ubuntu you want php-pgsql, php-mysql, or php-sqlite. +

+EOD); +} + + +function create_dirs() +{ + $data_exists = file_exists("data") || mkdir("data"); + $data_writable = is_writable("data") || chmod("data", 0755); + + if (!$data_exists || !$data_writable) { + throw new InstallerException( + "Directory Permissions Error:", + "

Shimmie needs to have a 'data' folder in its directory, writable by the PHP user.

+

If you see this error, if probably means the folder is owned by you, and it needs to be writable by the web server.

+

PHP reports that it is currently running as user: ".$_ENV["USER"]." (". $_SERVER["USER"] .")

+

Once you have created this folder and / or changed the ownership of the shimmie folder, hit 'refresh' to continue.

", + 7 + ); + } +} + +function create_tables(Database $db) +{ + try { + if ($db->count_tables() > 0) { + throw new InstallerException( + "Warning: The Database schema is not empty!", + "

Please ensure that the database you are installing Shimmie with is empty before continuing.

+

Once you have emptied the database of any tables, please hit 'refresh' to continue.

", + 2 + ); + } + + $db->create_table("aliases", " + oldtag VARCHAR(128) NOT NULL, + newtag VARCHAR(128) NOT NULL, + PRIMARY KEY (oldtag) + "); + $db->execute("CREATE INDEX aliases_newtag_idx ON aliases(newtag)", []); + + $db->create_table("config", " + name VARCHAR(128) NOT NULL, + value TEXT, + PRIMARY KEY (name) + "); + $db->create_table("users", " + id SCORE_AIPK, + name VARCHAR(32) UNIQUE NOT NULL, + pass VARCHAR(250), + joindate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + class VARCHAR(32) NOT NULL DEFAULT 'user', + email VARCHAR(128) + "); + $db->execute("CREATE INDEX users_name_idx ON users(name)", []); + + $db->execute("INSERT INTO users(name, pass, joindate, class) VALUES(:name, :pass, now(), :class)", ["name" => 'Anonymous', "pass" => null, "class" => 'anonymous']); + $db->execute("INSERT INTO config(name, value) VALUES(:name, :value)", ["name" => 'anon_id', "value" => $db->get_last_insert_id('users_id_seq')]); + + if (check_im_version() > 0) { + $db->execute("INSERT INTO config(name, value) VALUES(:name, :value)", ["name" => 'thumb_engine', "value" => 'convert']); + } + + $db->create_table("images", " + id SCORE_AIPK, + owner_id INTEGER NOT NULL, + owner_ip SCORE_INET NOT NULL, + filename VARCHAR(64) NOT NULL, + filesize INTEGER NOT NULL, + hash CHAR(32) UNIQUE NOT NULL, + ext CHAR(4) NOT NULL, + source VARCHAR(255), + width INTEGER NOT NULL, + height INTEGER NOT NULL, + posted TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + locked SCORE_BOOL NOT NULL DEFAULT SCORE_BOOL_N, + FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT + "); + $db->execute("CREATE INDEX images_owner_id_idx ON images(owner_id)", []); + $db->execute("CREATE INDEX images_width_idx ON images(width)", []); + $db->execute("CREATE INDEX images_height_idx ON images(height)", []); + $db->execute("CREATE INDEX images_hash_idx ON images(hash)", []); + + $db->create_table("tags", " + id SCORE_AIPK, + tag VARCHAR(64) UNIQUE NOT NULL, + count INTEGER NOT NULL DEFAULT 0 + "); + $db->execute("CREATE INDEX tags_tag_idx ON tags(tag)", []); + + $db->create_table("image_tags", " + image_id INTEGER NOT NULL, + tag_id INTEGER NOT NULL, + UNIQUE(image_id, tag_id), + FOREIGN KEY (image_id) REFERENCES images(id) ON DELETE CASCADE, + FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE + "); + $db->execute("CREATE INDEX images_tags_image_id_idx ON image_tags(image_id)", []); + $db->execute("CREATE INDEX images_tags_tag_id_idx ON image_tags(tag_id)", []); + + $db->execute("INSERT INTO config(name, value) VALUES('db_version', 11)"); + $db->commit(); + } catch (PDOException $e) { + throw new InstallerException( + "PDO Error:", + "

An error occurred while trying to create the database tables necessary for Shimmie.

+

Please check and ensure that the database configuration options are all correct.

+

{$e->getMessage()}

", + 3 + ); + } +} + +function write_config($dsn) +{ + $file_content = "<" . "?php\ndefine('DATABASE_DSN', '$dsn');\n"; + + if (!file_exists("data/config")) { + mkdir("data/config", 0755, true); + } + + if (file_put_contents("data/config/shimmie.conf.php", $file_content, LOCK_EX)) { + header("Location: index.php"); + exit_with_page( + "Installation Successful", + "

If you aren't redirected, click here to Continue." + ); + } else { + $h_file_content = htmlentities($file_content); + throw new InstallerException( + "File Permissions Error:", + "The web server isn't allowed to write to the config file; please copy + the text below, save it as 'data/config/shimmie.conf.php', and upload it into the shimmie + folder manually. Make sure that when you save it, there is no whitespace + before the \"<?php\". + +

+ +

Once done, click here to Continue.", + 0 + ); + } +} + +function exit_with_page($title, $body, $code=0) { + print(" + + + Shimmie Installer + + + + +

+

Shimmie Installer

+

$title

+
+ $body +
+
+ +"); + exit($code); +} diff --git a/core/util.php b/core/util.php index 8201605b..17b6b3e2 100644 --- a/core/util.php +++ b/core/util.php @@ -471,9 +471,7 @@ function get_debug_info(): string function require_all(array $files): void { foreach ($files as $filename) { - if (basename($filename)[0] != "_") { - require_once $filename; - } + require_once $filename; } } @@ -630,155 +628,6 @@ function _get_query(): string } -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ -* Things used in the installer + unit tests * -\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -function create_dirs() -{ - $data_exists = file_exists("data") || mkdir("data"); - $data_writable = is_writable("data") || chmod("data", 0755); - - if (!$data_exists || !$data_writable) { - throw new InstallerException( - "Directory Permissions Error:", - "

Shimmie needs to have a 'data' folder in its directory, writable by the PHP user.

-

If you see this error, if probably means the folder is owned by you, and it needs to be writable by the web server.

-

PHP reports that it is currently running as user: ".$_ENV["USER"]." (". $_SERVER["USER"] .")

-

Once you have created this folder and / or changed the ownership of the shimmie folder, hit 'refresh' to continue.

", - 7 - ); - } -} - -function create_tables(Database $db) -{ - try { - if ($db->count_tables() > 0) { - throw new InstallerException( - "Warning: The Database schema is not empty!", - "

Please ensure that the database you are installing Shimmie with is empty before continuing.

-

Once you have emptied the database of any tables, please hit 'refresh' to continue.

", - 2 - ); - } - - $db->create_table("aliases", " - oldtag VARCHAR(128) NOT NULL, - newtag VARCHAR(128) NOT NULL, - PRIMARY KEY (oldtag) - "); - $db->execute("CREATE INDEX aliases_newtag_idx ON aliases(newtag)", []); - - $db->create_table("config", " - name VARCHAR(128) NOT NULL, - value TEXT, - PRIMARY KEY (name) - "); - $db->create_table("users", " - id SCORE_AIPK, - name VARCHAR(32) UNIQUE NOT NULL, - pass VARCHAR(250), - joindate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - class VARCHAR(32) NOT NULL DEFAULT 'user', - email VARCHAR(128) - "); - $db->execute("CREATE INDEX users_name_idx ON users(name)", []); - - $db->execute("INSERT INTO users(name, pass, joindate, class) VALUES(:name, :pass, now(), :class)", ["name" => 'Anonymous', "pass" => null, "class" => 'anonymous']); - $db->execute("INSERT INTO config(name, value) VALUES(:name, :value)", ["name" => 'anon_id', "value" => $db->get_last_insert_id('users_id_seq')]); - - if (check_im_version() > 0) { - $db->execute("INSERT INTO config(name, value) VALUES(:name, :value)", ["name" => 'thumb_engine', "value" => 'convert']); - } - - $db->create_table("images", " - id SCORE_AIPK, - owner_id INTEGER NOT NULL, - owner_ip SCORE_INET NOT NULL, - filename VARCHAR(64) NOT NULL, - filesize INTEGER NOT NULL, - hash CHAR(32) UNIQUE NOT NULL, - ext CHAR(4) NOT NULL, - source VARCHAR(255), - width INTEGER NOT NULL, - height INTEGER NOT NULL, - posted TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - locked SCORE_BOOL NOT NULL DEFAULT SCORE_BOOL_N, - FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT - "); - $db->execute("CREATE INDEX images_owner_id_idx ON images(owner_id)", []); - $db->execute("CREATE INDEX images_width_idx ON images(width)", []); - $db->execute("CREATE INDEX images_height_idx ON images(height)", []); - $db->execute("CREATE INDEX images_hash_idx ON images(hash)", []); - - $db->create_table("tags", " - id SCORE_AIPK, - tag VARCHAR(64) UNIQUE NOT NULL, - count INTEGER NOT NULL DEFAULT 0 - "); - $db->execute("CREATE INDEX tags_tag_idx ON tags(tag)", []); - - $db->create_table("image_tags", " - image_id INTEGER NOT NULL, - tag_id INTEGER NOT NULL, - UNIQUE(image_id, tag_id), - FOREIGN KEY (image_id) REFERENCES images(id) ON DELETE CASCADE, - FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE - "); - $db->execute("CREATE INDEX images_tags_image_id_idx ON image_tags(image_id)", []); - $db->execute("CREATE INDEX images_tags_tag_id_idx ON image_tags(tag_id)", []); - - $db->execute("INSERT INTO config(name, value) VALUES('db_version', 11)"); - $db->commit(); - } catch (PDOException $e) { - throw new InstallerException( - "PDO Error:", - "

An error occurred while trying to create the database tables necessary for Shimmie.

-

Please check and ensure that the database configuration options are all correct.

-

{$e->getMessage()}

", - 3 - ); - } -} - -function write_config() -{ - $file_content = "<" . "?php\ndefine('DATABASE_DSN', '".DATABASE_DSN."');\n"; - - if (!file_exists("data/config")) { - mkdir("data/config", 0755, true); - } - - if (file_put_contents("data/config/shimmie.conf.php", $file_content, LOCK_EX)) { - header("Location: index.php"); - print << -

Shimmie Installer

-

Things are OK \o/

-
-

If you aren't redirected, click here to Continue. -

- -EOD; - } else { - $h_file_content = htmlentities($file_content); - throw new InstallerException( - "File Permissions Error:", - "The web server isn't allowed to write to the config file; please copy - the text below, save it as 'data/config/shimmie.conf.php', and upload it into the shimmie - folder manually. Make sure that when you save it, there is no whitespace - before the \"<?php\" or after the \"?>\" - -

- -

Once done, click here to Continue.", - 0 - ); - } -} - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Code coverage * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ diff --git a/index.php b/index.php index 86666ee2..5a9e1750 100644 --- a/index.php +++ b/index.php @@ -48,7 +48,8 @@ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!file_exists("data/config/shimmie.conf.php")) { - require_once "core/_install.php"; + require_once "core/install.php"; + install(); exit; } @@ -99,17 +100,37 @@ require_once "core/util.php"; global $cache, $config, $database, $user, $page, $_tracer; _sanitise_environment(); $_tracer->begin("Bootstrap"); +$_tracer->begin("Load core"); _load_core_files(); +$_tracer->end(); +$_tracer->begin("Cache"); $cache = new Cache(CACHE_DSN); +$_tracer->end(); +$_tracer->begin("Database"); $database = new Database(DATABASE_DSN); +$_tracer->end(); +$_tracer->begin("DatabaseConfig"); $config = new DatabaseConfig($database); +$_tracer->end(); +$_tracer->begin("ExtensionInfo"); ExtensionInfo::load_all_extension_info(); +$_tracer->end(); +$_tracer->begin("Extension"); Extension::determine_enabled_extensions(); +$_tracer->end(); +$_tracer->begin("Load extension"); require_all(zglob("ext/{".Extension::get_enabled_extensions_as_string()."}/main.php")); +$_tracer->end(); +$_tracer->begin("Load theme"); _load_theme_files(); +$_tracer->end(); +$_tracer->begin("Page"); $page = new Page(); +$_tracer->end(); +$_tracer->begin("Load Event Listeners"); _load_event_listeners(); $_tracer->end(); +$_tracer->end(); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\