diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
new file mode 100644
index 00000000..84b6b9b7
--- /dev/null
+++ b/.github/workflows/ci.yaml
@@ -0,0 +1,12 @@
+name: Deploy localdev (PR)
+on:
+ pull_request:
+ workflow_dispatch:
+jobs:
+ deploy-localdev:
+ uses: LibriVox/librivox-ansible/.github/workflows/localdev.yaml@master
+ with:
+ catalog_git_refspec: ${{ github.ref }}
+ catalog_git_version: FETCH_HEAD
+ playbooks_repo: LibriVox/librivox-ansible
+ playbooks_repo_ref: master
diff --git a/.gitignore b/.gitignore
index b221217c..8e5d3bd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ application/config/email.php
application/logs/log-*
public_html/librivox-validator-books
public_html/uploads
+/vendor/
diff --git a/.gitreview b/.gitreview
deleted file mode 100644
index ba3adbe1..00000000
--- a/.gitreview
+++ /dev/null
@@ -1,4 +0,0 @@
-[gerrit]
-host=review.gerrithub.io
-port=29418
-project=LibriVox/librivox-catalog
diff --git a/application/controllers/catalog/Author.php b/application/controllers/catalog/Author.php
index 8ccf488b..1204bb4c 100644
--- a/application/controllers/catalog/Author.php
+++ b/application/controllers/catalog/Author.php
@@ -11,6 +11,10 @@ public function __construct()
public function index($author_id)
{
+ if (empty($author_id)) {
+ show_404();
+ }
+
$this->load->model('author_model');
$this->data['author'] = $this->author_model->get($author_id);
@@ -34,6 +38,10 @@ function get_results()
$author_id = $input['primary_key'];
$search_order = $input['search_order'];
+ if (empty($author_id)) {
+ show_error('A primary_key (author ID) must be supplied', 400);
+ }
+
//format offset
$offset = ($input['search_page'] - 1) * CATALOG_RESULT_COUNT;
diff --git a/application/controllers/catalog/Group.php b/application/controllers/catalog/Group.php
index 3a42086e..3d71694e 100644
--- a/application/controllers/catalog/Group.php
+++ b/application/controllers/catalog/Group.php
@@ -11,6 +11,10 @@ public function __construct()
public function index($group_id)
{
+ if (empty($group_id)) {
+ show_404();
+ }
+
$this->load->model('group_model');
$this->data['group'] = $this->group_model->get($group_id);
@@ -33,6 +37,10 @@ function get_results()
$input = $this->input->get(null, true);
$group_id = $input['primary_key'];
+ if (empty($group_id)) {
+ show_error('A primary_key (group ID) must be supplied', 400);
+ }
+
//format offset
$offset = ($input['search_page'] - 1) * CATALOG_RESULT_COUNT;
diff --git a/application/controllers/catalog/Page.php b/application/controllers/catalog/Page.php
index 1167f4be..74d22fc0 100644
--- a/application/controllers/catalog/Page.php
+++ b/application/controllers/catalog/Page.php
@@ -81,6 +81,9 @@ public function index($slug)
//$this->data['sections'] = $this->section_model->as_array()->get_many_by(array('project_id'=>$this->data['project']->id));
$this->data['sections'] = $this->section_model->get_full_sections_info($this->data['project']->id);
+ $this->load->helper('description_html_render');
+ $this->data['project']->description = _normalize_and_deduplicate_newlines_in_html($this->data['project']->description);
+
//var_dump($this->data['sections']);
if (!empty($this->data['sections']))
{
@@ -173,4 +176,4 @@ function _language($language_id)
$this->load->model('language_model');
return $this->language_model->get($language_id)->language;
}
-}
\ No newline at end of file
+}
diff --git a/application/controllers/catalog/Reader.php b/application/controllers/catalog/Reader.php
index 31e348cc..0508f0ca 100644
--- a/application/controllers/catalog/Reader.php
+++ b/application/controllers/catalog/Reader.php
@@ -11,6 +11,10 @@ public function __construct()
public function index($reader_id)
{
+ if (empty($reader_id)) {
+ show_404();
+ }
+
$this->load->model('user_model');
$this->data['reader'] = $this->user_model->as_array()->get($reader_id);
@@ -41,6 +45,10 @@ function get_results()
$reader_id = $input['primary_key'];
$search_order = $input['search_order'];
+ if (empty($reader_id)) {
+ show_error('A primary_key (reader ID) must be supplied', 400);
+ }
+
//format offset
$offset = ($input['search_page'] - 1) * CATALOG_RESULT_COUNT;
diff --git a/application/controllers/private/Iarchive_upload.php b/application/controllers/private/Iarchive_upload.php
index dfa46fd3..4fe98666 100644
--- a/application/controllers/private/Iarchive_upload.php
+++ b/application/controllers/private/Iarchive_upload.php
@@ -41,6 +41,7 @@ public function upload()
//additional params
$this->load->model('author_model');
$this->load->model('keyword_model');
+ $this->load->helper('description_html_render');
$params['creator'] = $this->author_model->create_author_list($project->id, 'author');
$params['date'] = date('Y-m-d');
@@ -48,7 +49,7 @@ public function upload()
$params['licenseurl'] = LICENSE_LINK;
$description = $this->_get_full_description($params, $project);
- $params['description'] = trim(preg_replace('/\s+/', ' ', $description)); //trims all newlines before placing in header
+ $params['description'] = _normalize_and_deduplicate_newlines_in_html($description); //Standardizes whitespace, replacing newlines with tags
$params['language'] = $this->data['language_code'];
// Close db connection before uploading to avoid hogging connections
diff --git a/application/controllers/private/Validator.php b/application/controllers/private/Validator.php
index fb771c77..d91e9f2f 100644
--- a/application/controllers/private/Validator.php
+++ b/application/controllers/private/Validator.php
@@ -56,7 +56,7 @@ public function index($project_id = 0)
if (empty($this->data['project'])) redirect(base_url() . 'private/validator/select_project');
$this->data['project']->full_title = create_full_title($this->data['project']);
- $this->data['project']->suggested_title = url_title(replace_accents($this->data['project']->full_title), '_', true);
+ $this->data['project']->suggested_title = substr(url_title(replace_accents($this->data['project']->full_title), '', true), 0, 39);
$this->data['project']->author_full_name = $this->_get_author_by_project($project_id);
$this->data['project']->author_last_name = $this->_get_author_by_project($project_id, 'last');
diff --git a/application/helpers/description_html_render_helper.php b/application/helpers/description_html_render_helper.php
new file mode 100644
index 00000000..41d00216
--- /dev/null
+++ b/application/helpers/description_html_render_helper.php
@@ -0,0 +1,35 @@
+ tags into project descriptions. Now, we want to
+ * render the newlines properly, so we need to try and dedupe a bit so that we
+ * don't have crazy amounts of whitespace.
+ *
+ * Inspired by this post: https://www.darklaunch.com/php-normalize-newlines-line-endings-crlf-cr-lf-unix-windows-mac.html
+ *
+ * $description string The description to render as HTML
+ */
+function _normalize_and_deduplicate_newlines_in_html($description) {
+ // Normalise everything to '\n' characters
+ $description = preg_replace(
+ array("/ \r?\n?/i", "/\r\n?/"),
+ "\n",
+ $description
+ );
+
+ // Replace suspiciously-long strings of newlines
+ $description = preg_replace(
+ "/\n{3,}/",
+ "\n\n",
+ $description,
+ );
+
+ // Turn the newlines into ' ' tags
+ // return nl2br($description);
+ return str_replace(
+ "\n",
+ " ",
+ $description,
+ );
+}
diff --git a/application/libraries/Librivox_search.php b/application/libraries/Librivox_search.php
index 6798cba7..84ba0ec5 100644
--- a/application/libraries/Librivox_search.php
+++ b/application/libraries/Librivox_search.php
@@ -322,14 +322,7 @@ private function _get_projects_by_author($author)
AND a.linked_to = 0 ';
$author_like = "%$author%";
$query = $this->db->query($sql, array($author_like, $author_like));
-
- // why the zero, you ask? makes sure our IN clause always has a value for valid sql
- $project_ids[0] = 0;
- foreach ($query->result() as $key => $value) {
- $project_ids[] = $value->project_id;
- }
-
- return $project_ids;
+ return $this->ids($query, 'project_id');
}
@@ -350,14 +343,7 @@ private function _get_projects_by_section_author($author)
AND a.linked_to = 0 ';
$author_like = "%$author%";
$query = $this->db->query($sql, array($author_like, $author_like));
-
- $project_ids[0] = 0;
- foreach ($query->result() as $key => $value) {
- $project_ids[] = $value->source_id;
- }
-
- return $project_ids;
-
+ return $this->ids($query, 'source_id');
}
@@ -376,13 +362,7 @@ private function _get_author_ids($author)
AND a.linked_to = 0 ';
$author_like = "%$author%";
$query = $this->db->query($sql, array($author_like, $author_like));
-
- $author_ids[0] = 0;
- foreach ($query->result() as $key => $value) {
- $author_ids[] = $value->id;
- }
-
- return $author_ids;
+ return $this->ids($query);
}
private function _get_reader_ids($reader, $exact_match)
@@ -393,14 +373,7 @@ private function _get_reader_ids($reader, $exact_match)
OR u.username LIKE ?';
$reader_like = $exact_match ? $reader : "%$reader%";
$query = $this->db->query($sql, array($reader_like, $reader_like));
-
- $reader_ids[0] = 0;
- foreach ($query->result() as $key => $value) {
- $reader_ids[] = $value->id;
- }
-
- return $reader_ids;
-
+ return $this->ids($query);
}
@@ -410,14 +383,7 @@ private function _get_projects_by_section_language($language_id)
FROM search_table st
WHERE section_language_id = ? ';
$query = $this->db->query($sql, array($language_id));
-
- $project_ids[0] = 0;
- foreach ($query->result() as $key => $value) {
- $project_ids[] = $value->source_id;
- }
-
- return $project_ids;
-
+ return $this->ids($query, 'source_id');
}
@@ -429,16 +395,21 @@ private function _get_projects_by_reader($reader, $exact_match)
OR pr.username LIKE ?';
$reader_like = $exact_match ? $reader : "%$reader%";
$query = $this->db->query($sql, array($reader_like, $reader_like));
+ return $this->ids($query, 'project_id');
+ }
- //echo $this->db->last_query();
- $project_ids[0] = 0;
- foreach ($query->result() as $key => $value) {
- $project_ids[] = $value->project_id;
+ private function ids($query, $id_column = 'id')
+ {
+ $ids = [];
+ foreach ($query->result('array') as $key => $value)
+ {
+ $ids[] = $value[$id_column];
}
-
- return $project_ids;
+ if (empty($ids))
+ {
+ $ids[] = 0; // To prevent SQL syntax errors of the form "WHERE id IN ()".
+ }
+ return $ids;
}
-
-
}
diff --git a/application/tests/.gitignore b/application/tests/.gitignore
new file mode 100644
index 00000000..9fd09829
--- /dev/null
+++ b/application/tests/.gitignore
@@ -0,0 +1,4 @@
+_ci_phpunit_test/tmp/
+.phpunit.cache
+.phpunit.result.cache
+build
diff --git a/application/tests/Bootstrap.php b/application/tests/Bootstrap.php
new file mode 100644
index 00000000..b13b9fc1
--- /dev/null
+++ b/application/tests/Bootstrap.php
@@ -0,0 +1,401 @@
+='))
+ {
+ error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
+ }
+ else
+ {
+ error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE);
+ }
+ break;
+
+ default:
+ header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
+ echo 'The application environment is not set correctly.';
+ exit(1); // EXIT_ERROR
+}
+
+/*
+ *---------------------------------------------------------------
+ * SYSTEM DIRECTORY NAME
+ *---------------------------------------------------------------
+ *
+ * This variable must contain the name of your "system" directory.
+ * Set the path if it is not in the same directory as this file.
+ */
+ $system_path = '../../system';
+
+/*
+ *---------------------------------------------------------------
+ * APPLICATION DIRECTORY NAME
+ *---------------------------------------------------------------
+ *
+ * If you want this front controller to use a different "application"
+ * directory than the default one you can set its name here. The directory
+ * can also be renamed or relocated anywhere on your server. If you do,
+ * use an absolute (full) server path.
+ * For more info please see the user guide:
+ *
+ * https://codeigniter.com/user_guide/general/managing_apps.html
+ *
+ * NO TRAILING SLASH!
+ */
+ $application_folder = '../../application';
+
+/*
+ *---------------------------------------------------------------
+ * VIEW DIRECTORY NAME
+ *---------------------------------------------------------------
+ *
+ * If you want to move the view directory out of the application
+ * directory, set the path to it here. The directory can be renamed
+ * and relocated anywhere on your server. If blank, it will default
+ * to the standard location inside your application directory.
+ * If you do move this, use an absolute (full) server path.
+ *
+ * NO TRAILING SLASH!
+ */
+ $view_folder = '';
+
+
+/*
+ * --------------------------------------------------------------------
+ * DEFAULT CONTROLLER
+ * --------------------------------------------------------------------
+ *
+ * Normally you will set your default controller in the routes.php file.
+ * You can, however, force a custom routing by hard-coding a
+ * specific controller class/function here. For most applications, you
+ * WILL NOT set your routing here, but it's an option for those
+ * special instances where you might want to override the standard
+ * routing in a specific front controller that shares a common CI installation.
+ *
+ * IMPORTANT: If you set the routing here, NO OTHER controller will be
+ * callable. In essence, this preference limits your application to ONE
+ * specific controller. Leave the function name blank if you need
+ * to call functions dynamically via the URI.
+ *
+ * Un-comment the $routing array below to use this feature
+ */
+ // The directory name, relative to the "controllers" directory. Leave blank
+ // if your controller is not in a sub-directory within the "controllers" one
+ // $routing['directory'] = '';
+
+ // The controller class file name. Example: mycontroller
+ // $routing['controller'] = '';
+
+ // The controller function you wish to be called.
+ // $routing['function'] = '';
+
+
+/*
+ * -------------------------------------------------------------------
+ * CUSTOM CONFIG VALUES
+ * -------------------------------------------------------------------
+ *
+ * The $assign_to_config array below will be passed dynamically to the
+ * config class when initialized. This allows you to set custom config
+ * items or override any default config values found in the config.php file.
+ * This can be handy as it permits you to share one application between
+ * multiple front controller files, with each file containing different
+ * config values.
+ *
+ * Un-comment the $assign_to_config array below to use this feature
+ */
+ // $assign_to_config['name_of_config_item'] = 'value of config item';
+
+
+
+// --------------------------------------------------------------------
+// END OF USER CONFIGURABLE SETTINGS. DO NOT EDIT BELOW THIS LINE
+// --------------------------------------------------------------------
+
+/*
+ * ---------------------------------------------------------------
+ * Resolve the system path for increased reliability
+ * ---------------------------------------------------------------
+ */
+
+ // Set the current directory correctly for CLI requests
+// if (defined('STDIN'))
+// {
+ // This is needed for @runInSeparateProcess
+ chdir(dirname(__FILE__));
+// }
+
+ if (($_temp = realpath($system_path)) !== FALSE)
+ {
+ $system_path = $_temp.DIRECTORY_SEPARATOR;
+ }
+ else
+ {
+ // Ensure there's a trailing slash
+ $system_path = strtr(
+ rtrim($system_path, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ ).DIRECTORY_SEPARATOR;
+ }
+
+ // Is the system path correct?
+ if ( ! is_dir($system_path))
+ {
+ header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
+ echo 'Your system folder path does not appear to be set correctly. Please open the following file and correct this: '.pathinfo(__FILE__, PATHINFO_BASENAME);
+ exit(3); // EXIT_CONFIG
+ }
+
+/*
+ * -------------------------------------------------------------------
+ * Now that we know the path, set the main path constants
+ * -------------------------------------------------------------------
+ */
+ // The name of THIS file
+ define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
+
+ // Path to the test directory containing all the test files.
+ define('TESTPATH', __dir__.DIRECTORY_SEPARATOR); // Should be the folder this `Bootstrap.php` file is in.
+
+ // Path to the system directory
+ define('BASEPATH', $system_path);
+
+ // Path to the front controller (this file) directory
+ define('FCPATH', realpath(dirname(__FILE__).'/../../public_html/').DIRECTORY_SEPARATOR);
+
+ // Name of the "system" directory
+ define('SYSDIR', basename(BASEPATH));
+
+ // The path to the "application" directory
+ if (is_dir($application_folder))
+ {
+ if (($_temp = realpath($application_folder)) !== FALSE)
+ {
+ $application_folder = $_temp;
+ }
+ else
+ {
+ $application_folder = strtr(
+ rtrim($application_folder, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ );
+ }
+ }
+ elseif (is_dir(BASEPATH.$application_folder.DIRECTORY_SEPARATOR))
+ {
+ $application_folder = BASEPATH.strtr(
+ trim($application_folder, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ );
+ }
+ else
+ {
+ header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
+ echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF;
+ exit(3); // EXIT_CONFIG
+ }
+
+ define('APPPATH', $application_folder.DIRECTORY_SEPARATOR);
+
+ // The path to the "views" directory
+ if ( ! isset($view_folder[0]) && is_dir(APPPATH.'views'.DIRECTORY_SEPARATOR))
+ {
+ $view_folder = APPPATH.'views';
+ }
+ elseif (is_dir($view_folder))
+ {
+ if (($_temp = realpath($view_folder)) !== FALSE)
+ {
+ $view_folder = $_temp;
+ }
+ else
+ {
+ $view_folder = strtr(
+ rtrim($view_folder, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ );
+ }
+ }
+ elseif (is_dir(APPPATH.$view_folder.DIRECTORY_SEPARATOR))
+ {
+ $view_folder = APPPATH.strtr(
+ trim($view_folder, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ );
+ }
+ else
+ {
+ header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
+ echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF;
+ exit(3); // EXIT_CONFIG
+ }
+
+ define('VIEWPATH', $view_folder.DIRECTORY_SEPARATOR);
+
+ // Path to the ci-phpunit-test directory
+ if (is_file(TESTPATH . '_ci_phpunit_test' . DIRECTORY_SEPARATOR . 'CIPHPUnitTest.php'))
+ {
+ define('CI_PHPUNIT_TESTPATH', TESTPATH . '_ci_phpunit_test' . DIRECTORY_SEPARATOR);
+ }
+ else
+ {
+ // Assume Composer with a vendor directory parallel to the application directory
+ define('CI_PHPUNIT_TESTPATH', implode(
+ DIRECTORY_SEPARATOR,
+ [dirname(APPPATH), 'vendor', 'kenjis', 'ci-phpunit-test', 'application', 'tests', '_ci_phpunit_test']
+ ).DIRECTORY_SEPARATOR);
+ }
+
+/*
+ * -------------------------------------------------------------------
+ * Enabling Monkey Patching
+ * -------------------------------------------------------------------
+ *
+ * If you want to use monkey patching, uncomment below code and configure
+ * for your application.
+ */
+/*
+require CI_PHPUNIT_TESTPATH . 'patcher/bootstrap.php';
+MonkeyPatchManager::init([
+ // If you want debug log, set `debug` true, and optionally you can set the log file path
+ 'debug' => true,
+ 'log_file' => '/tmp/monkey-patch-debug.log',
+ // PHP Parser: PREFER_PHP7, PREFER_PHP5, ONLY_PHP7, ONLY_PHP5
+ 'php_parser' => 'PREFER_PHP5',
+ 'cache_dir' => CI_PHPUNIT_TESTPATH . 'tmp/cache',
+ // Directories to patch source files
+ 'include_paths' => [
+ APPPATH,
+ BASEPATH,
+ CI_PHPUNIT_TESTPATH . 'replacing/',
+ ],
+ // Excluding directories to patch
+ // If you want to patch files inside paths below, you must add the directory starting with '-'
+ 'exclude_paths' => [
+ TESTPATH,
+ '-' . CI_PHPUNIT_TESTPATH . 'replacing/',
+ ],
+ // All patchers you use.
+ 'patcher_list' => [
+ 'ExitPatcher',
+ 'FunctionPatcher',
+ 'MethodPatcher',
+ 'ConstantPatcher',
+ ],
+ // Additional functions to patch
+ 'functions_to_patch' => [
+ //'random_string',
+ ],
+ 'exit_exception_classname' => 'CIPHPUnitTestExitException',
+]);
+*/
+
+/*
+ * -------------------------------------------------------------------
+ * Added for ci-phpunit-test
+ * -------------------------------------------------------------------
+ */
+
+// If you want to change the path of tests directory, set TESTPATH
+/*
+define('TESTPATH', APPPATH.'tests'.DIRECTORY_SEPARATOR);
+*/
+
+require CI_PHPUNIT_TESTPATH . '/CIPHPUnitTest.php';
+
+// CIPHPUnitTest::init();
+// Or you can set directories for autoloading
+
+CIPHPUnitTest::init([
+ // Directories for autoloading
+ APPPATH.'models',
+ APPPATH.'libraries',
+ APPPATH.'controllers',
+ APPPATH.'modules',
+ APPPATH.'hooks',
+ APPPATH.'helpers',
+ APPPATH.'core',
+]);
diff --git a/application/tests/DbTestCase.php b/application/tests/DbTestCase.php
new file mode 100644
index 00000000..62df8640
--- /dev/null
+++ b/application/tests/DbTestCase.php
@@ -0,0 +1,5 @@
+request('GET', 'author/0');
+ $this->assertResponseCode(404);
+ }
+
+ public function test_search_without_author_id_returns_400() {
+ $this->request(
+ 'GET',
+ 'author/get_results',
+ [
+ 'primary_key' => 0,
+ 'search_page' => 1,
+ 'search_order' => 'alpha',
+ 'project_type' => 'either',
+ ]
+ );
+ $this->assertResponseCode(400);
+ }
+}
+
+?>
diff --git a/application/tests/controllers/Welcome_test.php b/application/tests/controllers/Welcome_test.php
new file mode 100644
index 00000000..0257eb5a
--- /dev/null
+++ b/application/tests/controllers/Welcome_test.php
@@ -0,0 +1,29 @@
+
+ * @license MIT License
+ * @copyright 2015 Kenji Suzuki
+ * @link https://github.com/kenjis/ci-phpunit-test
+ */
+
+class Welcome_test extends TestCase
+{
+ public function test_method_404()
+ {
+ $this->request('GET', 'welcome/method_not_exist');
+ $this->assertResponseCode(404);
+ }
+
+ public function test_APPPATH()
+ {
+ $actual = realpath(APPPATH);
+ $expected = realpath(__DIR__ . '/../..');
+ $this->assertEquals(
+ $expected,
+ $actual,
+ 'Your APPPATH seems to be wrong. Check your $application_folder in tests/Bootstrap.php'
+ );
+ }
+}
diff --git a/application/tests/helpers/.gitkeep b/application/tests/helpers/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/application/tests/helpers/Description_html_render_helper_test.php b/application/tests/helpers/Description_html_render_helper_test.php
new file mode 100644
index 00000000..a849e544
--- /dev/null
+++ b/application/tests/helpers/Description_html_render_helper_test.php
@@ -0,0 +1,59 @@
+resetInstance();
+ $this->CI->load->helper('description_html_render_helper');
+ }
+
+ /**
+ * @dataProvider provider
+ */
+ public function test_newline_smushing_works($input, $expected) {
+ $actual = _normalize_and_deduplicate_newlines_in_html($input);
+ $this->assertEquals($expected, $actual);
+ }
+
+ public static function provider() {
+ return array(
+ // Simple case
+ array("a b", "a b"),
+
+ // Multiple newlines
+ array("a\nb", "a b"),
+ array("a\n\nb", "a b"),
+ array("a\n\n\nb", "a b"),
+
+ // Multiple carriage returns + newlines
+ array("a\r\nb", "a b"),
+ array("a\r\n\r\nb", "a b"),
+ array("a\r\n\r\n\r\nb", "a b"),
+
+ // Multiple tags
+ array("a b", "a b"),
+ array("a b", "a b"),
+ array("a b", "a b"),
+
+ // Multiple tags
+ array("a b", "a b"),
+ array("a b", "a b"),
+ array("a b", "a b"),
+ array("a b", "a b"),
+
+ // Mixed "newline" things
+ array("a \n b", "a b"),
+ array("a \r\n b", "a b"),
+ array("a \n\r\n b", "a b"),
+ array("a\n \r\n b", "a b"),
+ array("a\n\r\n b", "a b"),
+
+ // Case sensitivity, and deduplicating newlines following tags
+ array("a \r\n \r\nb", "a b"),
+ array("a \n \rb", "a b"),
+ );
+ }
+}
+
+?>
diff --git a/application/tests/hooks/.gitkeep b/application/tests/hooks/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/application/tests/libraries/.gitkeep b/application/tests/libraries/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/application/tests/mocks/autoloader.php b/application/tests/mocks/autoloader.php
new file mode 100644
index 00000000..f6b2cfd0
--- /dev/null
+++ b/application/tests/mocks/autoloader.php
@@ -0,0 +1,121 @@
+
+ * @license MIT License
+ * @copyright 2015 Kenji Suzuki
+ * @link https://github.com/kenjis/ci-phpunit-test
+ */
+
+class Mock_Libraries_Email
+{
+ private $data = [];
+
+ /**
+ * @var bool return value of send()
+ */
+ public $return_send = TRUE;
+
+ public function initialize()
+ {
+
+ }
+
+ public function from($from)
+ {
+ $this->data['from'] = $from;
+ }
+
+ public function to($to)
+ {
+ $this->data['to'] = $to;
+ }
+
+ public function bcc($bcc)
+ {
+ $this->data['bcc'] = $bcc;
+ }
+
+ public function subject($subject)
+ {
+ $this->data['subject'] = $subject;
+ }
+
+ public function message($message)
+ {
+ $this->data['message'] = $message;
+ }
+
+ public function send()
+ {
+ return $this->return_send;
+ }
+
+ public function _get_data()
+ {
+ return $this->data;
+ }
+}
diff --git a/application/tests/models/.gitkeep b/application/tests/models/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/application/tests/phpunit.xml b/application/tests/phpunit.xml
new file mode 100644
index 00000000..0e0773e1
--- /dev/null
+++ b/application/tests/phpunit.xml
@@ -0,0 +1,31 @@
+
+
+
+
+ ./
+ ./_ci_phpunit_test/
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ../controllers
+ ../models
+ ../views
+ ../libraries
+ ../helpers
+ ../hooks
+
+
+ ../views/errors
+
+
+
diff --git a/application/views/catalog/partials/advanced_search.php b/application/views/catalog/partials/advanced_search.php
index 65b2fdd7..499e674f 100644
--- a/application/views/catalog/partials/advanced_search.php
+++ b/application/views/catalog/partials/advanced_search.php
@@ -101,9 +101,13 @@
+
Still can't find what you're looking for? Try searching Internet Archive's LibriVox Audiobook Collection
+ by title, author, reader, key terms, or terms appearing in book descriptions.
+
+
-
\ No newline at end of file
+
diff --git a/application/views/catalog/partials/footer.php b/application/views/catalog/partials/footer.php
index 0be52d80..fceb7839 100644
--- a/application/views/catalog/partials/footer.php
+++ b/application/views/catalog/partials/footer.php
@@ -120,6 +120,7 @@ function get_search_page_from_url() {
if (current_page !== 'search')
{
window.location.href = CI_ROOT + 'search/' + search_category;
+ return;
}
e.preventDefault();
@@ -461,18 +462,3 @@ function librivox_search()
-
-
diff --git a/application/views/private/administer_projects/add_catalog_item.php b/application/views/private/administer_projects/add_catalog_item.php
index 3be3c6d3..7adacde2 100644
--- a/application/views/private/administer_projects/add_catalog_item.php
+++ b/application/views/private/administer_projects/add_catalog_item.php
@@ -173,16 +173,16 @@
= $grandchild['name'];?>
- endforeach; ?>
+
- endforeach; ?>
+
- endforeach; ?>
+
@@ -381,4 +381,4 @@
= $project_url_modal ?>
-= $project_readers_modal ?>
\ No newline at end of file
+= $project_readers_modal ?>
diff --git a/application/views/private/validator/archive_description.php b/application/views/private/validator/archive_description.php
index b9b01dc0..ec88a227 100644
--- a/application/views/private/validator/archive_description.php
+++ b/application/views/private/validator/archive_description.php
@@ -1,5 +1,5 @@
LibriVox recording of = $title ?> by = $authors ?>. = $translators ?>
-Read in = $language ?> by = $readers ?>
-= $description ?>
+Read in = $language ?> by = $readers ?>
+= $description ?>
For further information, including links to online text, reader information, RSS feeds, CD cover or other formats (if available), please go to the LibriVox catalog page for this recording.
For more free audio books or to become a volunteer reader, visit librivox.org .
\ No newline at end of file
diff --git a/application/views/public/project_launch/index.php b/application/views/public/project_launch/index.php
index 5cdc53de..eb8b5f66 100644
--- a/application/views/public/project_launch/index.php
+++ b/application/views/public/project_launch/index.php
@@ -192,16 +192,16 @@
= $grandchild['name'];?>
- endforeach; ?>
+
- endforeach; ?>
+
- endforeach; ?>
+
@@ -303,4 +303,4 @@
-
\ No newline at end of file
+
diff --git a/application/views/test/test_genres.php b/application/views/test/test_genres.php
index 69397e28..83404a71 100644
--- a/application/views/test/test_genres.php
+++ b/application/views/test/test_genres.php
@@ -119,10 +119,10 @@ function build_id_list(id)
= $child['name'];?>
- endforeach; ?>
+
- endforeach; ?>
+
diff --git a/composer.json b/composer.json
new file mode 100644
index 00000000..7421c4c5
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,6 @@
+{
+ "require-dev": {
+ "kenjis/ci-phpunit-test": "^3.0",
+ "phpunit/phpunit": "^10.5"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 00000000..6a3f9212
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1683 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "a5fdfa1a951a94a0cf179134fc918f71",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "kenjis/ci-phpunit-test",
+ "version": "v3.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kenjis/ci-phpunit-test.git",
+ "reference": "b4f53e137bc23d5c1bfa6429554825469dfe674c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kenjis/ci-phpunit-test/zipball/b4f53e137bc23d5c1bfa6429554825469dfe674c",
+ "reference": "b4f53e137bc23d5c1bfa6429554825469dfe674c",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.2",
+ "php": ">=7.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kenji Suzuki",
+ "homepage": "https://github.com/kenjis"
+ }
+ ],
+ "description": "An easier way to use PHPUnit with CodeIgniter 3.x",
+ "homepage": "http://kenjis.github.io/ci-phpunit-test/",
+ "keywords": [
+ "codeigniter",
+ "codeigniter3",
+ "monkey patch",
+ "phpunit",
+ "test",
+ "unit testing"
+ ],
+ "support": {
+ "forum": "http://forum.codeigniter.com/thread-61725.html",
+ "issues": "https://github.com/kenjis/ci-phpunit-test/issues",
+ "source": "https://github.com/kenjis/ci-phpunit-test/tree/v3.0.4"
+ },
+ "time": "2022-12-26T04:22:15+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.11.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/collections": "<1.6.8",
+ "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.6.8",
+ "doctrine/common": "^2.13.3 || ^3.2.2",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ],
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "support": {
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-08T13:26:56+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.18.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
+ "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
+ },
+ "time": "2023-12-10T21:03:43+00:00"
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
+ "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "ext-xmlwriter": "*",
+ "phar-io/version": "^3.0.1",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+ },
+ "time": "2021-07-20T11:28:43+00:00"
+ },
+ {
+ "name": "phar-io/version",
+ "version": "3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Library for handling version information and constraints",
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues",
+ "source": "https://github.com/phar-io/version/tree/3.2.1"
+ },
+ "time": "2022-02-21T01:04:05+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "10.1.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "78c3b7625965c2513ee96569a4dbb62601784145"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145",
+ "reference": "78c3b7625965c2513ee96569a4dbb62601784145",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xmlwriter": "*",
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=8.1",
+ "phpunit/php-file-iterator": "^4.0",
+ "phpunit/php-text-template": "^3.0",
+ "sebastian/code-unit-reverse-lookup": "^3.0",
+ "sebastian/complexity": "^3.0",
+ "sebastian/environment": "^6.0",
+ "sebastian/lines-of-code": "^2.0",
+ "sebastian/version": "^4.0",
+ "theseer/tokenizer": "^1.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.1"
+ },
+ "suggest": {
+ "ext-pcov": "PHP extension that provides line coverage",
+ "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "10.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.11"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-21T15:38:30+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "4.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c",
+ "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-08-31T06:24:48+00:00"
+ },
+ {
+ "name": "phpunit/php-invoker",
+ "version": "4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-invoker.git",
+ "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
+ "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "ext-pcntl": "*",
+ "phpunit/phpunit": "^10.0"
+ },
+ "suggest": {
+ "ext-pcntl": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Invoke callables with a timeout",
+ "homepage": "https://github.com/sebastianbergmann/php-invoker/",
+ "keywords": [
+ "process"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
+ "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:56:09+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "3.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748",
+ "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-08-31T14:07:24+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "6.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d",
+ "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "6.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:57:52+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "10.5.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50b8e314b6d0dd06521dc31d1abffa73f25f850c",
+ "reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.10.1",
+ "phar-io/manifest": "^2.0.3",
+ "phar-io/version": "^3.0.2",
+ "php": ">=8.1",
+ "phpunit/php-code-coverage": "^10.1.5",
+ "phpunit/php-file-iterator": "^4.0",
+ "phpunit/php-invoker": "^4.0",
+ "phpunit/php-text-template": "^3.0",
+ "phpunit/php-timer": "^6.0",
+ "sebastian/cli-parser": "^2.0",
+ "sebastian/code-unit": "^2.0",
+ "sebastian/comparator": "^5.0",
+ "sebastian/diff": "^5.0",
+ "sebastian/environment": "^6.0",
+ "sebastian/exporter": "^5.1",
+ "sebastian/global-state": "^6.0.1",
+ "sebastian/object-enumerator": "^5.0",
+ "sebastian/recursion-context": "^5.0",
+ "sebastian/type": "^4.0",
+ "sebastian/version": "^4.0"
+ },
+ "suggest": {
+ "ext-soap": "To be able to generate mocks based on WSDL files"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "10.5-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/Framework/Assert/Functions.php"
+ ],
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.10"
+ },
+ "funding": [
+ {
+ "url": "https://phpunit.de/sponsors.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-02-04T09:07:51+00:00"
+ },
+ {
+ "name": "sebastian/cli-parser",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae",
+ "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for parsing CLI options",
+ "homepage": "https://github.com/sebastianbergmann/cli-parser",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:58:15+00:00"
+ },
+ {
+ "name": "sebastian/code-unit",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit.git",
+ "reference": "a81fee9eef0b7a76af11d121767abc44c104e503"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503",
+ "reference": "a81fee9eef0b7a76af11d121767abc44c104e503",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Collection of value objects that represent the PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/code-unit",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:58:43+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
+ "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:59:15+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "5.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "2db5010a484d53ebf536087a70b4a5423c102372"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372",
+ "reference": "2db5010a484d53ebf536087a70b4a5423c102372",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-mbstring": "*",
+ "php": ">=8.1",
+ "sebastian/diff": "^5.0",
+ "sebastian/exporter": "^5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "security": "https://github.com/sebastianbergmann/comparator/security/policy",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-08-14T13:18:12+00:00"
+ },
+ {
+ "name": "sebastian/complexity",
+ "version": "3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "68ff824baeae169ec9f2137158ee529584553799"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799",
+ "reference": "68ff824baeae169ec9f2137158ee529584553799",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for calculating the complexity of PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/complexity",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/complexity/issues",
+ "security": "https://github.com/sebastianbergmann/complexity/security/policy",
+ "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-21T08:37:17+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "5.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f",
+ "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "security": "https://github.com/sebastianbergmann/diff/security/policy",
+ "source": "https://github.com/sebastianbergmann/diff/tree/5.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T10:55:06+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "6.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951",
+ "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "suggest": {
+ "ext-posix": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "6.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "https://github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "security": "https://github.com/sebastianbergmann/environment/security/policy",
+ "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-04-11T05:39:26+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "5.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc",
+ "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=8.1",
+ "sebastian/recursion-context": "^5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "https://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "security": "https://github.com/sebastianbergmann/exporter/security/policy",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-09-24T13:22:09+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "6.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4",
+ "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "sebastian/object-reflector": "^3.0",
+ "sebastian/recursion-context": "^5.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "6.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "security": "https://github.com/sebastianbergmann/global-state/security/policy",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-07-19T07:19:23+00:00"
+ },
+ {
+ "name": "sebastian/lines-of-code",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0",
+ "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for counting the lines of code in PHP source code",
+ "homepage": "https://github.com/sebastianbergmann/lines-of-code",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
+ "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-21T08:38:20+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "5.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906",
+ "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "sebastian/object-reflector": "^3.0",
+ "sebastian/recursion-context": "^5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T07:08:32+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "24ed13d98130f0e7122df55d06c5c4942a577957"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957",
+ "reference": "24ed13d98130f0e7122df55d06c5c4942a577957",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T07:06:18+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "5.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "05909fb5bc7df4c52992396d0116aed689f93712"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712",
+ "reference": "05909fb5bc7df4c52992396d0116aed689f93712",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "https://github.com/sebastianbergmann/recursion-context",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T07:05:40+00:00"
+ },
+ {
+ "name": "sebastian/type",
+ "version": "4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/type.git",
+ "reference": "462699a16464c3944eefc02ebdd77882bd3925bf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf",
+ "reference": "462699a16464c3944eefc02ebdd77882bd3925bf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Collection of value objects that represent the types of the PHP type system",
+ "homepage": "https://github.com/sebastianbergmann/type",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/type/issues",
+ "source": "https://github.com/sebastianbergmann/type/tree/4.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T07:10:45+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "4.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17",
+ "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "source": "https://github.com/sebastianbergmann/version/tree/4.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-07T11:34:05+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
+ "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2023-11-20T00:12:19+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.6.0"
+}
diff --git a/composer.phar b/composer.phar
new file mode 100755
index 00000000..bd5bab8c
Binary files /dev/null and b/composer.phar differ
diff --git a/public_html/js/private/section_compiler/index.js b/public_html/js/private/section_compiler/index.js
index 15c0e2c2..20446818 100644
--- a/public_html/js/private/section_compiler/index.js
+++ b/public_html/js/private/section_compiler/index.js
@@ -356,6 +356,14 @@ $(document).ready(function() {
$('.add_btn').show(300);
});
+ // Show the 'Assign reader sections' button by default, if the project status is 'open'
+ var project_status = $('#status').val();
+ if (project_status == 'open')
+ {
+ $('#assign_reader_toggle').hide();
+ $('#assign_reader_div').show();
+ }
+
});