diff --git a/.env.example b/.env.example index 3e24d20e1..6097d4a06 100644 --- a/.env.example +++ b/.env.example @@ -74,6 +74,8 @@ CLOUDFRONT_DISTRIBUTION= COULDFRONT_SDK_VERSION= COULDFRONT_REGION= +API_BASE_URL=https://api-dev.artic.edu +API_PUBLIC_URL=https://api-dev.artic.edu API_CACHE_ENABLED=true API_CACHE_TTL=60 API_CACHE_VERSION=1 diff --git a/.env.testing b/.env.testing index 5fe21af17..cddf16c7e 100644 --- a/.env.testing +++ b/.env.testing @@ -3,7 +3,7 @@ APP_ENV=testing APP_KEY=base64:nkScfqkJ+t4c4JMZOgO4hEK6gy0rOEF9f71FuL6AuzI= APP_DEBUG=true APP_LOG_LEVEL=debug -APP_URL=http://localhost +APP_URL=localhost DB_CONNECTION='pgsql' DB_HOST='127.0.0.1' @@ -11,3 +11,5 @@ DB_PORT=5432 DB_DATABASE='testing' DB_USERNAME='homestead' DB_PASSWORD='secret' + +SHOW_DEFAULT_RELATED_ITEMS=false diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml new file mode 100644 index 000000000..94175c72d --- /dev/null +++ b/.github/workflows/linting.yml @@ -0,0 +1,16 @@ +name: Linting +on: [push] +jobs: + lint: + runs-on: ubuntu-20.04 + steps: + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + - name: Checkout code + uses: actions/checkout@v3 + - name: Install PHP dependencies + run: composer install --no-interaction --no-progress --no-scripts + - name: Run PHP CodeSniffer + run: composer lint diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index de376f822..9e9e974f6 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -4,154 +4,61 @@ Contributions to artic.edu may include major feature development, bug fixing, writing documentation, editing, reviewing, idea generation, presentation, product management, and maintenance. We are grateful for every contribution. ## Art Institute of Chicago team -> Past and present - -### nikhil trivedi -Role: Director of Engineering -GitHub: [nikhiltri](https://github.com/nikhiltri) -Twitter: [@nikhiltri](https://twitter.com/nikhiltri) - -### Zach Garwood -Role: Web Developer -GitHub: [zachgarwood](https://github.com/zachgarwood) -GitLab: [zachgarwood](https://gitlab.com/zachgarwood) - -### Trevin Alonzo -Role: Web Developer -Github: [web-dev-trev](https://github.com/web-dev-trev) - -### Illya Moskvin -Role: Senior Web Developer -GitHub: [IllyaMoskvin](https://github.com/IllyaMoskvin) -Twitter: [@IllyaMoskvin](https://twitter.com/IllyaMoskvin) - -### Josh Andrews -Role: Product Owner -GitHub: [jbandrews](https://github.com/jbandrews) -Twitter: [@joshandrews](https://twitter.com/joshandrews) - -### Kirsten Southwell -Role: Creative Director, Visual Design -Twitter: [@kmsouthwell](https://twitter.com/kmsouthwell) - -### Michael Neault -Role: AVP & Executive Creative Director, Experience Design -Twitter: [@michael_neault](https://twitter.com/michael_neault) - -### Tina Shah -Role: Senior Web Developer -GitHub: [surreal8](https://github.com/surreal8) -Twitter: [@tshah](https://twitter.com/tshah) - -### Mike Bingaman -Role: Systems Administrator -GitHub: [bingaman](https://github.com/bingaman) -Twitter: [@bingaman](https://twitter.com/bingaman) - -### Mark Dascoli -Role: Integration Technologist -GitHub: [markdascoli](https://github.com/markdascoli) -Twitter: [@markdascoli](https://twitter.com/markdascoli) - +### Current staff + +| Name | Role | Contact | +|---|---|---| +| nikhil trivedi | Director of Engineering | GitHub: [nikhiltri](https://github.com/nikhiltri), Twitter: [@nikhiltri](https://twitter.com/nikhiltri) | +| Zach Garwood | Web Developer | GitHub: [zachgarwood](https://github.com/zachgarwood), GitLab: [zachgarwood](https://gitlab.com/zachgarwood) | +| Trevin Alonzo | Web Developer | Github: [web-dev-trev](https://github.com/web-dev-trev) | +| Josh Andrews | Product Owner | GitHub: [jbandrews](https://github.com/jbandrews), Twitter: [@joshandrews](https://twitter.com/joshandrews) | +| Michael Neault | AVP & Executive Creative Director, Experience Design | Twitter: [@michael_neault](https://twitter.com/michael_neault) | +| Mike Bingaman | Systems Administrator | GitHub: [bingaman](https://github.com/bingaman), Twitter: [@bingaman](https://twitter.com/bingaman) | +| Lauren Makholm | Assoc Director of Production and Manager of Digital Initiatives, Print & Digital Publishing | [LinkedIn](https://www.linkedin.com/in/lmakholm/) | + +### Former staff +| Name | Role | Contact | +|---|---|---| +| Illya Moskvin | Senior Web Developer | GitHub: [IllyaMoskvin](https://github.com/IllyaMoskvin), Twitter: [@IllyaMoskvin](https://twitter.com/IllyaMoskvin) | +| Tina Shah | Senior Web Developer | GitHub: [surreal8](https://github.com/surreal8), Twitter: [@tshah](https://twitter.com/tshah) | +| Kirsten Southwell | Creative Director, Visual Design | Twitter: [@kmsouthwell](https://twitter.com/kmsouthwell) | +| Marc Choi | Senior Designer, Visual Design | [LinkedIn](https://www.linkedin.com/in/marcchoi/) | +| Mark Dascoli | Integration Technologist | GitHub: [markdascoli](https://github.com/markdascoli), Twitter: [@markdascoli](https://twitter.com/markdascoli) | ## Initial development and interactive features by AREA 17 > [area17.com](http://www.area17.com/) -### Kemp Attwood -Role: Creative Director -Site: [area17.com/about/kemp-attwood](https://area17.com/about/kemp-attwood) -Twitter: [@attwoodkemp](https://twitter.com/attwoodkemp) - -### Jesse Golomb -Role: Producer -Site: [area17.com/about/jesse-golomb](https://area17.com/about/jesse-golomb) -Twitter: [@jessegolomb_](https://twitter.com/jessegolomb_) - -### Pat McQueen -Role: Strategy -Site: [area17.com/about/pat-mcqueen](https://area17.com/about/pat-mcqueen) - -### Skyler Swezy -Role: Strategy -Site: [area17.com/about/skyler-swezy](https://area17.com/about/skyler-swezy) -Twitter: [@skylerswezy](https://twitter.com/skylerswezy) - -### Christophe da Silva -Role: UX -Site: [area17.com/about/christophe-da-silva](https://area17.com/about/christophe-da-silva) -Twitter: [@kjuice](https://twitter.com/kjuice) - -### Marius Roosendaal -Role: Designer -Site: [area17.com/about/marius-roosendaal](https://area17.com/about/marius-roosendaal) -Twitter: [@mroosendaal](https://twitter.com/mroosendaal) - -### Iain Lawson -Role: Technical Lead -Site: [area17.com/about/iain-lawson](https://area17.com/about/iain-lawson) - -### Fernando Petrelli -Role: Back End Development -Site: [area17.com/about/fernando-petrelli](https://area17.com/about/fernando-petrelli) -GitHub: [ferpetrelli](https://github.com/ferpetrelli) -Twitter: [@ferpetrelli](https://twitter.com/ferpetrelli) - -### Quentin Renard -Role: Back End Development -Site: [area17.com/about/quentin-renard](https://area17.com/about/quentin-renard) -GitHub: [ifox](https://github.com/ifox) -Twitter: [@ifox](https://twitter.com/ifox) - -### Mike Byrne -Role: Front End Development -Site: [area17.com/about/mike-byrne](https://area17.com/about/mike-byrne) -GitHub: [13twelve](https://github.com/13twelve) -Twitter: [@13twelve](https://twitter.com/13twelve) - -### Mubashar Iqbal -Role: Back End Development -GitHub: [mubashariqbal](https://github.com/mubashariqbal) -Twitter: [@mubashariqbal](https://twitter.com/mubashariqbal) - -### Yanhao Li -Role: Back End Development -GitHub: [yanhao-li](https://github.com/yanhao-li) -Twitter: [@yanhao_li](https://twitter.com/yanhao_li) - -### Tim Brook -Role: Front End Development -GitHub: [mrtimbrook](https://github.com/mrtimbrook) -Twitter: [@tim_brook](https://twitter.com/tim_brook) - -### Pablo Barrios -Role: Back End Development -GitHub: [sauron](https://github.com/sauron) -Twitter: [@pablo_barrios](https://twitter.com/pablo_barrios) - -### Kyle Wayne Luck -Role: Back End Development -GitHub: [kylewayneluck](https://github.com/kylewayneluck) -Twitter: [@kylewayneluck](https://twitter.com/kylewayneluck) - -### Nicolas Davi -Role: Front End Development -GitHub: [nicolasdavi](https://github.com/nicolasdavi) -Twitter: [@nicolasdavi](https://twitter.com/nicolasdavi) - -### Powell May -Role: Back End Development -GitHub: [ptouch718](https://github.com/ptouch718) -Twitter: [@ptouch718](https://twitter.com/ptouch718) - -### Chris Hale -Role: Front End Development -GitHub: [chrishale](https://github.com/chrishale) -Twitter: [@chrishale](https://twitter.com/chrishale) - -### Luis Lavena -Role: Back End Development -GitHub: [luislavena](https://github.com/luislavena) -Twitter: [@luislavena](https://twitter.com/luislavena) +| Name | Role | Contact | +|---|---|---| +| Kemp Attwood | Creative Director | Site: [area17.com/about/kemp-attwood](https://area17.com/about/kemp-attwood), Twitter: [@attwoodkemp](https://twitter.com/attwoodkemp) | +| Jesse Golomb | Producer | Site: [area17.com/about/jesse-golomb](https://area17.com/about/jesse-golomb), Twitter: [@jessegolomb_](https://twitter.com/jessegolomb_) | +| Pat McQueen | Strategy | Site: [area17.com/about/pat-mcqueen](https://area17.com/about/pat-mcqueen) | +| Skyler Swezy | Strategy | Site: [area17.com/about/skyler-swezy](https://area17.com/about/skyler-swezy), Twitter: [@skylerswezy](https://twitter.com/skylerswezy) | +| Christophe da Silva | UX | Site: [area17.com/about/christophe-da-silva](https://area17.com/about/christophe-da-silva), Twitter: [@kjuice](https://twitter.com/kjuice) | +| Marius Roosendaal | Designer | Site: [area17.com/about/marius-roosendaal](https://area17.com/about/marius-roosendaal), Twitter: [@mroosendaal](https://twitter.com/mroosendaal) | +| Iain Lawson | Technical Lead | Site: [area17.com/about/iain-lawson](https://area17.com/about/iain-lawson) | +| Fernando Petrelli | Back End Development | Site: [area17.com/about/fernando-petrelli](https://area17.com/about/fernando-petrelli), GitHub: [ferpetrelli](https://github.com/ferpetrelli), Twitter: [@ferpetrelli](https://twitter.com/ferpetrelli) | +| Quentin Renard | Back End Development | Site: [area17.com/about/quentin-renard](https://area17.com/about/quentin-renard), GitHub: [ifox](https://github.com/ifox), Twitter: [@ifox](https://twitter.com/ifox) | +| Mike Byrne | Front End Development | Site: [area17.com/about/mike-byrne](https://area17.com/about/mike-byrne), GitHub: [13twelve](https://github.com/13twelve), Twitter: [@13twelve](https://twitter.com/13twelve) | +| Mubashar Iqbal | Back End Development | GitHub: [mubashariqbal](https://github.com/mubashariqbal), Twitter: [@mubashariqbal](https://twitter.com/mubashariqbal) | +| Yanhao Li | Back End Development | GitHub: [yanhao-li](https://github.com/yanhao-li), Twitter: [@yanhao_li](https://twitter.com/yanhao_li) | +| Tim Brook | Front End Development | GitHub: [mrtimbrook](https://github.com/mrtimbrook), Twitter: [@tim_brook](https://twitter.com/tim_brook) | +| Pablo Barrios | Back End Development | GitHub: [sauron](https://github.com/sauron), Twitter: [@pablo_barrios](https://twitter.com/pablo_barrios) | +| Kyle Wayne Luck | Back End Development | GitHub: [kylewayneluck](https://github.com/kylewayneluck), Twitter: [@kylewayneluck](https://twitter.com/kylewayneluck) | +| Nicolas Davi | Front End Development | GitHub: [nicolasdavi](https://github.com/nicolasdavi), Twitter: [@nicolasdavi](https://twitter.com/nicolasdavi) | +| Powell May | Back End Development | GitHub: [ptouch718](https://github.com/ptouch718), Twitter: [@ptouch718](https://twitter.com/ptouch718) | +| Chris Hale | Front End Development | GitHub: [chrishale](https://github.com/chrishale), Twitter: [@chrishale](https://twitter.com/chrishale) | +| Luis Lavena | Back End Development | GitHub: [luislavena](https://github.com/luislavena), Twitter: [@luislavena](https://twitter.com/luislavena) | + +## Layered Image Viewer initial development by Cogapp +> [cogapp.com](http://www.cogapp.com/) + +| Name | Role | Contact | +|---|---|---| +| Jon White | Senior Front-End Developer, he/him | Site: [cogapp.com/team/jon-white](https://www.cogapp.com/team/jon-white) | +| Tristin Roddis | Technical Director, he/him | Site: [cogapp.com/team/tristan-roddis](https://www.cogapp.com/team/tristan-roddis) | +| Hannah Baker | Developer | Site: [cogapp.com/team/hannah-baker](https://www.cogapp.com/team/hannah-baker) | +| Louise Cole | Production Director, she/her | Site: [cogapp.com/team/louise-cole](https://www.cogapp.com/team/louise-cole) | ## Site Built with [Twill](https://twill.io). diff --git a/README.md b/README.md index 5afc02ce2..16f5fd842 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,34 @@ git checkout -b feature/good-short-description # ... make some changes ``` +### Formatting your code + +We use the [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) +tool to ensure that all of our code is consistently formatted. Before checking +in any changes, we recommend running the `lint` script: +```bash +composer lint +``` + +Additional arguments can be passed to PHP CodeSniffer. For example, if you wanted +to view the full lint report instead of the default summary: +```bash +composer lint -- --report=full +``` + +Some linting errors can be automattically addressed by PHP CodeSniffer itself and +a second tool, +[PHP Coding Standard Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer). +If the lint script returns a list of errors, we recommend running the `format` +script: +```bash +composer format +``` + +These two tools are fairly comprehensive, but are not able to address every +linting error. You may need to manually make some formatting changes to your +code in order to pass the lint check. + ### Commiting your changes ```bash # Make sure you're working off of the latest commit on the branch diff --git a/VERSION b/VERSION index 17db1ec79..45ea4a2a9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.40 \ No newline at end of file +6.41 \ No newline at end of file diff --git a/app/Console/Commands/Events/EventExport.php b/app/Console/Commands/Events/EventExport.php index 060d3a7af..e2c166af0 100644 --- a/app/Console/Commands/Events/EventExport.php +++ b/app/Console/Commands/Events/EventExport.php @@ -3,10 +3,8 @@ namespace App\Console\Commands\Events; use App\Models\Event; - use League\Csv\Writer; use Illuminate\Support\Facades\Storage; - use Aic\Hub\Foundation\AbstractCommand as BaseCommand; class EventExport extends BaseCommand diff --git a/app/Console/Commands/Events/EventImport.php b/app/Console/Commands/Events/EventImport.php index f3d1cf964..45782a725 100644 --- a/app/Console/Commands/Events/EventImport.php +++ b/app/Console/Commands/Events/EventImport.php @@ -5,10 +5,8 @@ use App\Models\Event; use App\Models\ApiRelation; use App\Models\Api\TicketedEvent; - use League\Csv\Reader; use Illuminate\Support\Facades\Storage; - use Aic\Hub\Foundation\AbstractCommand as BaseCommand; class EventImport extends BaseCommand diff --git a/app/Console/Commands/FixGalleries.php b/app/Console/Commands/FixGalleries.php index 594e67331..840813eed 100644 --- a/app/Console/Commands/FixGalleries.php +++ b/app/Console/Commands/FixGalleries.php @@ -3,7 +3,6 @@ namespace App\Console\Commands; use App\Models\Vendor\Block; - use Illuminate\Console\Command; class FixGalleries extends Command diff --git a/app/Console/Commands/GeneratePdfs.php b/app/Console/Commands/GeneratePdfs.php index 1a1c165fc..1133c452e 100644 --- a/app/Console/Commands/GeneratePdfs.php +++ b/app/Console/Commands/GeneratePdfs.php @@ -12,7 +12,7 @@ class GeneratePdfs extends Command { - const STORAGE_PATH = '/pdf/static/'; + public const BUCKET_PATH = '/pdf/static/'; /** * The name and signature of the console command. @@ -64,37 +64,18 @@ public function handle() protected function generatePdf($model, $route = null) { - if (empty($route)) { - $route = self::route($model); - } - + $route = empty($route) ? self::route($model) : $route; if (empty($route)) { return false; } - - $path = null; - - if (get_class($model) == DigitalPublicationSection::class) { - $path = route($route, [ - 'pubId' => $model->digitalPublication->id, - 'pubSlug' => $model->digitalPublication->getSlug(), - 'id' => $model->id, - 'slug' => $model->getSlug(), - ], false); - } else { - $path = route($route, [ - 'id' => $model->id, - 'slug' => $model->getSlug(), - ], false); - } - $baseUrl = config('aic.protocol') . '://' . config('app.url'); - $fullUrl = $baseUrl . $path; + $fullUrl = $baseUrl . $this->path($model, $route); // Now, produce the PDF $prince = new Prince(config('aic.prince_command')); $prince->setBaseURL($baseUrl); $prince->setMedia('print'); + $prince->setFailMissingResources(true); if (config('app.debug') || config('aic.pdf_debug')) { $prince->setVerbose(true); @@ -103,36 +84,67 @@ protected function generatePdf($model, $route = null) set_time_limit(0); $html = Http::get($fullUrl, ['print' => true])->body(); - - $pdfFileName = self::pdfFileName($model); - $pdfPath = storage_path('app/' . $pdfFileName); - $prince->convertStringToFile($html, $pdfPath); - - if (config('aic.pdf_s3_enabled')) { - // Stream the file to S3; be sure to set `AWS_BUCKET` in `.env` and otherwise configure credentials - Storage::disk('pdf_s3')->putFileAs(self::STORAGE_PATH, new File($pdfPath), $pdfFileName, 'public'); + $fileName = self::fileName($model); + $class = class_basename($model); + if ($prince->convertStringToFile($html, self::localPath($fileName))) { + $this->storePdf($fileName); + } else { + throw new \Exception("Prince was unable to generate a PDF for {$class} with ID {$model->id}"); } - if ($model->pdf_download_path != self::pdfDownloadPath($pdfFileName)) { - $model->pdf_download_path = self::pdfDownloadPath($pdfFileName); + $model->pdf_download_path = self::downloadPath($fileName); + if ($model->isDirty('pdf_download_path')) { $model->save(); } - $class = class_basename($model); + $this->info("Generated PDF for {$class} with ID {$model->id}"); } - public static function pdfFileName(AbstractModel $model): string + protected function path($model, $route): string + { + return route($route, [ + 'pubId' => $model->digitalPublication->id, + 'pubSlug' => $model->digitalPublication->getSlug(), + 'id' => $model->id, + 'slug' => $model->getSlug(), + ], false); + } + + /** + * Stream the file to S3 then remove the local copy. Be sure to set + * `AWS_BUCKET` in `.env` and otherwise configure credentials. + */ + protected function storePdf($fileName): void + { + if (config('aic.pdf_s3_enabled')) { + $localPath = self::localPath($fileName); + Storage::disk('pdf_s3')->putFileAs( + self::BUCKET_PATH, + new File($localPath), + $fileName, + 'public' + ); + unlink($localPath); + } + } + + public static function fileName(AbstractModel $model): string { $route = self::route($model); return 'download-' . $route . '-' . $model->id . '.pdf'; } - public static function pdfDownloadPath($pdfFileName): string + public static function localPath($fileName): string + { + return storage_path('app/' . $fileName); + } + + public static function downloadPath($fileName): string { - return self::STORAGE_PATH . $pdfFileName; + return self::BUCKET_PATH . $fileName; } - public static function route($model): string + protected static function route($model): string { return array_search(get_class($model), self::$models); } diff --git a/app/Console/Commands/GenerateSitemap.php b/app/Console/Commands/GenerateSitemap.php index ea139b63f..bb91576e7 100644 --- a/app/Console/Commands/GenerateSitemap.php +++ b/app/Console/Commands/GenerateSitemap.php @@ -8,15 +8,11 @@ use App\Models\PrintedPublication; use App\Models\DigitalPublication; use App\Models\GenericPage; - use App\Repositories\GenericPageRepository; - use Spatie\Sitemap\Sitemap; use Spatie\Sitemap\Tags\Url; - use Symfony\Component\DomCrawler\Link; use Symfony\Component\DomCrawler\Crawler as DomCrawler; - use Illuminate\Console\Command; use Illuminate\Support\Str; @@ -84,7 +80,6 @@ private function addHardcodedPages(&$sitemap) $this->addRoute($sitemap, 'collection.publications.printed-publications', 0.6); $this->addRoute($sitemap, 'collection.publications.digital-publications', 0.6); $this->addRoute($sitemap, 'collection.research_resources'); - $this->addRoute($sitemap, 'collection.resources.research-guides'); $this->addRoute($sitemap, 'collection.resources.educator-resources'); } diff --git a/app/Console/Commands/MigrateExhibitions.php b/app/Console/Commands/MigrateExhibitions.php index 062d82bdb..74b7662ff 100644 --- a/app/Console/Commands/MigrateExhibitions.php +++ b/app/Console/Commands/MigrateExhibitions.php @@ -7,7 +7,6 @@ use App\Models\Api\Exhibition as ApiExhibition; use App\Repositories\ExhibitionRepository as AugmentedRepository; use App\Repositories\Api\ExhibitionRepository as ApiRepository; - use Illuminate\Console\Command; class MigrateExhibitions extends Command diff --git a/app/Console/Commands/MigrateOSCIPublicationOne.php b/app/Console/Commands/MigrateOSCIPublicationOne.php index ddde936a4..43bc225c8 100644 --- a/app/Console/Commands/MigrateOSCIPublicationOne.php +++ b/app/Console/Commands/MigrateOSCIPublicationOne.php @@ -53,7 +53,7 @@ public function handle() $webPub->is_dsc_stub = false; $webPub->save(); - foreach ($apiPub->sections as $apiSection){ + foreach ($apiPub->sections as $apiSection) { $webSection = new DigitalPublicationSection(); $webSection->title = $apiSection->title; $webSection->published = false; diff --git a/app/Console/Commands/ReportAltText.php b/app/Console/Commands/ReportAltText.php index c96c2f6c2..4d6fcfbbc 100644 --- a/app/Console/Commands/ReportAltText.php +++ b/app/Console/Commands/ReportAltText.php @@ -35,7 +35,6 @@ public function handle() \App\Models\Page::class, \App\Models\PressRelease::class, \App\Models\PrintedPublication::class, - \App\Models\ResearchGuide::class, \App\Models\Highlight::class, \App\Models\Video::class, \A17\Twill\Models\Block::class, @@ -100,7 +99,7 @@ public function handle() * @param array $data the array of data * @return string CSV text */ - private function str_putcsv($data) + private function str_putcsv($data) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { // Don't create a file, attempt to use memory instead $fh = fopen('php://temp', 'rw'); @@ -160,9 +159,11 @@ public function url($item) } // Alter slugs - if (\App\Models\Artist::class == get_class($item) + if ( + \App\Models\Artist::class == get_class($item) || \App\Models\Department::class == get_class($item) - || \App\Models\Exhibition::class == get_class($item)) { + || \App\Models\Exhibition::class == get_class($item) + ) { $slug = $item->datahub_id . '/' . $item->getApiModelFilled()->titleSlug; } @@ -230,8 +231,10 @@ public function url($item) } } - if (\A17\Twill\Models\Block::class == get_class($item) - || \App\Models\Lightbox::class == get_class($item)) { + if ( + \A17\Twill\Models\Block::class == get_class($item) + || \App\Models\Lightbox::class == get_class($item) + ) { return ''; } diff --git a/app/Console/Commands/UpdateCancelled.php b/app/Console/Commands/UpdateCancelled.php index 683d0a293..f1f8f5cd2 100644 --- a/app/Console/Commands/UpdateCancelled.php +++ b/app/Console/Commands/UpdateCancelled.php @@ -3,7 +3,6 @@ namespace App\Console\Commands; use App\Models\Event; - use Illuminate\Console\Command; class UpdateCancelled extends Command diff --git a/app/Console/Commands/UpdateCredits.php b/app/Console/Commands/UpdateCredits.php index 9f8ce986a..4c53ce615 100644 --- a/app/Console/Commands/UpdateCredits.php +++ b/app/Console/Commands/UpdateCredits.php @@ -3,7 +3,6 @@ namespace App\Console\Commands; use App\Models\Event; - use Illuminate\Console\Command; class UpdateCredits extends Command diff --git a/app/Console/Commands/UpdateEmailSeries.php b/app/Console/Commands/UpdateEmailSeries.php index fe9187d70..b3fc66e68 100644 --- a/app/Console/Commands/UpdateEmailSeries.php +++ b/app/Console/Commands/UpdateEmailSeries.php @@ -5,7 +5,6 @@ use App\Models\EmailSeries; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; - use Illuminate\Console\Command; class UpdateEmailSeries extends Command diff --git a/app/Console/Commands/UpdateSponsors.php b/app/Console/Commands/UpdateSponsors.php index 4e4354459..397fe983b 100644 --- a/app/Console/Commands/UpdateSponsors.php +++ b/app/Console/Commands/UpdateSponsors.php @@ -4,9 +4,7 @@ use App\Models\Exhibition; use App\Models\Sponsor; - use A17\Twill\Repositories\BlockRepository; - use Illuminate\Console\Command; class UpdateSponsors extends Command @@ -22,7 +20,6 @@ public function handle() // Remove all existing sponsors, including soft-deleted ones Sponsor::withTrashed()->where('id', '!=', 26)->get()->each(function ($sponsor) use ($blockRepository) { - // Delete all the blocks - deleting the sponsor doesn't cascade changes $blockRepository->bulkDelete($sponsor->blocks()->pluck('id')->toArray()); diff --git a/app/Events/UpdateArticle.php b/app/Events/UpdateArticle.php index bb21757fb..e27b14a51 100644 --- a/app/Events/UpdateArticle.php +++ b/app/Events/UpdateArticle.php @@ -8,7 +8,9 @@ class UpdateArticle { - use Dispatchable, InteractsWithSockets, SerializesModels; + use Dispatchable; + use InteractsWithSockets; + use SerializesModels; public $item; public $urls = []; diff --git a/app/Events/UpdateEvent.php b/app/Events/UpdateEvent.php index e72f83b95..0da482a9b 100644 --- a/app/Events/UpdateEvent.php +++ b/app/Events/UpdateEvent.php @@ -8,7 +8,9 @@ class UpdateEvent { - use Dispatchable, InteractsWithSockets, SerializesModels; + use Dispatchable; + use InteractsWithSockets; + use SerializesModels; public $item; public $urls = []; diff --git a/app/Events/UpdateExhibition.php b/app/Events/UpdateExhibition.php index a709e640c..37c2ff52c 100644 --- a/app/Events/UpdateExhibition.php +++ b/app/Events/UpdateExhibition.php @@ -8,7 +8,9 @@ class UpdateExhibition { - use Dispatchable, InteractsWithSockets, SerializesModels; + use Dispatchable; + use InteractsWithSockets; + use SerializesModels; public $item; public $urls = []; diff --git a/app/Events/UpdateHighlight.php b/app/Events/UpdateHighlight.php index 1e1447cd6..757a96590 100644 --- a/app/Events/UpdateHighlight.php +++ b/app/Events/UpdateHighlight.php @@ -8,7 +8,9 @@ class UpdateHighlight { - use Dispatchable, InteractsWithSockets, SerializesModels; + use Dispatchable; + use InteractsWithSockets; + use SerializesModels; public $item; public $urls = []; diff --git a/app/Events/UpdateHomeFeature.php b/app/Events/UpdateHomeFeature.php index b75ad3370..d34316a38 100644 --- a/app/Events/UpdateHomeFeature.php +++ b/app/Events/UpdateHomeFeature.php @@ -8,7 +8,9 @@ class UpdateHomeFeature { - use Dispatchable, InteractsWithSockets, SerializesModels; + use Dispatchable; + use InteractsWithSockets; + use SerializesModels; public $item; public $urls = []; diff --git a/app/Events/UpdatePage.php b/app/Events/UpdatePage.php index 19e2bd3a1..3f3bd0eab 100644 --- a/app/Events/UpdatePage.php +++ b/app/Events/UpdatePage.php @@ -8,7 +8,9 @@ class UpdatePage { - use Dispatchable, InteractsWithSockets, SerializesModels; + use Dispatchable; + use InteractsWithSockets; + use SerializesModels; public $item; public $urls = []; diff --git a/app/Helpers/BlockHelpers.php b/app/Helpers/BlockHelpers.php index f6e6ef3c6..0f153b4be 100644 --- a/app/Helpers/BlockHelpers.php +++ b/app/Helpers/BlockHelpers.php @@ -4,7 +4,6 @@ class BlockHelpers { - /** * Sorts a list of blocks by the order in which they are set in the config. */ diff --git a/app/Helpers/CollectionHelpers.php b/app/Helpers/CollectionHelpers.php index f5acba202..2da3ee8ba 100644 --- a/app/Helpers/CollectionHelpers.php +++ b/app/Helpers/CollectionHelpers.php @@ -4,7 +4,6 @@ class CollectionHelpers { - /** * Create a collection from the given value. * diff --git a/app/Helpers/FrontendHelpers.php b/app/Helpers/FrontendHelpers.php index e141f3d5e..eac76ea77 100644 --- a/app/Helpers/FrontendHelpers.php +++ b/app/Helpers/FrontendHelpers.php @@ -15,7 +15,6 @@ */ class FrontendHelpers { - /** * @param string $file * @return string diff --git a/app/Helpers/ImageHelpers.php b/app/Helpers/ImageHelpers.php index 064b3fbf8..c2587d83c 100644 --- a/app/Helpers/ImageHelpers.php +++ b/app/Helpers/ImageHelpers.php @@ -8,7 +8,6 @@ class ImageHelpers { - /** * Get the UUID of a media library asset * `uuid` represents the full S3 path, but we only want the UUID @@ -299,16 +298,15 @@ public static function aic_imageSettings($data) ]; } - return [ - 'srcset' => $stringSrcset, - 'src' => $originalSrc, - 'sizes' => $stringSizes, - 'width' => $stringWidth, - 'height' => $stringHeight, - 'lqip' => $lqip, - 'iiifId' => $iiifId, - ]; - + return [ + 'srcset' => $stringSrcset, + 'src' => $originalSrc, + 'sizes' => $stringSizes, + 'width' => $stringWidth, + 'height' => $stringHeight, + 'lqip' => $lqip, + 'iiifId' => $iiifId, + ]; } // Assign the sizes @@ -371,7 +369,7 @@ public static function aic_imageSettings($data) } if (empty($settings['crop'])) { - $settings['crop'] = 'faces,edges,entropy'; + $settings['crop'] = 'faces,center'; } } @@ -411,7 +409,7 @@ public static function aic_imageSettings($data) } if (empty($settings['crop'])) { - $imgixSettings['crop'] = 'faces,edges,entropy'; + $imgixSettings['crop'] = 'faces,center'; } else { $imgixSettings['crop'] = $settings['crop']; } @@ -436,13 +434,13 @@ public static function aic_imageSettings($data) if ($stringSrcset) { $stringSrcset .= ', '; } - $imgixSettings['w'] = $size; + $imgixSettings['w'] = $size; - if ($height && $height !== 'auto') { - $imgixSettings['h'] = round(($height / $width) * $size); - } - $imgixSettingsString = http_build_query($imgixSettings); - $stringSrcset .= $base . $imgixSettingsString . ' ' . $size . 'w'; + if ($height && $height !== 'auto') { + $imgixSettings['h'] = round(($height / $width) * $size); + } + $imgixSettingsString = http_build_query($imgixSettings); + $stringSrcset .= $base . $imgixSettingsString . ' ' . $size . 'w'; } // Get data-pin-media for pinterest @@ -470,7 +468,6 @@ public static function aic_imageSettings($data) } if ($sourceType === 'dams') { - // IIIF doesn't have many image processing features.. // http://iiif.io/api/image/2.1/#region // /{region}/{size}/{rotation}/{quality}.{format} @@ -529,7 +526,7 @@ public static function aic_imageSettings($data) if (!empty($stringSrcset)) { $stringSrcset .= ', '; } - $stringSrcset .= $base . '/' . $resizeVal . '/' . $size . ',/0/default.jpg ' . $size . 'w'; + $stringSrcset .= $base . '/' . $resizeVal . '/' . $size . ',/0/default.jpg ' . $size . 'w'; } // Get data-pin-media for pinterest @@ -620,7 +617,7 @@ public static function aic_imageSizes($data) $thisSize = round(($totalCSScolumns * (100 / ($totalCSScolumns + $outerGutterCSScolumns + $outerGutterCSScolumns))), 2) . 'vw'; } } - $sizes .= ($name === 'xlarge' ? '' : ', ') . $point . ' ' . $thisSize; + $sizes .= ($name === 'xlarge' ? '' : ', ') . $point . ' ' . $thisSize; } return $sizes; diff --git a/app/Helpers/NavHelpers.php b/app/Helpers/NavHelpers.php index dfc4a4c16..fbb534a49 100644 --- a/app/Helpers/NavHelpers.php +++ b/app/Helpers/NavHelpers.php @@ -21,18 +21,6 @@ public static function get_nav_for_publications(string $title) ], ]; - $journalPage = GenericPage::forSlug('journal')->published()->first(); - - if (isset($journalPage)) { - $journalPageUrl = $journalPage->url; - - array_push($subNav, [ - 'label' => $journalPage->present()->title, - 'href' => $journalPageUrl, - 'active' => request()->path() == ltrim($journalPageUrl, '/'), - ]); - } - $nav = [ ['label' => 'Collection', 'href' => route('collection'), 'links' => $subNav] ]; diff --git a/app/Helpers/StringHelpers.php b/app/Helpers/StringHelpers.php index abf13a8c5..173769463 100644 --- a/app/Helpers/StringHelpers.php +++ b/app/Helpers/StringHelpers.php @@ -4,7 +4,6 @@ class StringHelpers { - /** * Get Unicode slug * @see HasSlug::getUtf8Slug() @@ -249,11 +248,13 @@ public static function properTitleCase($string) public static function rightTrim($string, $needle) { if (is_string($string)) { - while (( - strlen($string) >= strlen($needle) - ) && ( - strpos($string, $needle, strlen($string) - strlen($needle)) !== false - )) { + while ( + ( + strlen($string) >= strlen($needle) + ) && ( + strpos($string, $needle, strlen($string) - strlen($needle)) !== false + ) + ) { $string = substr($string, 0, -strlen($needle)); } } diff --git a/app/Http/Controllers/API/EventOccurrencesController.php b/app/Http/Controllers/API/EventOccurrencesController.php index 6b572613a..ce5ce6aa6 100644 --- a/app/Http/Controllers/API/EventOccurrencesController.php +++ b/app/Http/Controllers/API/EventOccurrencesController.php @@ -3,9 +3,7 @@ namespace App\Http\Controllers\API; use App\Repositories\EventRepository; - use Carbon\Carbon; - use Illuminate\Http\Request; class EventOccurrencesController extends BaseController diff --git a/app/Http/Controllers/API/GeotargetController.php b/app/Http/Controllers/API/GeotargetController.php index 9836eeab5..52aedc141 100644 --- a/app/Http/Controllers/API/GeotargetController.php +++ b/app/Http/Controllers/API/GeotargetController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers\API; use Illuminate\Http\Request; - use Illuminate\Routing\Controller as BaseController; class GeotargetController extends BaseController diff --git a/app/Http/Controllers/API/IssueArticlesController.php b/app/Http/Controllers/API/IssueArticlesController.php deleted file mode 100644 index 537656a44..000000000 --- a/app/Http/Controllers/API/IssueArticlesController.php +++ /dev/null @@ -1,9 +0,0 @@ -getPages() )->map(function ($item) { - return new class($item) extends AbstractModel { + return new class ($item) extends AbstractModel { }; // For transform() })->each(function ($item) use ($collection) { $collection->push($item); diff --git a/app/Http/Controllers/Admin/BaseApiController.php b/app/Http/Controllers/Admin/BaseApiController.php index 493c0c4b8..d23d837c1 100644 --- a/app/Http/Controllers/Admin/BaseApiController.php +++ b/app/Http/Controllers/Admin/BaseApiController.php @@ -61,8 +61,7 @@ protected function getRepository() return parent::getRepository(); } - return $this->getApiRepository(); - + return $this->getApiRepository(); } protected function getBrowserTableData($items) diff --git a/app/Http/Controllers/Admin/DigitalPublicationSectionController.php b/app/Http/Controllers/Admin/DigitalPublicationSectionController.php index 4cef40c4d..4f386e10f 100644 --- a/app/Http/Controllers/Admin/DigitalPublicationSectionController.php +++ b/app/Http/Controllers/Admin/DigitalPublicationSectionController.php @@ -12,6 +12,7 @@ class DigitalPublicationSectionController extends ModuleController protected $moduleName = 'digitalPublications.sections'; protected $modelName = 'DigitalPublicationSection'; + protected $previewView = 'site.digitalPublicationSectionDetail'; protected $permalinkBase = 'digital-publications/'; diff --git a/app/Http/Controllers/Admin/ExhibitionController.php b/app/Http/Controllers/Admin/ExhibitionController.php index 0e9dcff3a..6ce34b068 100644 --- a/app/Http/Controllers/Admin/ExhibitionController.php +++ b/app/Http/Controllers/Admin/ExhibitionController.php @@ -5,7 +5,6 @@ use A17\Twill\Http\Controllers\Admin\ModuleController; use App\Repositories\Api\ExhibitionRepository; use App\Repositories\SiteTagRepository; - use Illuminate\Contracts\Foundation\Application; use Illuminate\Http\Request; diff --git a/app/Http/Controllers/Admin/ExperienceController.php b/app/Http/Controllers/Admin/ExperienceController.php index 68706274e..59f4e873a 100644 --- a/app/Http/Controllers/Admin/ExperienceController.php +++ b/app/Http/Controllers/Admin/ExperienceController.php @@ -60,18 +60,17 @@ protected function getItemColumnData($item, $column) 'thumbnail' => $item->presentAdmin()->{$column['presenter']}, ]; } - $variant = isset($column['variant']); - $crop = $variant ? $column['variant']['crop'] : head(array_keys(head($item->mediasParams))); - $params = $variant && isset($column['variant']['params']) - ? $column['variant']['params'] - : ['w' => 80, 'h' => 80, 'fit' => 'crop']; + $variant = isset($column['variant']); + $crop = $variant ? $column['variant']['crop'] : head(array_keys(head($item->mediasParams))); + $params = $variant && isset($column['variant']['params']) + ? $column['variant']['params'] + : ['w' => 80, 'h' => 80, 'fit' => 'crop']; - $thumbnail_image = $item->defaultCmsImage($params); - - return [ - 'thumbnail' => $thumbnail_image, - ]; + $thumbnail_image = $item->defaultCmsImage($params); + return [ + 'thumbnail' => $thumbnail_image, + ]; } if (isset($column['nested']) && $column['nested']) { diff --git a/app/Http/Controllers/Admin/IssueArticleController.php b/app/Http/Controllers/Admin/IssueArticleController.php deleted file mode 100644 index c08373667..000000000 --- a/app/Http/Controllers/Admin/IssueArticleController.php +++ /dev/null @@ -1,110 +0,0 @@ - true, - ]; - - protected function getParentModuleForeignKey() - { - return 'issue_id'; - } - - protected $indexColumns = [ - 'image' => [ - 'title' => 'Hero', - 'thumb' => true, - 'variant' => [ - 'role' => 'hero', - 'crop' => 'default', - ], - ], - 'title' => [ - 'title' => 'Title', - 'edit_link' => true, - 'sort' => true, - 'field' => 'title', - ], - 'date' => [ - 'title' => 'Date', - 'edit_link' => true, - 'sort' => true, - 'field' => 'date', - 'present' => true, - ], - 'issue_number' => [ - 'title' => 'Issue No.', - 'edit_link' => true, - 'sort' => true, - 'field' => 'issueNumber', - 'present' => true, - ], - ]; - - protected $defaultOrders = ['position' => 'asc']; - - protected function indexData($request) - { - $issue = app(IssueRepository::class)->getById(request('issue')); - - return [ - 'breadcrumb' => [ - [ - 'label' => 'Issues', - 'url' => moduleRoute('issues', 'collection', 'index'), - ], - [ - 'label' => $issue->title, - 'url' => moduleRoute('issues', 'collection', 'edit', [$issue->id]), - ], - [ - 'label' => 'Articles', - ], - - ], - ]; - } - - protected function formData($request) - { - $item = $this->repository->getById(request('article') ?? request('id')); - $baseUrl = '//' . config('app.url') . '/' . $this->permalinkBase . $item->id . '/'; - - $issue = app(IssueRepository::class)->getById(request('issue')); - - return [ - 'baseUrl' => $baseUrl, - 'breadcrumb' => [ - [ - 'label' => 'Issues', - 'url' => moduleRoute('issues', 'collection', 'index'), - ], - [ - 'label' => $issue->title, - 'url' => moduleRoute('issues', 'collection', 'edit', [$issue->id]), - ], - [ - 'label' => 'Articles', - 'url' => moduleRoute('issues.articles', 'collection', 'index', [$request->route('issue')]), - ], - [ - 'label' => $issue->title, - ], - ], - ]; - } -} diff --git a/app/Http/Controllers/Admin/IssueController.php b/app/Http/Controllers/Admin/IssueController.php deleted file mode 100644 index 8cdad4453..000000000 --- a/app/Http/Controllers/Admin/IssueController.php +++ /dev/null @@ -1,59 +0,0 @@ - [ - 'title' => 'Hero', - 'thumb' => true, - 'variant' => [ - 'role' => 'hero', - 'crop' => 'default', - ], - ], - 'title' => [ - 'title' => 'Title', - 'edit_link' => true, - 'sort' => true, - 'field' => 'title', - ], - 'date' => [ - 'title' => 'Date', - 'edit_link' => true, - 'sort' => true, - 'field' => 'date', - 'present' => true, - ], - 'issue_number' => [ - 'title' => 'Issue No.', - 'edit_link' => true, - 'sort' => true, - 'field' => 'issueNumber', - 'present' => true, - ], - 'articles' => [ - 'title' => 'Articles', - 'nested' => 'articles', - ] - ]; - - protected $defaultOrders = ['position' => 'asc']; - - protected function formData($request) - { - $item = $this->repository->getById(request('issue') ?? request('id')); - $baseUrl = '//' . config('app.url') . '/' . $this->permalinkBase . $item->issue_number . '/'; - - return [ - 'baseUrl' => $baseUrl, - ]; - } -} diff --git a/app/Http/Controllers/Admin/PageController.php b/app/Http/Controllers/Admin/PageController.php index fc71453b9..c7096f021 100644 --- a/app/Http/Controllers/Admin/PageController.php +++ b/app/Http/Controllers/Admin/PageController.php @@ -8,7 +8,7 @@ class PageController extends ModuleController { - const MISSING_CMS_PAGE_MESSAGE = "CMS home page doesn't exist, make sure to migrate the database and seed it first (php artisan migrate & php artisan db:seed)"; + public const MISSING_CMS_PAGE_MESSAGE = "CMS home page doesn't exist, make sure to migrate the database and seed it first (php artisan migrate & php artisan db:seed)"; protected $moduleName = 'pages'; @@ -69,6 +69,7 @@ public function art(PageRepository $pages) return view('admin.pages.form', $fields); } + // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps public function articles_publications(PageRepository $pages) { abort_unless($page = $pages->byName('Articles and Publications'), 500, self::MISSING_CMS_PAGE_MESSAGE); diff --git a/app/Http/Controllers/Admin/ResearchGuideController.php b/app/Http/Controllers/Admin/ResearchGuideController.php deleted file mode 100644 index 93e2ffaee..000000000 --- a/app/Http/Controllers/Admin/ResearchGuideController.php +++ /dev/null @@ -1,25 +0,0 @@ - $baseUrl, - ]; - } - - protected function previewData($item) - { - return $this->repository->getShowData($item); - } -} diff --git a/app/Http/Controllers/Admin/ResourceCategoryController.php b/app/Http/Controllers/Admin/ResourceCategoryController.php index 655821723..5861e4aac 100644 --- a/app/Http/Controllers/Admin/ResourceCategoryController.php +++ b/app/Http/Controllers/Admin/ResourceCategoryController.php @@ -12,6 +12,7 @@ class ResourceCategoryController extends ModuleController 'publish' => false, 'editInModal' => true, 'permalink' => false, + 'reorder' => true ]; protected $titleColumnKey = 'name'; diff --git a/app/Http/Controllers/ArticleController.php b/app/Http/Controllers/ArticleController.php index 0ef6d0c2e..161954cb2 100644 --- a/app/Http/Controllers/ArticleController.php +++ b/app/Http/Controllers/ArticleController.php @@ -10,7 +10,7 @@ class ArticleController extends FrontController { - const ARTICLES_PER_PAGE = 12; + public const ARTICLES_PER_PAGE = 12; protected $repository; public function __construct(ArticleRepository $repository) diff --git a/app/Http/Controllers/ArticlesPublicationsController.php b/app/Http/Controllers/ArticlesPublicationsController.php index 1e576e965..78d22ab50 100644 --- a/app/Http/Controllers/ArticlesPublicationsController.php +++ b/app/Http/Controllers/ArticlesPublicationsController.php @@ -42,8 +42,6 @@ public function index() ], 'featureHero' => $featureHero, 'features' => $articles, - 'journalFeatureHero' => $page->present()->getFeaturedJournalIssue(), - 'journalFeatures' => $page->present()->getFeaturedJournalArticles(), 'digitalPublications' => [ 'items' => $page->digitalPublications ], diff --git a/app/Http/Controllers/ArtistController.php b/app/Http/Controllers/ArtistController.php index 687d7887c..dca83fcd1 100644 --- a/app/Http/Controllers/ArtistController.php +++ b/app/Http/Controllers/ArtistController.php @@ -7,7 +7,7 @@ class ArtistController extends FrontController { - const ARTWORKS_PER_PAGE = 12; + public const ARTWORKS_PER_PAGE = 12; protected $repository; diff --git a/app/Http/Controllers/ArtworkController.php b/app/Http/Controllers/ArtworkController.php index 9ad611f4d..cf076d7eb 100644 --- a/app/Http/Controllers/ArtworkController.php +++ b/app/Http/Controllers/ArtworkController.php @@ -11,7 +11,7 @@ class ArtworkController extends BaseScopedController { - const PER_PAGE = 20; + public const PER_PAGE = 20; protected $artworkRepository; @@ -120,7 +120,7 @@ public function clearRecentlyViewed(RecentlyViewedService $service) return redirect()->back(); } - public function addRecentlyViewed($idSlug, $slug = null, RecentlyViewedService $service) + public function addRecentlyViewed(RecentlyViewedService $service, $idSlug, $slug = null) { $item = Artwork::query()->findOrFail((int) $idSlug); diff --git a/app/Http/Controllers/BaseScopedController.php b/app/Http/Controllers/BaseScopedController.php index 970eddd16..29dffdaee 100644 --- a/app/Http/Controllers/BaseScopedController.php +++ b/app/Http/Controllers/BaseScopedController.php @@ -24,7 +24,7 @@ class BaseScopedController extends FrontController /** * Default elements per page */ - const PER_PAGE = 20; + public const PER_PAGE = 20; /** * Define here the set of rules to apply scopes @@ -136,11 +136,10 @@ protected function hasAnyScope() return true; } - foreach ($this->scopes as $parameter => $scope) { - if (request()->input($parameter) != null) { - return true; - } + foreach ($this->scopes as $parameter => $scope) { + if (request()->input($parameter) != null) { + return true; } - + } } } diff --git a/app/Http/Controllers/CollectionController.php b/app/Http/Controllers/CollectionController.php index 38bf24269..0c848ac78 100644 --- a/app/Http/Controllers/CollectionController.php +++ b/app/Http/Controllers/CollectionController.php @@ -7,7 +7,7 @@ class CollectionController extends BaseScopedController { - const PER_PAGE = 50; + public const PER_PAGE = 50; protected $apiRepository; protected $searchRepository; @@ -39,11 +39,13 @@ protected function beginOfAssociationChain() public function index() { // WEB-1287: Redirect some common boolean filters - if (in_array(strtolower(request('q')), [ + if ( + in_array(strtolower(request('q')), [ 'cc0', 'public domain', 'creative commons', - ])) { + ]) + ) { return redirect(route('collection', ['is_public_domain' => 1])); } @@ -164,14 +166,13 @@ protected function setNofollowMeta() return true; } - if ($count == 1) { - // If there's only one selected filter, check if it has more than one active element - $input = request()->input(); + if ($count == 1) { + // If there's only one selected filter, check if it has more than one active element + $input = request()->input(); - if (count(explode(';', array_shift($input))) > 1) { - return true; - } + if (count(explode(';', array_shift($input))) > 1) { + return true; } - + } } } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 03e02a23e..6c453fe8e 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -9,5 +9,7 @@ class Controller extends BaseController { - use AuthorizesRequests, DispatchesJobs, ValidatesRequests; + use AuthorizesRequests; + use DispatchesJobs; + use ValidatesRequests; } diff --git a/app/Http/Controllers/DepartmentController.php b/app/Http/Controllers/DepartmentController.php index 3121b8603..4c31e755b 100644 --- a/app/Http/Controllers/DepartmentController.php +++ b/app/Http/Controllers/DepartmentController.php @@ -6,7 +6,7 @@ class DepartmentController extends FrontController { - const ARTWORKS_PER_PAGE = 24; + public const ARTWORKS_PER_PAGE = 24; protected $repository; diff --git a/app/Http/Controllers/DigitalPublicationsController.php b/app/Http/Controllers/DigitalPublicationsController.php index 84099b640..c6109fd2f 100644 --- a/app/Http/Controllers/DigitalPublicationsController.php +++ b/app/Http/Controllers/DigitalPublicationsController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; - use App\Models\DigitalPublication; use App\Repositories\DigitalPublicationRepository; use App\Helpers\NavHelpers; diff --git a/app/Http/Controllers/EducatorResourcesController.php b/app/Http/Controllers/EducatorResourcesController.php index 851a6f372..47bd3952f 100644 --- a/app/Http/Controllers/EducatorResourcesController.php +++ b/app/Http/Controllers/EducatorResourcesController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; - use App\Repositories\EducatorResourceRepository; use App\Models\ResourceCategory; @@ -33,7 +32,7 @@ protected function beginOfAssociationChain() public function index(Request $request) { - $items = $this->collection()->paginate(); + $items = $this->collection()->orderByDate()->paginate(); $title = 'Educator Resources'; diff --git a/app/Http/Controllers/EventsController.php b/app/Http/Controllers/EventsController.php index 91c34d967..afde95f51 100644 --- a/app/Http/Controllers/EventsController.php +++ b/app/Http/Controllers/EventsController.php @@ -14,7 +14,7 @@ class EventsController extends FrontController protected $repository; protected $moduleName = 'events'; - const PER_PAGE = 10; + public const PER_PAGE = 10; public function __construct(EventRepository $repository) { diff --git a/app/Http/Controllers/ExhibitionHistoryController.php b/app/Http/Controllers/ExhibitionHistoryController.php index cce617426..6f3f986e6 100644 --- a/app/Http/Controllers/ExhibitionHistoryController.php +++ b/app/Http/Controllers/ExhibitionHistoryController.php @@ -3,16 +3,14 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; - use App\Repositories\Api\ExhibitionRepository; use App\Libraries\Search\ExhibitionHistoryService; - use App\Models\Api\Exhibition; use App\Models\Page; class ExhibitionHistoryController extends FrontController { - const PER_PAGE = 20; + public const PER_PAGE = 20; protected $apiRepository; public function __construct(ExhibitionRepository $repository) diff --git a/app/Http/Controllers/ExhibitionPressRoomController.php b/app/Http/Controllers/ExhibitionPressRoomController.php index 08cf27ef2..550262617 100644 --- a/app/Http/Controllers/ExhibitionPressRoomController.php +++ b/app/Http/Controllers/ExhibitionPressRoomController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; - use App\Repositories\ExhibitionPressRoomRepository; use App\Models\ExhibitionPressRoom; @@ -20,6 +19,10 @@ public function __construct(ExhibitionPressRoomRepository $repository) public function index(Request $request) { + if ($auth = $this->authorize($request)) { + return $auth; + } + $items = ExhibitionPressRoom::published()->ordered()->paginate(); $title = 'Exhibition Press Room'; @@ -50,8 +53,12 @@ public function index(Request $request) return view('site.genericPage.index', $view_data); } - public function show($id) + public function show($id, Request $request) { + if ($auth = $this->authorize($request)) { + return $auth; + } + $item = $this->repository->getById((int) $id); $canonicalPath = route('about.exhibitionPressRooms.show', ['id' => $item->id, 'slug' => $item->getSlug()]); diff --git a/app/Http/Controllers/ExhibitionsController.php b/app/Http/Controllers/ExhibitionsController.php index 9e9aefaf2..ceaafbd4d 100644 --- a/app/Http/Controllers/ExhibitionsController.php +++ b/app/Http/Controllers/ExhibitionsController.php @@ -13,7 +13,7 @@ class ExhibitionsController extends FrontController protected $apiRepository; protected $eventRepository; - const RELATED_EVENTS_PER_PAGE = 3; + public const RELATED_EVENTS_PER_PAGE = 3; public function __construct(ExhibitionRepository $repository, EventRepository $eventRepository) { @@ -58,8 +58,7 @@ public function index($upcoming = false) if ($upcoming) { $featured = $page->apiModels('exhibitionsUpcoming', 'Exhibition'); $featured = $featured->filter($isUpcomingFilter); - } - else { + } else { $featured = $page->apiModels('exhibitionsExhibitions', 'Exhibition'); $featured = $featured->filter($isCurrentFilter); } diff --git a/app/Http/Controllers/Forms/EducatorAdmissionController.php b/app/Http/Controllers/Forms/EducatorAdmissionController.php index 4cb40ee5b..2dc96614c 100644 --- a/app/Http/Controllers/Forms/EducatorAdmissionController.php +++ b/app/Http/Controllers/Forms/EducatorAdmissionController.php @@ -3,11 +3,8 @@ namespace App\Http\Controllers\Forms; use Illuminate\Support\Facades\Mail; - use App\Http\Requests\Form\EducatorAdmissionRequest; - use App\Models\Form\EducatorAdmission; - use App\Mail\FormEducatorAdmission; class EducatorAdmissionController extends FormController diff --git a/app/Http/Controllers/Forms/EmailSubscriptionsController.php b/app/Http/Controllers/Forms/EmailSubscriptionsController.php index 650dbe1a9..875759f39 100644 --- a/app/Http/Controllers/Forms/EmailSubscriptionsController.php +++ b/app/Http/Controllers/Forms/EmailSubscriptionsController.php @@ -4,11 +4,8 @@ use Illuminate\Http\Request; use Illuminate\Support\Str; - use App\Http\Requests\Form\EmailSubscriptionsRequest; - use App\Libraries\ExactTargetService; - use App\Models\ExactTargetList; use App\Models\Form\EmailSubscriptions; diff --git a/app/Http/Controllers/Forms/FilmingAndPhotoShootProposalController.php b/app/Http/Controllers/Forms/FilmingAndPhotoShootProposalController.php index f72f741cf..06e6b61af 100644 --- a/app/Http/Controllers/Forms/FilmingAndPhotoShootProposalController.php +++ b/app/Http/Controllers/Forms/FilmingAndPhotoShootProposalController.php @@ -3,11 +3,8 @@ namespace App\Http\Controllers\Forms; use Illuminate\Support\Facades\Mail; - use App\Http\Requests\Form\FilmingProposalRequest; - use App\Models\Form\FilmingProposal; - use App\Mail\FormFilmingProposal; class FilmingAndPhotoShootProposalController extends FormController diff --git a/app/Http/Controllers/Forms/FormController.php b/app/Http/Controllers/Forms/FormController.php index 0d3fbb08b..287617835 100644 --- a/app/Http/Controllers/Forms/FormController.php +++ b/app/Http/Controllers/Forms/FormController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers\Forms; use Carbon\Carbon; - use App\Helpers\DateHelpers; use App\Http\Controllers\FrontController; diff --git a/app/Http/Controllers/Forms/RyersonClassVisitController.php b/app/Http/Controllers/Forms/RyersonClassVisitController.php index 88cb88478..a5427d576 100644 --- a/app/Http/Controllers/Forms/RyersonClassVisitController.php +++ b/app/Http/Controllers/Forms/RyersonClassVisitController.php @@ -3,11 +3,8 @@ namespace App\Http\Controllers\Forms; use Illuminate\Support\Facades\Mail; - use App\Http\Requests\Form\RyersonClassVisitRequest; - use App\Models\Form\RyersonClassVisit; - use App\Mail\FormRyersonClassVisit; class RyersonClassVisitController extends FormController diff --git a/app/Http/Controllers/FrontController.php b/app/Http/Controllers/FrontController.php index 601f128d2..bdef0276a 100644 --- a/app/Http/Controllers/FrontController.php +++ b/app/Http/Controllers/FrontController.php @@ -62,4 +62,27 @@ protected function getPageMetaData($item) ) ); } + public function authorize($request) + { + $configuredUsername = config('aic.http_username'); + $configuredPassword = config('aic.http_password'); + + if (empty($configuredUsername) || empty($configuredPassword)) { + return abort(500, 'Basic authentication not configured.'); + } + + $authenticationHasPassed = false; + $username = $request->header('PHP_AUTH_USER', null); + $password = $request->header('PHP_AUTH_PW', null); + + if ($username && $password) { + if ($username === $configuredUsername && $password === $configuredPassword) { + $authenticationHasPassed = true; + } + } + + if (!$authenticationHasPassed) { + return response()->make('Invalid credentials.', 401, ['WWW-Authenticate' => 'Basic']); + } + } } diff --git a/app/Http/Controllers/GalleryController.php b/app/Http/Controllers/GalleryController.php index bf5d77f2f..d1c4eaaf4 100644 --- a/app/Http/Controllers/GalleryController.php +++ b/app/Http/Controllers/GalleryController.php @@ -6,7 +6,7 @@ class GalleryController extends FrontController { - const ARTWORKS_PER_PAGE = 50; + public const ARTWORKS_PER_PAGE = 50; protected $repository; diff --git a/app/Http/Controllers/GenericPagesController.php b/app/Http/Controllers/GenericPagesController.php index 942fb0492..40bf80628 100644 --- a/app/Http/Controllers/GenericPagesController.php +++ b/app/Http/Controllers/GenericPagesController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Repositories\GenericPageRepository; +use Illuminate\Http\Request; class GenericPagesController extends FrontController { @@ -15,20 +16,20 @@ public function __construct(GenericPageRepository $genericPageRepository) parent::__construct(); } - public function show($slug) + public function show($slug, Request $request) { - $page = $this->getPage($slug); + if ($slug === 'press/art-institute-images') { + if ($auth = $this->authorize($request)) { + return $auth; + } + } + $page = $this->getPage($slug); // Redirect the user if "Redirect URL" is defined if ($page->redirect_url) { return redirect($page->redirect_url); } - // Add basic http protection if selected. - if ($page->http_protected) { - \Httpauth::secure(); - } - $crumbs = $page->present()->breadCrumb($page); $navigation = $page->present()->navigation(); diff --git a/app/Http/Controllers/Helpers/Seo.php b/app/Http/Controllers/Helpers/Seo.php index bf4e5c80e..d4044df7a 100644 --- a/app/Http/Controllers/Helpers/Seo.php +++ b/app/Http/Controllers/Helpers/Seo.php @@ -4,7 +4,6 @@ use A17\Twill\Http\Controllers\Front\Helpers\Seo as BaseSeo; use Illuminate\Support\Str; - use App\Helpers\ImageHelpers; class Seo extends BaseSeo diff --git a/app/Http/Controllers/HighlightsController.php b/app/Http/Controllers/HighlightsController.php index 7d813d5fe..adc1a70aa 100644 --- a/app/Http/Controllers/HighlightsController.php +++ b/app/Http/Controllers/HighlightsController.php @@ -7,7 +7,7 @@ class HighlightsController extends FrontController { - const HIGHLIGHTS_PER_PAGE = 12; + public const HIGHLIGHTS_PER_PAGE = 12; protected $repository; public function __construct(HighlightRepository $repository) diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index db33de432..253d90ffa 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -4,7 +4,6 @@ use App\Models\Page; use App\Models\Lightbox; - use Carbon\Carbon; class HomeController extends FrontController diff --git a/app/Http/Controllers/IssueArticleController.php b/app/Http/Controllers/IssueArticleController.php deleted file mode 100644 index 873cb0c63..000000000 --- a/app/Http/Controllers/IssueArticleController.php +++ /dev/null @@ -1,56 +0,0 @@ -repository = $repository; - - parent::__construct(); - } - - public function show($id, $slug = null) - { - $item = $this->repository->published()->findOrFail($id); - - $canonicalPath = $item->url; - - if ($canonicalRedirect = $this->getCanonicalRedirect($canonicalPath)) { - return $canonicalRedirect; - } - - $this->seo->setTitle($item->meta_title ?: $item->title); - $this->seo->setDescription($item->meta_description ?: ($item->list_description ?: $item->description)); - $this->seo->setImage($item->imageFront('hero')); - - $this->seo->citationTitle = $item->meta_title ?: $item->title; - $this->seo->citationJournalTitle = 'Art Institute Review'; - $this->seo->citationJournalAbbrev = 'AIR'; - $this->seo->citationPublisher = 'The Art Institute of Chicago'; - - foreach ($item->authors as $author) { - $this->seo->citationAuthor[] = $author->title; - } - - if (empty($this->seo->citationAuthor)) { - $this->seo->citationAuthor[] = $item->author_display; - } - $this->seo->citationPublicationDate = $item->date->toDateString(); - $this->seo->citationOnlineDate = $item->date->toDateString(); - $this->seo->citationIssue = $item->present()->issueNumber(); - - return view('site.issueArticleDetail', [ - 'item' => $item, - 'contrastHeader' => false, - 'borderlessHeader' => false, - 'unstickyHeader' => true, - 'canonicalUrl' => $canonicalPath, - ]); - } -} diff --git a/app/Http/Controllers/IssueController.php b/app/Http/Controllers/IssueController.php deleted file mode 100644 index afce3bb2a..000000000 --- a/app/Http/Controllers/IssueController.php +++ /dev/null @@ -1,63 +0,0 @@ -repository = $repository; - - parent::__construct(); - } - - public function latest() - { - if (request()->url() !== route('issues.latest')) { - return redirect()->route('issues.latest'); - } - - $issue = $this->repository->getLatestIssue(); - - if (!$issue) { - return redirect('/artinstitutereview/about'); - } - - return $this->show($issue->id, $issue->getSlug(), true); - } - - public function show($issueNumber, $slug = null, $isRequestForLatest = false) - { - $issues = $this->repository->published()->get(); - $item = $issues->where('issue_number', (int) $issueNumber)->first(); - - if (!$item) { - abort(404); - } - - $canonicalPath = route('issues.show', ['issueNumber' => $item->issue_number, 'slug' => $item->getSlug()]); - - if (!$isRequestForLatest) { - if ($canonicalRedirect = $this->getCanonicalRedirect($canonicalPath)) { - return $canonicalRedirect; - } - } - - $this->seo->setTitle($item->meta_title ?: $item->title); - $this->seo->setDescription($item->meta_description ?: $item->heading); // Issues have no blocks - $this->seo->setImage($item->imageFront('hero')); - - return view('site.issueDetail', [ - 'item' => $item, - 'contrastHeader' => false, - 'borderlessHeader' => false, - 'issues' => $issues, - 'welcomeNote' => $this->repository->getWelcomeNote($item), - 'canonicalUrl' => $canonicalPath, - ]); - } -} diff --git a/app/Http/Controllers/PreviewController.php b/app/Http/Controllers/PreviewController.php index 70c1cb4d1..638a6eb9a 100644 --- a/app/Http/Controllers/PreviewController.php +++ b/app/Http/Controllers/PreviewController.php @@ -4,7 +4,6 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; - use Illuminate\Routing\Controller as BaseController; class PreviewController extends BaseController diff --git a/app/Http/Controllers/PrintedPublicationsController.php b/app/Http/Controllers/PrintedPublicationsController.php index 94a49e689..1c5f433f4 100644 --- a/app/Http/Controllers/PrintedPublicationsController.php +++ b/app/Http/Controllers/PrintedPublicationsController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; - use App\Repositories\PrintedPublicationRepository; use App\Models\CatalogCategory; use App\Helpers\NavHelpers; diff --git a/app/Http/Controllers/ResearchGuidesController.php b/app/Http/Controllers/ResearchGuidesController.php deleted file mode 100644 index 0ebcd24b4..000000000 --- a/app/Http/Controllers/ResearchGuidesController.php +++ /dev/null @@ -1,86 +0,0 @@ -repository = $repository; - - parent::__construct(); - } - - public function index(Request $request) - { - $items = ResearchGuide::published()->paginate(); - $title = 'Research guides'; - $subNav = [ - ['label' => $title, 'href' => route('collection.resources.research-guides'), 'active' => true] - ]; - - $nav = [ - ['label' => 'Collection', 'href' => route('collection'), 'links' => $subNav] - ]; - - $crumbs = [ - ['label' => 'The Collection', 'href' => route('collection')], - ['label' => $title, 'href' => ''] - ]; - - $view_data = [ - 'title' => $title, - 'subNav' => $subNav, - 'nav' => $nav, - 'breadcrumb' => $crumbs, - 'wideBody' => true, - 'filters' => null, - 'listingCountText' => 'Showing ' . $items->total() . ' research guides', - 'listingItems' => $items, - ]; - - return view('site.genericPage.index', $view_data); - } - - public function show($id) - { - $page = $this->repository->find((int) $id); - - if (!$page) { - $page = $this->repository->forSlug($id); - - if (!$page) { - abort(404); - } - } - - $this->seo->setTitle($page->meta_title ?? $page->title); - $this->seo->setDescription($page->meta_description ?? $page->short_description ?? $page->listing_description); - $this->seo->setImage($page->imageFront('listing')); - - $crumbs = [ - ['label' => 'The Collection', 'href' => route('collection')], - ['label' => 'Research guides', 'href' => route('collection.resources.research-guides')], - ['label' => $page->title, 'href' => ''] - ]; - - return view('site.genericPage.show', [ - 'borderlessHeader' => !(empty($page->imageFront('banner'))), - 'subNav' => null, - 'intro' => $page->short_description, - 'headerImage' => $page->imageFront('banner'), - 'title' => $page->title, - 'breadcrumb' => $crumbs, - 'blocks' => null, - 'nav' => [], - 'page' => $page, - ]); - } -} diff --git a/app/Http/Controllers/RobotsController.php b/app/Http/Controllers/RobotsController.php new file mode 100644 index 000000000..7a5e260f1 --- /dev/null +++ b/app/Http/Controllers/RobotsController.php @@ -0,0 +1,19 @@ +getHttpHost()) { + return response() + ->view('site.robots') + ->header('Content-Type', 'text/plain'); + } + return response("User-agent: *\nDisallow: /", 200) + ->header('Content-Type', 'text/plain'); + } +} diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 481379d48..4c8d53084 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -4,48 +4,44 @@ use App\Models\Api\Artwork; use App\Models\Api\Search as GeneralSearch; - use App\Repositories\Api\ArtworkRepository; use App\Repositories\Api\ArtistRepository; use App\Repositories\Api\SearchRepository; use App\Repositories\Api\ExhibitionRepository; use App\Repositories\ArticleRepository; +use App\Repositories\EducatorResourceRepository; use App\Repositories\PublicationsRepository; use App\Repositories\EventRepository; use App\Repositories\GenericPageRepository; use App\Repositories\PressReleaseRepository; -use App\Repositories\ResearchGuideRepository; use App\Repositories\InteractiveFeatureRepository; use App\Repositories\HighlightRepository; - use App\Libraries\Search\CollectionService; - use App\Helpers\QueryHelpers; - use Illuminate\Support\Str; class SearchController extends BaseScopedController { - const ALL_PER_PAGE = 5; - const ALL_PER_PAGE_ARTWORKS = 8; - const ALL_PER_PAGE_EXHIBITIONS = 4; - const ALL_PER_PAGE_EVENTS = 4; - const ALL_PER_PAGE_PAGES = 3; - const ALL_PER_PAGE_ARTICLES = 4; - const ALL_PER_PAGE_PUBLICATIONS = 4; - const ALL_PER_PAGE_INTERACTIVEFEATURES = 4; - const ALL_PER_PAGE_HIGHLIGHTS = 4; - - const ARTWORKS_PER_PAGE = 20; - const PAGES_PER_PAGE = 20; - const EXHIBITIONS_PER_PAGE = 20; - const INTERACTIVEFEATURES_PER_PAGE = 20; - const HIGHLIGHTS_PER_PAGE = 20; - const ARTICLES_PER_PAGE = 20; - const EVENTS_PER_PAGE = 20; - const PUBLICATIONS_PER_PAGE = 20; - const ARTISTS_PER_PAGE = 30; - const AUTOCOMPLETE_PER_PAGE = 10; + public const ALL_PER_PAGE = 5; + public const ALL_PER_PAGE_ARTWORKS = 8; + public const ALL_PER_PAGE_EXHIBITIONS = 4; + public const ALL_PER_PAGE_EVENTS = 4; + public const ALL_PER_PAGE_PAGES = 3; + public const ALL_PER_PAGE_ARTICLES = 4; + public const ALL_PER_PAGE_PUBLICATIONS = 4; + public const ALL_PER_PAGE_INTERACTIVEFEATURES = 4; + public const ALL_PER_PAGE_HIGHLIGHTS = 4; + + public const ARTWORKS_PER_PAGE = 20; + public const PAGES_PER_PAGE = 20; + public const EXHIBITIONS_PER_PAGE = 20; + public const INTERACTIVEFEATURES_PER_PAGE = 20; + public const HIGHLIGHTS_PER_PAGE = 20; + public const ARTICLES_PER_PAGE = 20; + public const EVENTS_PER_PAGE = 20; + public const PUBLICATIONS_PER_PAGE = 20; + public const ARTISTS_PER_PAGE = 30; + public const AUTOCOMPLETE_PER_PAGE = 10; protected $artworksRepository; protected $artistsRepository; @@ -55,7 +51,7 @@ class SearchController extends BaseScopedController protected $eventsRepository; protected $publicationsRepository; protected $pagesRepository; - protected $researchGuideRepository; + protected $educatorResourceRepository; protected $pressRepository; protected $interactiveFeatureRepository; protected $highlightRepository; @@ -69,7 +65,7 @@ public function __construct( PublicationsRepository $publications, EventRepository $events, GenericPageRepository $pages, - ResearchGuideRepository $researchGuide, + EducatorResourceRepository $educatorResources, PressReleaseRepository $press, InteractiveFeatureRepository $interactiveFeature, HighlightRepository $highlight @@ -82,9 +78,9 @@ public function __construct( $this->eventsRepository = $events; $this->publicationsRepository = $publications; $this->pagesRepository = $pages; - $this->researchGuideRepository = $researchGuide; + $this->educatorResourceRepository = $educatorResources; $this->pressRepository = $press; - $this->interactiveFeatureRespository = $interactiveFeature; + $this->interactiveFeatureRepository = $interactiveFeature; $this->highlightRepository = $highlight; parent::__construct(); @@ -117,9 +113,9 @@ public function index() $exhibitions = $this->exhibitionsRepository->searchApi(request('q'), self::ALL_PER_PAGE_EXHIBITIONS); $events = $this->eventsRepository->searchApi(request('q'), self::ALL_PER_PAGE_EVENTS); $pages = $this->pagesRepository->searchApi(request('q'), self::ALL_PER_PAGE_PAGES); - $guides = $this->researchGuideRepository->searchApi(request('q'), self::ALL_PER_PAGE_EVENTS); + $educatorResources = $this->educatorResourceRepository->searchApi(request('q'), self::ALL_PER_PAGE_EVENTS); $press = $this->pressRepository->searchApi(request('q'), self::ALL_PER_PAGE_EVENTS); - $interactiveFeatures = $this->interactiveFeatureRespository->search(request('q'))->paginate(self::ALL_PER_PAGE_INTERACTIVEFEATURES); + $interactiveFeatures = $this->interactiveFeatureRepository->search(request('q'))->paginate(self::ALL_PER_PAGE_INTERACTIVEFEATURES); $highlights = $this->highlightRepository->searchApi(request('q'), self::ALL_PER_PAGE_HIGHLIGHTS); return view('site.search.index', [ @@ -134,7 +130,7 @@ public function index() 'highlights' => $highlights, 'publications' => $publications, 'pressReleases' => $press, - 'researchGuides' => $guides, + 'educatorResources' => $educatorResources, 'allResultsView' => false, 'searchResultsTypeLinks' => $links ]); @@ -193,7 +189,7 @@ public function autocomplete() $item->section = 'Highlights'; break; - } + } $item->text = $item->title; } @@ -268,7 +264,7 @@ public function interactiveFeatures() $this->seo->setTitle('Search'); $general = $this->searchRepository->forSearchQuery(request('q'), 0); - $interactiveFeatures = $this->interactiveFeatureRespository->search(request('q'))->paginate(self::INTERACTIVEFEATURES_PER_PAGE); + $interactiveFeatures = $this->interactiveFeatureRepository->search(request('q'))->paginate(self::INTERACTIVEFEATURES_PER_PAGE); $links = $this->buildSearchLinks($general, 'interactive-features'); @@ -359,17 +355,17 @@ public function pages() ]); } - public function researchGuides() + public function educatorResources() { $this->seo->setTitle('Search'); $general = $this->searchRepository->forSearchQuery(request('q'), 0); - $guides = $this->researchGuideRepository->searchApi(request('q'), self::ALL_PER_PAGE_EVENTS); + $educatorResources = $this->educatorResourceRepository->searchApi(request('q'), self::ALL_PER_PAGE_EVENTS); - $links = $this->buildSearchLinks($general, 'research-guides'); + $links = $this->buildSearchLinks($general, 'educator-resources'); return view('site.search.index', [ - 'researchGuides' => $guides, + 'educatorResources' => $educatorResources, 'allResultsView' => true, 'searchResultsTypeLinks' => $links, ]); @@ -447,8 +443,8 @@ protected function buildSearchLinks($all, $active = 'all') array_push($links, $this->buildLabel('Publications', QueryHelpers::extractAggregation($aggregations, ['digital-catalogs', 'printed-catalogs']), route('search.publications', ['q' => request('q')]), $active == 'publications')); } - if (QueryHelpers::extractAggregation($aggregations, ['research-guides', 'educator-resources'])) { - array_push($links, $this->buildLabel('Resources', QueryHelpers::extractAggregation($aggregations, ['research-guides', 'educator-resources']), route('search.research-guides', ['q' => request('q')]), $active == 'research-guides')); + if (QueryHelpers::extractAggregation($aggregations, 'educator-resources')) { + array_push($links, $this->buildLabel('Resources', QueryHelpers::extractAggregation($aggregations, 'educator-resources'), route('search.educator-resources', ['q' => request('q')]), $active == 'educator-resources')); } if (QueryHelpers::extractAggregation($aggregations, 'press-releases')) { diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index f0d19b561..bfbce78e1 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -59,6 +59,5 @@ class Kernel extends HttpKernel 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, - 'httpauth' => \App\Http\Middleware\BasicHttpAuth::class, ]; } diff --git a/app/Http/Middleware/BasicHttpAuth.php b/app/Http/Middleware/BasicHttpAuth.php deleted file mode 100644 index 76ca0e2f7..000000000 --- a/app/Http/Middleware/BasicHttpAuth.php +++ /dev/null @@ -1,21 +0,0 @@ - 'required', 'heading' => 'max:255', 'list_description' => 'max:255', - 'citations' => 'max:255' + 'citations' => 'max:255', + 'hero_caption' => 'max:255' ]; } } diff --git a/app/Http/Requests/Admin/CategoryTermRequest.php b/app/Http/Requests/Admin/CategoryTermRequest.php index bf0a89afd..b7cf8087a 100644 --- a/app/Http/Requests/Admin/CategoryTermRequest.php +++ b/app/Http/Requests/Admin/CategoryTermRequest.php @@ -9,14 +9,14 @@ class CategoryTermRequest extends Request public function rulesForCreate() { return [ - 'name' => 'required', + 'title' => 'required', ]; } public function rulesForUpdate() { return [ - 'name' => 'required' + 'title' => 'required' ]; } } diff --git a/app/Http/Requests/Admin/DigitalPublicationRequest.php b/app/Http/Requests/Admin/DigitalPublicationRequest.php index e607f33b5..58f35e63b 100644 --- a/app/Http/Requests/Admin/DigitalPublicationRequest.php +++ b/app/Http/Requests/Admin/DigitalPublicationRequest.php @@ -18,7 +18,7 @@ public function rulesForUpdate() return [ 'title' => 'required', 'listing_description' => 'max:255', - 'short_description' => 'max:255', + 'hero_caption' => 'max:255', 'bgcolor' => 'nullable|regex:/^#[0-9a-fA-F]{6}/' ]; } diff --git a/app/Http/Requests/Admin/EventRequest.php b/app/Http/Requests/Admin/EventRequest.php index fdc3fd940..832d1dffd 100644 --- a/app/Http/Requests/Admin/EventRequest.php +++ b/app/Http/Requests/Admin/EventRequest.php @@ -5,7 +5,6 @@ use App\Models\Event; use Illuminate\Validation\Rule; use Illuminate\Support\Facades\Validator; - use A17\Twill\Http\Requests\Admin\Request; class EventRequest extends Request diff --git a/app/Http/Requests/Admin/FeeCategoryRequest.php b/app/Http/Requests/Admin/FeeCategoryRequest.php index fa9399a1d..f7b87de7b 100644 --- a/app/Http/Requests/Admin/FeeCategoryRequest.php +++ b/app/Http/Requests/Admin/FeeCategoryRequest.php @@ -9,7 +9,7 @@ class FeeCategoryRequest extends Request public function rulesForCreate() { return [ - 'title' => 'required', + 'title' => 'required', 'tooltip' => 'required' ]; } @@ -17,7 +17,7 @@ public function rulesForCreate() public function rulesForUpdate() { return [ - 'title' => 'required', + 'title' => 'required', 'tooltip' => 'required', ]; } diff --git a/app/Http/Requests/Admin/IssueArticleRequest.php b/app/Http/Requests/Admin/IssueArticleRequest.php deleted file mode 100644 index e7ac79a8f..000000000 --- a/app/Http/Requests/Admin/IssueArticleRequest.php +++ /dev/null @@ -1,20 +0,0 @@ - 'required', - ]; - } -} diff --git a/app/Http/Requests/Admin/IssueRequest.php b/app/Http/Requests/Admin/IssueRequest.php deleted file mode 100644 index 2d85cd7f5..000000000 --- a/app/Http/Requests/Admin/IssueRequest.php +++ /dev/null @@ -1,21 +0,0 @@ - 'required', - 'issue_number' => 'required|numeric', - ]; - } -} diff --git a/app/Http/Requests/Admin/PressReleaseRequest.php b/app/Http/Requests/Admin/PressReleaseRequest.php index 7f17a4738..546e696c1 100644 --- a/app/Http/Requests/Admin/PressReleaseRequest.php +++ b/app/Http/Requests/Admin/PressReleaseRequest.php @@ -17,7 +17,8 @@ public function rulesForUpdate() { return [ 'title' => 'required', - 'listing_description' => 'max:255' + 'listing_description' => 'max:255', + 'short_description' => 'max:255' ]; } } diff --git a/app/Http/Requests/Admin/ResearchGuideRequest.php b/app/Http/Requests/Admin/ResearchGuideRequest.php deleted file mode 100644 index ac8834a16..000000000 --- a/app/Http/Requests/Admin/ResearchGuideRequest.php +++ /dev/null @@ -1,24 +0,0 @@ - 'required' - ]; - } - - public function rulesForUpdate() - { - return [ - 'title' => 'required', - 'listing_description' => 'max:255', - 'short_description' => 'max:255' - ]; - } -} diff --git a/app/Http/Resources/Slide.php b/app/Http/Resources/Slide.php index aac0a0c40..d0309a3c3 100644 --- a/app/Http/Resources/Slide.php +++ b/app/Http/Resources/Slide.php @@ -166,10 +166,9 @@ protected function getFullWidthMediaAttributes() ]; } - return [ - - ]; + return [ + ]; } else { $src = ''; } @@ -231,10 +230,9 @@ protected function get3DTourAttributes() ]; } - return [ - - ]; + return [ + ]; } protected function getEndAttributes() diff --git a/app/Http/Resources/SlideAsset.php b/app/Http/Resources/SlideAsset.php index cd6dfbd65..33f2f2a7c 100644 --- a/app/Http/Resources/SlideAsset.php +++ b/app/Http/Resources/SlideAsset.php @@ -47,7 +47,6 @@ public function toArray($request) ]; } - return []; - + return []; } } diff --git a/app/Http/Transformers/InteractiveFeatureTransformer.php b/app/Http/Transformers/InteractiveFeatureTransformer.php index 2f31dfd30..5ff3391c3 100644 --- a/app/Http/Transformers/InteractiveFeatureTransformer.php +++ b/app/Http/Transformers/InteractiveFeatureTransformer.php @@ -4,7 +4,6 @@ class InteractiveFeatureTransformer extends ApiTransformer { - /** * List of resources possible to include * diff --git a/app/Http/Transformers/IssueArticleTransformer.php b/app/Http/Transformers/IssueArticleTransformer.php deleted file mode 100644 index 27ed9baf1..000000000 --- a/app/Http/Transformers/IssueArticleTransformer.php +++ /dev/null @@ -1,7 +0,0 @@ -getSearch($perPage, $columns, $pageName, $page); } - return $this->getPaginated($perPage, $columns, $pageName, $page); - + return $this->getPaginated($perPage, $columns, $pageName, $page); } protected function paginator($items, $total, $perPage, $currentPage, $options) @@ -598,8 +596,7 @@ public function resolveCollectionEndpoint() return $this->customEndpoint; } - return $this->performSearch ? 'search' : 'collection'; - + return $this->performSearch ? 'search' : 'collection'; } /** diff --git a/app/Libraries/Api/Builders/ApiModelBuilderSearch.php b/app/Libraries/Api/Builders/ApiModelBuilderSearch.php index 7ebefa500..7f589fbf6 100644 --- a/app/Libraries/Api/Builders/ApiModelBuilderSearch.php +++ b/app/Libraries/Api/Builders/ApiModelBuilderSearch.php @@ -8,7 +8,6 @@ class ApiModelBuilderSearch extends ApiModelBuilder { - /** * Defines a map of [types => API class, ...] * diff --git a/app/Libraries/Api/Builders/ApiQueryBuilder.php b/app/Libraries/Api/Builders/ApiQueryBuilder.php index 1e6da347f..507b6d8ad 100644 --- a/app/Libraries/Api/Builders/ApiQueryBuilder.php +++ b/app/Libraries/Api/Builders/ApiQueryBuilder.php @@ -11,7 +11,6 @@ class ApiQueryBuilder { - /** * All of the available clause operators. * @@ -171,8 +170,7 @@ public function whereIn($column, $values, $boolean = 'and', $not = false) return $this; } - throw new \Exception('whereIn function has been defined only for IDS at the API Query Builder'); - + throw new \Exception('whereIn function has been defined only for IDS at the API Query Builder'); } /** @@ -470,8 +468,7 @@ public function get($columns = [], $endpoint = null) return $results->body; } - return $results; - + return $results; } $this->columns = $original; diff --git a/app/Libraries/Api/Builders/Connection/AicConnection.php b/app/Libraries/Api/Builders/Connection/AicConnection.php index 3f3f413a6..baed27675 100644 --- a/app/Libraries/Api/Builders/Connection/AicConnection.php +++ b/app/Libraries/Api/Builders/Connection/AicConnection.php @@ -133,8 +133,7 @@ public function execute($endpoint = null, $params = []) return $response; } - return $this->client->request($verb, $endpoint, $options); - + return $this->client->request($verb, $endpoint, $options); } /** diff --git a/app/Libraries/Api/Builders/Grammar/AicGrammar.php b/app/Libraries/Api/Builders/Grammar/AicGrammar.php index 7d4af34eb..3cbd753b6 100644 --- a/app/Libraries/Api/Builders/Grammar/AicGrammar.php +++ b/app/Libraries/Api/Builders/Grammar/AicGrammar.php @@ -122,8 +122,7 @@ protected function compileSearchText($query, $text) return ['q' => $text]; } - return []; - + return []; } protected function compileSearchParameters($query, array $elasticParameters) diff --git a/app/Libraries/Api/Builders/Grammar/MsearchGrammar.php b/app/Libraries/Api/Builders/Grammar/MsearchGrammar.php index 3dd247483..45cd8c272 100644 --- a/app/Libraries/Api/Builders/Grammar/MsearchGrammar.php +++ b/app/Libraries/Api/Builders/Grammar/MsearchGrammar.php @@ -6,7 +6,6 @@ class MsearchGrammar extends SearchGrammar { - /** * Compile the components necessary for a select clause. * diff --git a/app/Libraries/Api/Models/ApiCollection.php b/app/Libraries/Api/Models/ApiCollection.php index ef9bc8cca..6d512144c 100644 --- a/app/Libraries/Api/Models/ApiCollection.php +++ b/app/Libraries/Api/Models/ApiCollection.php @@ -21,8 +21,7 @@ public function getMetadata($name = null) return $this->metadata->get($name); } - return $this->metadata; - + return $this->metadata; } } diff --git a/app/Libraries/Api/Models/BaseApiModel.php b/app/Libraries/Api/Models/BaseApiModel.php index 5c5b1bfb9..c11d15fc5 100644 --- a/app/Libraries/Api/Models/BaseApiModel.php +++ b/app/Libraries/Api/Models/BaseApiModel.php @@ -25,7 +25,10 @@ abstract class BaseApiModel implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, UrlRoutable { - use HasApiCalls, HasAugmentedModel, HasRelationships, HasPresenter; + use HasApiCalls; + use HasAugmentedModel; + use HasRelationships; + use HasPresenter; protected $attributes = []; @@ -520,8 +523,10 @@ public function attributesToArray() // the values to their appropriate type. If the attribute has a mutator we // will not perform the cast on those attributes to avoid any confusion. foreach ($this->casts as $key => $value) { - if (!array_key_exists($key, $attributes) || - in_array($key, $mutatedAttributes)) { + if ( + !array_key_exists($key, $attributes) || + in_array($key, $mutatedAttributes) + ) { continue; } @@ -589,8 +594,10 @@ protected function getArrayableItems(array $values) */ public function getAttribute($key) { - if (array_key_exists($key, $this->attributes) || - $this->hasGetMutator($key)) { + if ( + array_key_exists($key, $this->attributes) || + $this->hasGetMutator($key) + ) { return $this->getAttributeValue($key); } @@ -937,8 +944,7 @@ public function newCollection($models = []) return $models; } - return new BaseCollection($models); - + return new BaseCollection($models); } /** @@ -1052,7 +1058,6 @@ public function getEndpoint($type) public function getTable() { - } /** @@ -1077,7 +1082,6 @@ public function resolveRouteBinding($value, $field = null) public function resolveChildRouteBinding($childType, $value, $field) { - } public function getKeyName() diff --git a/app/Libraries/Api/Models/Behaviors/HasApiCalls.php b/app/Libraries/Api/Models/Behaviors/HasApiCalls.php index effc978bd..684556f93 100644 --- a/app/Libraries/Api/Models/Behaviors/HasApiCalls.php +++ b/app/Libraries/Api/Models/Behaviors/HasApiCalls.php @@ -8,7 +8,6 @@ trait HasApiCalls { - /** * The array of default scopes on the model. * diff --git a/app/Libraries/Api/Models/Behaviors/HasRelationships.php b/app/Libraries/Api/Models/Behaviors/HasRelationships.php index f17821795..505ce7e3b 100644 --- a/app/Libraries/Api/Models/Behaviors/HasRelationships.php +++ b/app/Libraries/Api/Models/Behaviors/HasRelationships.php @@ -46,13 +46,12 @@ public function hasMany($related, $localKey = 'id', $limit = -1) return; } - return $this->newHasMany( - $queryInstance, - $this, - $localKey, - $limit - ); - + return $this->newHasMany( + $queryInstance, + $this, + $localKey, + $limit + ); } /** @@ -83,10 +82,9 @@ public function getRelationValue($key) return $this->relations[$key]; } - if (method_exists($this, $key)) { - return $this->getRelationshipFromMethod($key); - } - + if (method_exists($this, $key)) { + return $this->getRelationshipFromMethod($key); + } } protected function getRelationshipFromMethod($method) diff --git a/app/Libraries/DamsImageService.php b/app/Libraries/DamsImageService.php index d2a0b9aaa..9b7a488fb 100644 --- a/app/Libraries/DamsImageService.php +++ b/app/Libraries/DamsImageService.php @@ -4,7 +4,8 @@ use A17\Twill\Services\MediaLibrary\ImageServiceDefaults; use A17\Twill\Services\MediaLibrary\ImageServiceInterface; -use Cache; +use Illuminate\Support\Facades\Storage; +use Illuminate\Support\Facades\Cache; use App\Helpers\StringHelpers; class DamsImageService implements ImageServiceInterface @@ -85,28 +86,34 @@ public function getUrl($id, array $params = []) return $this->base_url . $this->version . '/' . $id . '/' . $size . '/' . $dimensions . '/0/default.jpg'; } - public function getUrlWithCrop($id, array $cropParams, array $params = []) + public function getUrlWithCrop($id, array $crop_params, array $params = []) { + return $this->getRawUrl($id); } public function getUrlWithFocalCrop($id, array $cropParams, $width, $height, array $params = []) { + return $this->getRawUrl($id); } public function getLQIPUrl($id, array $params = []) { + return $this->getRawUrl($id); } public function getSocialUrl($id, array $params = []) { + return $this->getRawUrl($id); } public function getCmsUrl($id, array $params = []) { + return $this->getRawUrl($id); } public function getRawUrl($id) { + return Storage::disk(config('twill.media_library.disk'))->url($id); } public function getInfo($object, $imageField = 'image_id') @@ -132,9 +139,8 @@ public function getInfo($object, $imageField = 'image_id') return $info; } - // Hit the server to get the info if not available - return $this->getDimensions($object->{$imageField}); - + // Hit the server to get the info if not available + return $this->getDimensions($object->{$imageField}); } public function getDimensions($id) diff --git a/app/Libraries/ExactTargetService.php b/app/Libraries/ExactTargetService.php index 14855c2c2..604ed01fc 100644 --- a/app/Libraries/ExactTargetService.php +++ b/app/Libraries/ExactTargetService.php @@ -42,7 +42,6 @@ public function __construct( */ public function subscribe($alsoRemove = true) { - $auth_url = config('exact-target.client.baseAuthUrl'); $clientId = config('exact-target.client.clientid'); $clientSecret = config('exact-target.client.clientsecret'); @@ -134,8 +133,10 @@ public function subscribe($alsoRemove = true) $error = $response->results[0]->ErrorMessage ?? ''; $status = $response->results[0]->StatusMessage ?? ''; - if (Str::startsWith($error, 'Violation of PRIMARY KEY constraint') - || Str::startsWith($status, 'The subscriber is already on the list')) { + if ( + Str::startsWith($error, 'Violation of PRIMARY KEY constraint') + || Str::startsWith($status, 'The subscriber is already on the list') + ) { // Email has been previously subscribed, so proceed } else { return $response; diff --git a/app/Libraries/ExploreFurther/BaseService.php b/app/Libraries/ExploreFurther/BaseService.php index 4fb06c9ea..8a0b7edb1 100644 --- a/app/Libraries/ExploreFurther/BaseService.php +++ b/app/Libraries/ExploreFurther/BaseService.php @@ -3,9 +3,7 @@ namespace App\Libraries\ExploreFurther; use App\Models\Api\Search; - use Illuminate\Support\Str; - use App\Helpers\DateHelpers; /** @@ -17,13 +15,13 @@ class BaseService { - const MAX_TAGS = 3; - const PER_PAGE_EXPLORE_FURTHER = 13; + public const MAX_TAGS = 3; + public const PER_PAGE_EXPLORE_FURTHER = 13; /** * Array with valid filters for the Explore Further section. */ - const VALID_FILTERS = [ + public const VALID_FILTERS = [ 'ef-classification_ids', 'ef-artist_ids', 'ef-style_ids', @@ -138,7 +136,7 @@ public function collection($parameters = []) if ($active) { if ($parameters->get('ef-most-similar_ids')) { - $query->byMostSimilar($this->resource->id, get_class($this->resource)); + $query->byMostSimilar($this->resource); } else { $years = explode('|', $parameters->get('ef-date_ids')); @@ -191,7 +189,7 @@ public function collection($parameters = []) break; case 'most-similar': - $query->byMostSimilar($this->resource->id, get_class($this->resource)); + $query->byMostSimilar($this->resource); break; } diff --git a/app/Libraries/RecentlyViewedService.php b/app/Libraries/RecentlyViewedService.php index de0f5b4e6..8dbb2794f 100644 --- a/app/Libraries/RecentlyViewedService.php +++ b/app/Libraries/RecentlyViewedService.php @@ -13,7 +13,7 @@ class RecentlyViewedService { - const THEMES_PER_CATEGORY = 3; + public const THEMES_PER_CATEGORY = 3; /** * Add a new item to the recently viewed collection @@ -98,7 +98,6 @@ public function getThemes() // If we have recently viewed elements if (!empty($ids)) { - // Let's aggregate on them to get better suggestions $tags = Search::query() ->forceEndpoint('search') diff --git a/app/Libraries/Search/CollectionService.php b/app/Libraries/Search/CollectionService.php index a47223314..5c0ede266 100644 --- a/app/Libraries/Search/CollectionService.php +++ b/app/Libraries/Search/CollectionService.php @@ -7,12 +7,11 @@ use App\Libraries\Search\Filters\BooleanFilter; use App\Libraries\Search\Filters\ColorFilter; use App\Models\Api\Search; - use Illuminate\Support\Str; class CollectionService { - const API_SEARCH_CACHE_TTL = 3600; + public const API_SEARCH_CACHE_TTL = 3600; protected $chain; diff --git a/app/Libraries/Search/Filters/BaseFilteredList.php b/app/Libraries/Search/Filters/BaseFilteredList.php index 3b4c31062..89d72e58f 100644 --- a/app/Libraries/Search/Filters/BaseFilteredList.php +++ b/app/Libraries/Search/Filters/BaseFilteredList.php @@ -28,9 +28,11 @@ public function generateFilteredCategory() // WEB-1035: If there's no item with a requested id in buckets, prepend it foreach ($inputs as $input) { - if (!$this->buckets->contains(function ($item) use ($input) { - return $item->key === $input; - })) { + if ( + !$this->buckets->contains(function ($item) use ($input) { + return $item->key === $input; + }) + ) { $this->buckets->prepend((object) [ 'key' => $input, 'doc_count' => 'N/A', diff --git a/app/Libraries/Search/Filters/Departments.php b/app/Libraries/Search/Filters/Departments.php index 6e8eae1d3..d391bb8d9 100644 --- a/app/Libraries/Search/Filters/Departments.php +++ b/app/Libraries/Search/Filters/Departments.php @@ -8,7 +8,7 @@ class Departments extends BaseFilteredList protected $entity = \App\Models\Api\Department::class; // ART-48, WEB-1831: Combine library and archives into one filter - const RESEARCH_TITLE = 'Research Center'; + public const RESEARCH_TITLE = 'Research Center'; private string $archiveTitle; private string $libraryTitle; diff --git a/app/Libraries/ShortcodeService.php b/app/Libraries/ShortcodeService.php index 7989e6c7f..3a4ff9167 100644 --- a/app/Libraries/ShortcodeService.php +++ b/app/Libraries/ShortcodeService.php @@ -5,16 +5,17 @@ class ShortcodeService { // Regex101 reference: https://regex101.com/r/mfPWWB/1/ - const REF_REGEXP = "/(?P(?:(?:\s?\[))(?Pref)(?:\])(?:(?P.*)(?:\[\/ref\])))/uU"; + public const REF_REGEXP = "/(?P(?:(?:\s?\[))(?Pref)(?:\])(?:(?P.*)(?:\[\/ref\])))/uU"; // Regex101 reference: https://regex101.com/r/sZ7wP0 - const ATTRIBUTE_REGEXP = "/(?\\S+)=[\"']?(?P(?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?/u"; + public const ATTRIBUTE_REGEXP = "/(?\\S+)=[\"']?(?P(?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?/u"; - public static function parse_ref($text) + public static function parse_ref($text) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { return self::parse_text_with_regexp($text, self::REF_REGEXP); } + // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps private static function parse_text_with_regexp($text, $regexp) { preg_match_all($regexp, $text, $matches, PREG_SET_ORDER); @@ -37,7 +38,7 @@ private static function parse_text_with_regexp($text, $regexp) return $shortcodes; } - private static function parse_attrs($attrs) + private static function parse_attrs($attrs) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { preg_match_all(self::ATTRIBUTE_REGEXP, $attrs, $matches, PREG_SET_ORDER); $attributes = []; diff --git a/app/Listeners/InvalidationListener.php b/app/Listeners/InvalidationListener.php index be06cf596..1d6dcb7c8 100644 --- a/app/Listeners/InvalidationListener.php +++ b/app/Listeners/InvalidationListener.php @@ -14,7 +14,6 @@ class InvalidationListener */ public function __construct() { - } /** diff --git a/app/Mail/FormMailable.php b/app/Mail/FormMailable.php index 09997dc5f..9a2600d8b 100644 --- a/app/Mail/FormMailable.php +++ b/app/Mail/FormMailable.php @@ -8,7 +8,8 @@ class FormMailable extends Mailable { - use Queueable, SerializesModels; + use Queueable; + use SerializesModels; protected function getSubjectTimestamp() { diff --git a/app/Models/Api/Artwork.php b/app/Models/Api/Artwork.php index 1a008b9cb..04822b997 100644 --- a/app/Models/Api/Artwork.php +++ b/app/Models/Api/Artwork.php @@ -13,12 +13,10 @@ use App\Helpers\DateHelpers; use App\Helpers\ImageHelpers; use App\Helpers\StringHelpers; +use Database\Factories\Api\HasApiFactory; class Artwork extends BaseApiModel { - const RELATED_MULTIMEDIA = 100; - const EXTRA_IMAGES_LIMIT = 9; - use HasMediasApi { imageFront as traitImageFront; } @@ -28,6 +26,11 @@ class Artwork extends BaseApiModel getCustomRelatedItems as traitGetCustomRelatedItems; } + use HasApiFactory; + + public const RELATED_MULTIMEDIA = 100; + public const EXTRA_IMAGES_LIMIT = 9; + protected $showDefaultRelatedItems = true; protected $endpoints = [ @@ -54,7 +57,7 @@ class Artwork extends BaseApiModel /** * Fields used when performing a search so we avoid a double call retrieving the complete entities */ - const SEARCH_FIELDS = [ + public const SEARCH_FIELDS = [ 'id', 'title', 'date_display', @@ -301,8 +304,8 @@ public function allImages() }) ->prepend($main) ->reject(function ($name) { - return empty($name); - }); + return empty($name); + }); } public function categories() @@ -565,7 +568,7 @@ private function getMostSimilarIds() return Search::query() ->resources(['artworks']) ->forceEndpoint('search') - ->byMostSimilar($this->id, get_class($this), true) + ->byMostSimilar($this, true) ->getPaginatedModel(13, self::SEARCH_FIELDS) ->filter(function ($value, $key) { return $this->id != $value->id; diff --git a/app/Models/Api/Asset.php b/app/Models/Api/Asset.php index efbb4d056..f1cc65a5a 100644 --- a/app/Models/Api/Asset.php +++ b/app/Models/Api/Asset.php @@ -5,7 +5,6 @@ use App\Libraries\Api\Models\BaseApiModel; use App\Models\Behaviors\HasMediasApi; use App\Helpers\ImageHelpers; - use Illuminate\Support\Str; class Asset extends BaseApiModel @@ -123,8 +122,8 @@ public function getEmbedAttribute() break; - // All other cases were deprecated. - // If needed to add another embed type start here. + // All other cases were deprecated. + // If needed to add another embed type start here. } } @@ -134,16 +133,15 @@ public function getIconAfterAttribute() case 'sounds': return 'audio'; - break; + break; case 'videos': return 'video'; - break; + break; default: return 'new-window'; - break; - + break; } } diff --git a/app/Models/Api/Exhibition.php b/app/Models/Api/Exhibition.php index f6a758c2b..8272fad6b 100644 --- a/app/Models/Api/Exhibition.php +++ b/app/Models/Api/Exhibition.php @@ -30,7 +30,7 @@ class Exhibition extends BaseApiModel /** * Fields used when performing a search so we avoid a double call retrieving the complete entities */ - const SEARCH_FIELDS = ['id', 'title', 'status', 'aic_start_at', 'aic_end_at', 'is_boosted', 'thumbnail', 'short_description', 'gallery_title', 'gallery_id', 'image_id', 'api_model']; + public const SEARCH_FIELDS = ['id', 'title', 'status', 'aic_start_at', 'aic_end_at', 'is_boosted', 'thumbnail', 'short_description', 'gallery_title', 'gallery_id', 'image_id', 'api_model']; /** * Generates the id-slug type of URL @@ -45,7 +45,8 @@ public function getTypeAttribute() return 'exhibition'; } - private function commonStatusChecks() { + private function commonStatusChecks() + { // If the start and end dates are overriden, don't consider this exhibition as closed if ($this->date_display_override) { return false; @@ -198,13 +199,15 @@ public function getSeoDescriptionAttribute() return $this->header_copy; } - if (( - $augmentedModel && $paragraph = $augmentedModel->blocks()->where('type', '=', 'paragraph')->first() - ) && ( - !empty($paragraph) && $paragraph = $paragraph->content['paragraph'] - ) && ( - !empty($paragraph) && $paragraph = strip_tags($paragraph) - )) { + if ( + ( + $augmentedModel && $paragraph = $augmentedModel->blocks()->where('type', '=', 'paragraph')->first() + ) && ( + !empty($paragraph) && $paragraph = $paragraph->content['paragraph'] + ) && ( + !empty($paragraph) && $paragraph = strip_tags($paragraph) + ) + ) { return $paragraph; } diff --git a/app/Models/Api/Search.php b/app/Models/Api/Search.php index abda21477..27de41fe7 100644 --- a/app/Models/Api/Search.php +++ b/app/Models/Api/Search.php @@ -512,19 +512,16 @@ public function scopeByColor($query, $hsl) return $query->rawSearch($params); } - public function scopeByMostSimilar($query, $id, $class = \App\Models\Api\Artwork::class, $boost = false) + public function scopeByMostSimilar($query, Artist|Artwork $item = null, $boost = false) { - if (empty($id)) { + if (empty($item)) { return $query; } + $class = get_class($item); $query->boost($boost); $query->forceEndpoint('msearch'); - // Generalize to use this scope on artworks as well as artists - $item = $class::query() - ->findOrFail((int) $id); - $shoulds = []; if ($class == \App\Models\Api\Artwork::class) { diff --git a/app/Models/Api/TicketedEvent.php b/app/Models/Api/TicketedEvent.php index e55bc8325..2b5760f9c 100644 --- a/app/Models/Api/TicketedEvent.php +++ b/app/Models/Api/TicketedEvent.php @@ -3,7 +3,6 @@ namespace App\Models\Api; use App\Libraries\Api\Models\BaseApiModel; - use Carbon\Carbon; class TicketedEvent extends BaseApiModel diff --git a/app/Models/Article.php b/app/Models/Article.php index 89f31b1fe..e0c11ee89 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -12,12 +12,24 @@ use App\Models\Behaviors\HasApiRelations; use App\Models\Behaviors\HasFeaturedRelated; use App\Models\Behaviors\HasUnlisted; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Spatie\Feed\Feedable; use Spatie\Feed\FeedItem; class Article extends AbstractModel implements Feedable { - use HasSlug, HasRevisions, HasMedias, HasMediasEloquent, HasBlocks, Transformable, HasRelated, HasApiRelations, HasFeaturedRelated, HasUnlisted, HasAuthors; + use HasSlug; + use HasRevisions; + use HasMedias; + use HasMediasEloquent; + use HasBlocks; + use Transformable; + use HasRelated; + use HasApiRelations; + use HasFeaturedRelated; + use HasUnlisted; + use HasAuthors; + use HasFactory; protected $presenter = 'App\Presenters\Admin\ArticlePresenter'; protected $presenterAdmin = 'App\Presenters\Admin\ArticlePresenter'; @@ -56,8 +68,8 @@ class Article extends AbstractModel implements Feedable 'title', ]; - const BASIC = 0; - const LARGE = 1; + public const BASIC = 0; + public const LARGE = 1; public static $articleLayouts = [ self::BASIC => 'Basic', diff --git a/app/Models/Artist.php b/app/Models/Artist.php index 0609b79a7..41d3d9f26 100644 --- a/app/Models/Artist.php +++ b/app/Models/Artist.php @@ -12,7 +12,13 @@ class Artist extends AbstractModel { - use HasSlug, HasApiModel, HasApiRelations, HasMedias, HasMediasEloquent, Transformable, HasRelated; + use HasSlug; + use HasApiModel; + use HasApiRelations; + use HasMedias; + use HasMediasEloquent; + use Transformable; + use HasRelated; protected $apiModel = 'App\Models\Api\Artist'; diff --git a/app/Models/Artwork.php b/app/Models/Artwork.php index 4181d12a9..5452b81b8 100644 --- a/app/Models/Artwork.php +++ b/app/Models/Artwork.php @@ -12,7 +12,13 @@ class Artwork extends AbstractModel { - use HasApiModel, Transformable, HasRelated, HasApiRelations, HasFeaturedRelated, HasMedias, HasFiles; + use HasApiModel; + use Transformable; + use HasRelated; + use HasApiRelations; + use HasFeaturedRelated; + use HasMedias; + use HasFiles; protected $apiModel = 'App\Models\Api\Artwork'; @@ -130,7 +136,7 @@ protected function transformMappingInternal() ->exists() // || $this->model3d()->exists() // || (bool) $this->default_manifest_url -; + ; }, ], ]; diff --git a/app/Models/Author.php b/app/Models/Author.php index e8611f544..6ed779feb 100644 --- a/app/Models/Author.php +++ b/app/Models/Author.php @@ -9,7 +9,10 @@ class Author extends AbstractModel { - use HasSlug, HasMedias, HasRevisions, HasMediasEloquent; + use HasSlug; + use HasMedias; + use HasRevisions; + use HasMediasEloquent; protected $fillable = [ 'published', @@ -55,11 +58,6 @@ public function experiences() return $this->morphedByMany('App\Models\Experience', 'authorable'); } - public function issueArticle() - { - return $this->morphedByMany('App\Models\IssueArticle', 'authorable'); - } - public function scopeOrdered($query) { if ($this->isFillable('title')) { diff --git a/app/Models/Behaviors/HasApiRelations.php b/app/Models/Behaviors/HasApiRelations.php index fb2275e17..609ad2e5a 100644 --- a/app/Models/Behaviors/HasApiRelations.php +++ b/app/Models/Behaviors/HasApiRelations.php @@ -23,18 +23,17 @@ public function apiModels($relation, $model, $ttl = null) if (empty($ids)) { return collect(); } - // Load real the real models from the API - $results = $modelClass::query()->ttl($ttl)->ids($ids)->get(); - - // Sort them by the original ids listing (coming from our CMS position attribute) - $sorted = $results->sortBy(function ($model, $key) use ($ids) { - return collect($ids)->search(function ($id, $key) use ($model) { - return $id == $model->id; - }); - }); + // Load real the real models from the API + $results = $modelClass::query()->ttl($ttl)->ids($ids)->get(); - return $sorted; + // Sort them by the original ids listing (coming from our CMS position attribute) + $sorted = $results->sortBy(function ($model, $key) use ($ids) { + return collect($ids)->search(function ($id, $key) use ($model) { + return $id == $model->id; + }); + }); + return $sorted; } public function getRelatedWithApiModels($browser_name, $apiModelsDefinitions, $typeUsesApi) diff --git a/app/Models/Behaviors/HasFeaturedRelated.php b/app/Models/Behaviors/HasFeaturedRelated.php index f33a2213d..fd092b347 100644 --- a/app/Models/Behaviors/HasFeaturedRelated.php +++ b/app/Models/Behaviors/HasFeaturedRelated.php @@ -9,7 +9,6 @@ use App\Models\Experience; use App\Models\DigitalPublication; use App\Models\Video; - use Illuminate\Support\Facades\Cache; use Carbon\Carbon; @@ -44,10 +43,12 @@ public function getFeaturedRelated() if (!$this->selectedFeaturedRelateds) { $relatedItems = $this->getCustomRelatedItems(); - if (($this->showDefaultRelatedItems ?? false) && $relatedItems->count() < 1) { - $relatedItems = $this->getDefaultRelatedItems($relatedItems); - $relatedItems = $relatedItems->slice(0, $this->getTargetItemCount()); - $this->sidebarContainsDefaultRelated = true; + if (config('aic.show_default_related_items')) { + if (($this->showDefaultRelatedItems ?? false) && $relatedItems->count() < 1) { + $relatedItems = $this->getDefaultRelatedItems($relatedItems); + $relatedItems = $relatedItems->slice(0, $this->getTargetItemCount()); + $this->sidebarContainsDefaultRelated = true; + } } $this->selectedFeaturedRelateds = $this->getLabeledRelatedItems($relatedItems); diff --git a/app/Models/Behaviors/HasMedias.php b/app/Models/Behaviors/HasMedias.php index ee2bf702c..2feacda12 100644 --- a/app/Models/Behaviors/HasMedias.php +++ b/app/Models/Behaviors/HasMedias.php @@ -23,6 +23,8 @@ public function imageAsArray($role, $crop = 'default', $params = [], $media = nu 'src' => $this->image($role, $crop, $params, false, false, $media), 'width' => $media->pivot->crop_w ?? $media->width, 'height' => $media->pivot->crop_h ?? $media->height, + 'crop_x' => $media->pivot->crop_x ?? 0, + 'crop_y' => $media->pivot->crop_y ?? 0, 'alt' => $this->imageAltText($role, $media), 'caption' => $this->imageCaption($role, $media), 'video' => $this->imageVideo($role, $media), diff --git a/app/Models/Behaviors/HasMediasApi.php b/app/Models/Behaviors/HasMediasApi.php index 9fad57ab5..db29ff14f 100644 --- a/app/Models/Behaviors/HasMediasApi.php +++ b/app/Models/Behaviors/HasMediasApi.php @@ -6,7 +6,6 @@ trait HasMediasApi { - /** * You have to define roles and crop on the API model. * @@ -38,12 +37,11 @@ public function imageFront($role = 'hero', $crop = null) return $image; } - if (!empty($this->{$this->getImageField($role, 'default')})) { - $image = DamsImageService::getImage($this, $this->getImageField($role, 'default')); - - return $image; - } + if (!empty($this->{$this->getImageField($role, 'default')})) { + $image = DamsImageService::getImage($this, $this->getImageField($role, 'default')); + return $image; + } } // If nothing has been returned on the API side, check for an augmented model @@ -69,8 +67,7 @@ protected function getImageField($role, $crop) return $this->mediasParams[$role][$crop]['field']; } - return 'image_id'; - + return 'image_id'; } protected function getWidth($role, $crop, $image) @@ -79,8 +76,7 @@ protected function getWidth($role, $crop, $image) return $this->mediasParams[$role][$crop]['width']; } - return $image['width'] ?? ''; - + return $image['width'] ?? ''; } protected function getHeight($role, $crop, $image) @@ -89,7 +85,6 @@ protected function getHeight($role, $crop, $image) return $this->mediasParams[$role][$crop]['height']; } - return $image['height'] ?? ''; - + return $image['height'] ?? ''; } } diff --git a/app/Models/CategoryTerm.php b/app/Models/CategoryTerm.php index 378f9e976..3144ad22b 100644 --- a/app/Models/CategoryTerm.php +++ b/app/Models/CategoryTerm.php @@ -9,7 +9,11 @@ class CategoryTerm extends AbstractModel { - use HasApiModel, Transformable, HasMedias, HasMediasEloquent, HasApiRelations; + use HasApiModel; + use Transformable; + use HasMedias; + use HasMediasEloquent; + use HasApiRelations; protected $apiModel = 'App\Models\Api\CategoryTerm'; diff --git a/app/Models/DateRule.php b/app/Models/DateRule.php index 3bf9bd223..adf51f6c1 100644 --- a/app/Models/DateRule.php +++ b/app/Models/DateRule.php @@ -69,26 +69,34 @@ public static function getMonthlyRepeat() public function getRuleType() { switch ($this->type) { - case 0:return 'recurrent'; - case 1:return 'include'; - case 2:return 'exclude'; + case 0: + return 'recurrent'; + case 1: + return 'include'; + case 2: + return 'exclude'; } } public function getMonthlyRepeatType() { switch ($this->monthly_repeat_pattern) { - case 0:return 'numeral'; - case 1:return 'first_day'; + case 0: + return 'numeral'; + case 1: + return 'first_day'; } } public function getRecurringType() { switch ($this->recurring_type) { - case 0:return 'DAILY'; - case 1:return 'WEEKLY'; - case 2:return 'MONTHLY'; + case 0: + return 'DAILY'; + case 1: + return 'WEEKLY'; + case 2: + return 'MONTHLY'; } } diff --git a/app/Models/Department.php b/app/Models/Department.php index 7febc5cce..b1caaefb3 100644 --- a/app/Models/Department.php +++ b/app/Models/Department.php @@ -11,7 +11,12 @@ class Department extends AbstractModel { - use HasApiModel, Transformable, HasMedias, HasApiRelations, HasMediasEloquent, HasRelated; + use HasApiModel; + use Transformable; + use HasMedias; + use HasApiRelations; + use HasMediasEloquent; + use HasRelated; protected $apiModel = 'App\Models\Api\Department'; diff --git a/app/Models/DigitalPublication.php b/app/Models/DigitalPublication.php index 9f0773a4f..6abde9f3c 100644 --- a/app/Models/DigitalPublication.php +++ b/app/Models/DigitalPublication.php @@ -4,7 +4,6 @@ use PDO; use Illuminate\Support\Facades\DB; - use A17\Twill\Models\Behaviors\HasFiles; use A17\Twill\Models\Behaviors\HasRevisions; use A17\Twill\Models\Behaviors\HasSlug; @@ -16,11 +15,18 @@ class DigitalPublication extends AbstractModel { - use HasBlocks, HasSlug, HasMedias, HasFiles, HasRevisions, HasMediasEloquent, Transformable, HasRelated, HasFactory; + use HasBlocks; + use HasSlug; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasMediasEloquent; + use Transformable; + use HasRelated; + use HasFactory; protected $fillable = [ 'listing_description', - 'short_description', 'hero_caption', 'title', 'title_display', diff --git a/app/Models/DigitalPublicationSection.php b/app/Models/DigitalPublicationSection.php index cd13fb746..a7ef4e2f1 100644 --- a/app/Models/DigitalPublicationSection.php +++ b/app/Models/DigitalPublicationSection.php @@ -6,18 +6,23 @@ use A17\Twill\Models\Behaviors\HasRevisions; use A17\Twill\Models\Behaviors\HasPosition; use A17\Twill\Models\Behaviors\Sortable; - use App\Models\Behaviors\HasAuthors; use App\Models\Behaviors\HasMedias; use App\Models\Behaviors\HasMediasEloquent; use App\Models\Behaviors\HasBlocks; - use Illuminate\Database\Eloquent\Factories\HasFactory; class DigitalPublicationSection extends AbstractModel implements Sortable { - use HasSlug, HasRevisions, HasPosition, HasMedias, HasMediasEloquent, HasBlocks, HasAuthors, Transformable, - HasFactory; + use HasSlug; + use HasRevisions; + use HasPosition; + use HasMedias; + use HasMediasEloquent; + use HasBlocks; + use HasAuthors; + use Transformable; + use HasFactory; protected $presenter = 'App\Presenters\Admin\DigitalPublicationSectionPresenter'; protected $presenterAdmin = 'App\Presenters\Admin\DigitalPublicationSectionPresenter'; @@ -80,9 +85,9 @@ class DigitalPublicationSection extends AbstractModel implements Sortable ], ]; - const ABOUT = 'about'; - const TEXT = 'text'; - const WORK = 'work'; + public const ABOUT = 'about'; + public const TEXT = 'text'; + public const WORK = 'work'; public static $types = [ self::ABOUT => 'About', diff --git a/app/Models/DiningHour.php b/app/Models/DiningHour.php index 2aae6449f..2c185e335 100644 --- a/app/Models/DiningHour.php +++ b/app/Models/DiningHour.php @@ -7,7 +7,8 @@ class DiningHour extends AbstractModel { - use HasMedias, HasMediasEloquent; + use HasMedias; + use HasMediasEloquent; protected $fillable = [ 'published', diff --git a/app/Models/EducatorResource.php b/app/Models/EducatorResource.php index fae97e2e9..89a6b6e56 100644 --- a/app/Models/EducatorResource.php +++ b/app/Models/EducatorResource.php @@ -12,7 +12,14 @@ class EducatorResource extends AbstractModel { - use HasBlocks, HasSlug, HasMedias, HasFiles, HasRevisions, HasMediasEloquent, Transformable, HasRelated; + use HasBlocks; + use HasSlug; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasMediasEloquent; + use Transformable; + use HasRelated; protected $fillable = [ 'listing_description', @@ -100,6 +107,10 @@ public function scopeIds($query, $ids = []) return $query->whereIn('id', $ids); } + public function scopeOrderByDate($query) + { + return $query->orderBy('publish_start_date', 'DESC'); + } public function scopeByCategory($query, $category = null) { if (empty($category)) { diff --git a/app/Models/Event.php b/app/Models/Event.php index 82eb0e43b..af40ed4c8 100644 --- a/app/Models/Event.php +++ b/app/Models/Event.php @@ -11,17 +11,23 @@ use App\Models\Behaviors\HasApiRelations; use App\Helpers\QueryHelpers; use Carbon\Carbon; - // WEB-2260: Use `whereJsonContains` in Laravel 5.7 - https://github.com/laravel/framework/pull/24330 use Illuminate\Support\Facades\DB; use Illuminate\Support\Arr; use Illuminate\Database\Eloquent\Factories\HasFactory; - use PDO; class Event extends AbstractModel { - use HasSlug, HasRevisions, HasApiRelations, HasMedias, HasMediasEloquent, HasBlocks, HasRecurrentDates, Transformable, HasFactory; + use HasSlug; + use HasRevisions; + use HasApiRelations; + use HasMedias; + use HasMediasEloquent; + use HasBlocks; + use HasRecurrentDates; + use Transformable; + use HasFactory; protected $presenterAdmin = 'App\Presenters\Admin\EventPresenter'; protected $presenter = 'App\Presenters\Admin\EventPresenter'; @@ -93,16 +99,16 @@ class Event extends AbstractModel /** * Dropdown does not accept null keys; use big numbers */ - const NULL_OPTION = 42; - const NULL_OPTION_AFFILIATE_GROUP = 1024; - const NULL_OPTION_EVENT_HOST = 1024; + public const NULL_OPTION = 42; + public const NULL_OPTION_AFFILIATE_GROUP = 1024; + public const NULL_OPTION_EVENT_HOST = 1024; - const CLASSES_AND_WORKSHOPS = 1; + public const CLASSES_AND_WORKSHOPS = 1; // const LIVE_ARTS = 2; - const SCREENINGS = 3; - const SPECIAL_EVENT = 4; - const TALKS = 5; - const TOUR = 6; + public const SCREENINGS = 3; + public const SPECIAL_EVENT = 4; + public const TALKS = 5; + public const TOUR = 6; // const COMMUNITIES = 7; public static $eventTypes = [ @@ -115,13 +121,13 @@ class Event extends AbstractModel // self::COMMUNITIES => 'Programs in Communities', ]; - const FAMILIES = 1; - const MEMBERS = 2; - const ADULTS = 3; - const TEENS = 4; - const RESEARCHERS_SCHOLARS = 5; - const TEACHERS = 6; - const LUMINARY = 8; + public const FAMILIES = 1; + public const MEMBERS = 2; + public const ADULTS = 3; + public const TEENS = 4; + public const RESEARCHERS_SCHOLARS = 5; + public const TEACHERS = 6; + public const LUMINARY = 8; public static $eventAudiences = [ self::ADULTS => 'General Public', @@ -133,22 +139,22 @@ class Event extends AbstractModel self::RESEARCHERS_SCHOLARS => 'Researchers/Scholars', ]; - const BASIC_LAYOUT = 0; - const LARGE_LAYOUT = 1; + public const BASIC_LAYOUT = 0; + public const LARGE_LAYOUT = 1; public static $eventLayouts = [ self::BASIC_LAYOUT => 'Basic', self::LARGE_LAYOUT => 'Large Feature', ]; - const MICHIGAN_AVE = 1; - const MODERN_WING = 2; - const COLUMBUS_DRIVE = 3; - const NORTH_GARDEN = 4; - const PRITZKER_GARDEN = 5; - const SOUTH_GARDEN = 6; - const OFF_SITE = 7; - const WEST_BOX = 8; + public const MICHIGAN_AVE = 1; + public const MODERN_WING = 2; + public const COLUMBUS_DRIVE = 3; + public const NORTH_GARDEN = 4; + public const PRITZKER_GARDEN = 5; + public const SOUTH_GARDEN = 6; + public const OFF_SITE = 7; + public const WEST_BOX = 8; public static $eventEntrances = [ self::MICHIGAN_AVE => 'Michigan Avenue', @@ -1040,12 +1046,14 @@ protected function transformMappingInternal() $emailSeriesPivots = $this->emailSeries->pluck('pivot'); return $emailSeriesPivots->each(function ($item) use ($eventHostTitle) { - foreach ([ + foreach ( + [ 'affiliate_copy', 'member_copy', 'luminary_copy', 'nonmember_copy', - ] as $field) { + ] as $field + ) { if (isset($item->{$field})) { if (isset($eventHostTitle)) { $item->{$field} = str_replace( diff --git a/app/Models/EventProgram.php b/app/Models/EventProgram.php index be2377fc3..8bbb073fb 100644 --- a/app/Models/EventProgram.php +++ b/app/Models/EventProgram.php @@ -6,7 +6,8 @@ class EventProgram extends AbstractModel { - use Transformable, HasFactory; + use Transformable; + use HasFactory; protected $fillable = [ 'name', diff --git a/app/Models/Exhibition.php b/app/Models/Exhibition.php index 04e01a4b1..0d6a07c14 100644 --- a/app/Models/Exhibition.php +++ b/app/Models/Exhibition.php @@ -16,7 +16,16 @@ class Exhibition extends AbstractModel { - use HasRevisions, HasSlug, HasMedias, HasMediasEloquent, HasBlocks, HasApiModel, Transformable, HasRelated, HasApiRelations, HasFeaturedRelated; + use HasRevisions; + use HasSlug; + use HasMedias; + use HasMediasEloquent; + use HasBlocks; + use HasApiModel; + use Transformable; + use HasRelated; + use HasApiRelations; + use HasFeaturedRelated; protected $apiModel = 'App\Models\Api\Exhibition'; @@ -25,13 +34,13 @@ class Exhibition extends AbstractModel 'deleted' => \App\Events\UpdateExhibition::class, ]; - const BASIC = 0; - const LARGE = 1; - const SPECIAL = 2; + public const BASIC = 0; + public const LARGE = 1; + public const SPECIAL = 2; - const OPEN = 'Open'; - const CLOSED = 'Closed'; - const ONGOING = 'Ongoing'; + public const OPEN = 'Open'; + public const CLOSED = 'Closed'; + public const ONGOING = 'Ongoing'; protected $fillable = [ 'published', @@ -290,7 +299,6 @@ protected function transformMappingInternal() public function getIsFeaturedAttribute() { - // @see ExhibitionsController::index and relations on Page model $page = Page::forType('Exhibitions and Events')->with('apiElements')->first(); diff --git a/app/Models/ExhibitionPressRoom.php b/app/Models/ExhibitionPressRoom.php index fffe5ccec..539ce78ee 100644 --- a/app/Models/ExhibitionPressRoom.php +++ b/app/Models/ExhibitionPressRoom.php @@ -11,7 +11,12 @@ class ExhibitionPressRoom extends AbstractModel { - use HasBlocks, HasSlug, HasMedias, HasFiles, HasRevisions, HasMediasEloquent; + use HasBlocks; + use HasSlug; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasMediasEloquent; protected $fillable = [ 'listing_description', diff --git a/app/Models/Experience.php b/app/Models/Experience.php index 97e3aebdd..89483a935 100644 --- a/app/Models/Experience.php +++ b/app/Models/Experience.php @@ -17,7 +17,15 @@ class Experience extends AbstractModel implements Sortable { - use HasBlocks, HasSlug, HasMedias, HasFiles, HasRevisions, HasPosition, Transformable, HasUnlisted, HasAuthors; + use HasBlocks; + use HasSlug; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasPosition; + use Transformable; + use HasUnlisted; + use HasAuthors; protected $presenter = 'App\Presenters\Admin\ExperiencePresenter'; protected $presenterAdmin = 'App\Presenters\Admin\ExperiencePresenter'; @@ -131,11 +139,10 @@ public function defaultCmsImage($params = []) if ($this->hasImage('thumbnail')) { return $this->image('thumbnail'); } - $attract_slide = $this->slides()->where('module_type', 'attract')->first(); - $attract_image = $attract_slide ? $attract_slide->attractExperienceImages()->first() : null; - - return $attract_image ? $attract_image->cmsImage('experience_image', 'default', $params) : ''; + $attract_slide = $this->slides()->where('module_type', 'attract')->first(); + $attract_image = $attract_slide ? $attract_slide->attractExperienceImages()->first() : null; + return $attract_image ? $attract_image->cmsImage('experience_image', 'default', $params) : ''; } public function slides() diff --git a/app/Models/ExperienceImage.php b/app/Models/ExperienceImage.php index 818451271..340d87cb5 100644 --- a/app/Models/ExperienceImage.php +++ b/app/Models/ExperienceImage.php @@ -11,7 +11,11 @@ class ExperienceImage extends AbstractModel implements Sortable { - use HasBlocks, HasMedias, HasFiles, HasRevisions, HasPosition; + use HasBlocks; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasPosition; protected $fillable = [ 'published', diff --git a/app/Models/ExperienceModal.php b/app/Models/ExperienceModal.php index 27bbe51ec..747eeabf0 100644 --- a/app/Models/ExperienceModal.php +++ b/app/Models/ExperienceModal.php @@ -11,7 +11,11 @@ class ExperienceModal extends AbstractModel implements Sortable { - use HasBlocks, HasMedias, HasFiles, HasRevisions, HasPosition; + use HasBlocks; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasPosition; protected $fillable = [ 'published', diff --git a/app/Models/Family.php b/app/Models/Family.php index 676122df7..0a3caeaf7 100644 --- a/app/Models/Family.php +++ b/app/Models/Family.php @@ -7,7 +7,8 @@ class Family extends AbstractModel { - use HasMedias, HasMediasEloquent; + use HasMedias; + use HasMediasEloquent; protected $fillable = [ 'published', diff --git a/app/Models/Fee.php b/app/Models/Fee.php index e4400fb6d..b6166c69d 100644 --- a/app/Models/Fee.php +++ b/app/Models/Fee.php @@ -20,12 +20,12 @@ class Fee extends AbstractModel */ public $checkboxes = []; - public function fee_age() + public function fee_age() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { return $this->belongsTo('App\Models\FeeAge'); } - public function fee_category() + public function fee_category() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { return $this->belongsTo('App\Models\FeeCategory'); } diff --git a/app/Models/Form/FormModel.php b/app/Models/Form/FormModel.php index d81635e56..c407ce16e 100644 --- a/app/Models/Form/FormModel.php +++ b/app/Models/Form/FormModel.php @@ -3,7 +3,6 @@ namespace App\Models\Form; use Illuminate\Database\Eloquent\Model; - use Carbon\Carbon; class FormModel extends Model diff --git a/app/Models/Gallery.php b/app/Models/Gallery.php index de15813a2..05d4caf7f 100644 --- a/app/Models/Gallery.php +++ b/app/Models/Gallery.php @@ -8,7 +8,9 @@ class Gallery extends AbstractModel { - use HasApiModel, Transformable, HasMedias; + use HasApiModel; + use Transformable; + use HasMedias; protected $apiModel = 'App\Models\Api\Gallery'; diff --git a/app/Models/GenericPage.php b/app/Models/GenericPage.php index 08507eed1..9d169e027 100644 --- a/app/Models/GenericPage.php +++ b/app/Models/GenericPage.php @@ -17,7 +17,18 @@ class GenericPage extends AbstractModel implements Sortable { - use HasMediasEloquent, HasBlocks, HasSlug, HasMedias, HasFiles, HasRevisions, HasPosition, NodeTrait, Transformable, HasRelated, HasApiRelations, HasFeaturedRelated; + use HasMediasEloquent; + use HasBlocks; + use HasSlug; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasPosition; + use NodeTrait; + use Transformable; + use HasRelated; + use HasApiRelations; + use HasFeaturedRelated; protected $fillable = [ 'short_description', @@ -54,18 +65,6 @@ class GenericPage extends AbstractModel implements Sortable protected $presenter = 'App\Presenters\Admin\GenericPresenter'; protected $presenterAdmin = 'App\Presenters\Admin\GenericPresenter'; - /** - * WEB-1522: Add "publication navigation" to `/journal`. - */ - public function __construct(array $attributes = []) - { - if (request()->is('journal')) { - $this->presenter = $this->presenterAdmin = 'App\Presenters\Admin\JournalPresenter'; - } - - parent::__construct(...func_get_args()); - } - /** * Required by the HasMedias trait */ diff --git a/app/Models/Highlight.php b/app/Models/Highlight.php index 1d34bb77e..39e265fba 100644 --- a/app/Models/Highlight.php +++ b/app/Models/Highlight.php @@ -18,7 +18,18 @@ class Highlight extends AbstractModel { - use HasSlug, HasRevisions, HasPosition, HasMedias, HasMediasEloquent, HasBlocks, Transformable, HasRelated, HasApiRelations, HasFeaturedRelated, HasUnlisted, HasAuthors; + use HasSlug; + use HasRevisions; + use HasPosition; + use HasMedias; + use HasMediasEloquent; + use HasBlocks; + use Transformable; + use HasRelated; + use HasApiRelations; + use HasFeaturedRelated; + use HasUnlisted; + use HasAuthors; protected $presenterAdmin = 'App\Presenters\Admin\HighlightPresenter'; protected $presenter = 'App\Presenters\Admin\HighlightPresenter'; @@ -44,8 +55,8 @@ class Highlight extends AbstractModel 'title', ]; - const NORMAL = 0; - const AUDIO_TOUR = 1; + public const NORMAL = 0; + public const AUDIO_TOUR = 1; public static $highlightTypes = [ self::NORMAL => 'Normal', diff --git a/app/Models/HomeArtist.php b/app/Models/HomeArtist.php index 925c53ff8..b4bcbdbd2 100644 --- a/app/Models/HomeArtist.php +++ b/app/Models/HomeArtist.php @@ -5,14 +5,17 @@ use A17\Twill\Models\Behaviors\HasMedias; use A17\Twill\Models\Behaviors\HasPosition; use A17\Twill\Models\Behaviors\Sortable; - use App\Models\Behaviors\HasApiRelations; use App\Models\Behaviors\HasMediasEloquent; use App\Models\Behaviors\HasRelated; class HomeArtist extends AbstractModel implements Sortable { - use HasMedias, HasPosition, HasApiRelations, HasMediasEloquent, HasRelated; + use HasMedias; + use HasPosition; + use HasApiRelations; + use HasMediasEloquent; + use HasRelated; protected $fillable = [ 'published', diff --git a/app/Models/HomeFeature.php b/app/Models/HomeFeature.php index 29577a030..fdeb92aae 100644 --- a/app/Models/HomeFeature.php +++ b/app/Models/HomeFeature.php @@ -10,7 +10,11 @@ class HomeFeature extends AbstractModel { - use HasMedias, HasBlocks, HasApiRelations, HasMediasEloquent, HasFiles; + use HasMedias; + use HasBlocks; + use HasApiRelations; + use HasMediasEloquent; + use HasFiles; protected $fillable = [ 'title', @@ -37,13 +41,20 @@ class HomeFeature extends AbstractModel 'hero' => [ 'default' => [ [ - 'name' => 'landscape', + 'name' => 'default', 'ratio' => 16 / 9, ], ], ], + 'mobile_hero' => [ + 'default' => [ + [ + 'name' => 'default', + 'ratio' => 1, + ], + ] + ] ]; - /** * A list of file roles */ @@ -98,6 +109,7 @@ public function enclosedItem() // Assign image and video to the actual item. Fallback to the element image if no image has been selected. $item->featureImage = $this->featureImage ?? $item->imageFront('hero'); + $item->featureImageMobile = $this->featureImageMobile ?? $item->imageFront('mobile_hero'); $item->videoFront = $this->videoFront($item->featureImage); // Generalize the article tag @@ -113,6 +125,11 @@ public function getFeatureImageAttribute() return $this->imageFront('hero'); } + public function getFeatureImageMobileAttribute() + { + return $this->imageFront('mobile_hero'); + } + public function getVideoFrontAttribute() { return $this->videoFront(); diff --git a/app/Models/Hour.php b/app/Models/Hour.php index f879831b7..7d3b2e237 100644 --- a/app/Models/Hour.php +++ b/app/Models/Hour.php @@ -7,7 +7,8 @@ class Hour extends AbstractModel { - use Transformable, HasFactory; + use Transformable; + use HasFactory; protected $presenter = 'App\Presenters\HoursPresenter'; protected $presenterAdmin = 'App\Presenters\HoursPresenter'; diff --git a/app/Models/InteractiveFeature.php b/app/Models/InteractiveFeature.php index ca0adfb2a..6d950e068 100644 --- a/app/Models/InteractiveFeature.php +++ b/app/Models/InteractiveFeature.php @@ -12,7 +12,14 @@ class InteractiveFeature extends AbstractModel { - use HasRevisions, HasSlug, HasMedias, HasMediasEloquent, HasBlocks, HasApiRelations, Transformable, HasRelated; + use HasRevisions; + use HasSlug; + use HasMedias; + use HasMediasEloquent; + use HasBlocks; + use HasApiRelations; + use Transformable; + use HasRelated; //protected $apiModel = 'App\Models\Api\DigitalLabel'; diff --git a/app/Models/Issue.php b/app/Models/Issue.php deleted file mode 100644 index 4caa8dbc8..000000000 --- a/app/Models/Issue.php +++ /dev/null @@ -1,233 +0,0 @@ - [ - 'default' => [ - [ - 'name' => 'default', - 'ratio' => 21 / 9, - ], - ], - ], - 'mobile_hero' => [ - 'default' => [ - [ - 'name' => 'default', - 'ratio' => 1, - ], - ], - ], - 'license' => [ - 'default' => [ - [ - 'name' => 'default', - 'ratio' => 16 / 9, - ], - ], - ], - ]; - - public function articles() - { - return $this->hasMany('App\Models\IssueArticle', 'issue_id'); - } - - /** - * Generates the id-slug type of URL - */ - public function getRouteKeyName() - { - return 'issue_slug'; - } - - public function getIssueSlugAttribute() - { - return join('/', [$this->issue_number, $this->getSlug()]); - } - - /** - * PUB-146: Affects what _m-listing is used for Writings landing - */ - public function getTypeAttribute() - { - return 'journal-issue'; - } - - /** - * PUB-146: Affects the tag on Writings landing - */ - public function getSubtypeAttribute() - { - return 'Issue ' . $this->issue_number; - } - - protected function transformMappingInternal() - { - return [ - [ - 'name' => 'title', - 'doc' => 'Title', - 'type' => 'string', - 'value' => function () { - return $this->title; - }, - ], - [ - 'name' => 'published', - 'doc' => 'Published', - 'type' => 'boolean', - 'value' => function () { - return $this->published; - }, - ], - [ - 'name' => 'publish_start_date', - 'doc' => 'Publish Start Date', - 'type' => 'datetime', - 'value' => function () { - return $this->publish_start_date; - } - ], - [ - 'name' => 'date', - 'doc' => 'Date', - 'type' => 'date', - 'value' => function () { - return $this->date; - }, - ], - [ - 'name' => 'copy', - 'doc' => 'Copy', - 'type' => 'text', - 'value' => function () { - return $this->blocks; - }, - ], - [ - 'name' => 'slug', - 'doc' => 'Slug', - 'type' => 'string', - 'value' => function () { - return $this->slug; - }, - ], - [ - 'name' => 'web_url', - 'doc' => 'Web URL', - 'type' => 'string', - 'value' => function () { - return url(route('issues.show', $this)); - }, - ], - [ - 'name' => 'heading', - 'doc' => 'Heading', - 'type' => 'string', - 'value' => function () { - return $this->header_text; - }, - ], - [ - 'name' => 'list_description', - 'doc' => 'List description', - 'type' => 'string', - 'value' => function () { - return $this->list_description; - }, - ], - [ - 'name' => 'issue_number', - 'doc' => 'Issue number', - 'type' => 'integer', - 'value' => function () { - return $this->issue_number; - }, - ], - [ - 'name' => 'license_text', - 'doc' => 'License text', - 'type' => 'string', - 'value' => function () { - return $this->license_text; - }, - ], - [ - 'name' => 'hero_caption', - 'doc' => 'Hero caption', - 'type' => 'string', - 'value' => function () { - return $this->hero_caption; - }, - ], - [ - 'name' => 'cite_as', - 'doc' => 'Cite as', - 'type' => 'string', - 'value' => function () { - return $this->cite_as; - }, - ], - [ - 'name' => 'welcome_note_display', - 'doc' => 'Welcome note', - 'type' => 'string', - 'value' => function () { - return $this->welcome_note_display; - }, - ], - ]; - } -} diff --git a/app/Models/IssueArticle.php b/app/Models/IssueArticle.php deleted file mode 100644 index 66ecd7bfc..000000000 --- a/app/Models/IssueArticle.php +++ /dev/null @@ -1,284 +0,0 @@ - [ - 'default' => [ - [ - 'name' => 'default', - 'ratio' => 16 / 9, - ], - ], - 'special' => [ - [ - 'name' => 'default', - 'ratio' => 21 / 9, - ], - ], - ], - 'mobile_hero' => [ - 'default' => [ - [ - 'name' => 'default', - 'ratio' => 1, - ], - ], - ], - 'license' => [ - 'default' => [ - [ - 'name' => 'default', - 'ratio' => 16 / 9, - ], - ], - ], - ]; - - public function scopePublished($query) - { - parent::scopePublished($query); - - // ...and the parent issue has to be published as well - return $query->whereHas('issue', function ($subquery) { - $subquery->published(); - }); - } - - public function scopeIds($query, $ids = []) - { - return $query->whereIn('id', $ids); - } - - public function getPublishedAttribute() - { - return ($this->issue->isPublished ?? false) && $this->isPublished; - } - - public function issue() - { - return $this->belongsTo('App\Models\Issue'); - } - - /** - * Generates the id-slug type of URL - */ - public function getRouteKeyName() - { - return 'issue_slug'; - } - - public function getIssueSlugAttribute() - { - return join('/', [$this->id, $this->getSlug()]); - } - - public function getUrlAttribute() - { - return route('issue-articles.show', ['id' => $this->id, 'slug' => $this->getSlug()], false); - } - - /** - * PUB-146: Affects what _m-listing is used for Writings landing - */ - public function getTypeAttribute() - { - return 'journal-article'; - } - - /** - * PUB-146: Affects the tag on Writings landing - */ - public function getSubtypeAttribute() - { - return $this->type_display ?? 'Journal Article'; - } - - protected function transformMappingInternal() - { - return [ - [ - 'name' => 'title', - 'doc' => 'Title', - 'type' => 'string', - 'value' => function () { - return $this->title; - }, - ], - [ - 'name' => 'published', - 'doc' => 'Published', - 'type' => 'boolean', - 'value' => function () { - return $this->published; - }, - ], - [ - 'name' => 'publish_start_date', - 'doc' => 'Publish Start Date', - 'type' => 'datetime', - 'value' => function () { - return $this->publish_start_date; - } - ], - [ - 'name' => 'date', - 'doc' => 'Date', - 'type' => 'date', - 'value' => function () { - return $this->date; - }, - ], - [ - 'name' => 'copy', - 'doc' => 'Copy', - 'type' => 'text', - 'value' => function () { - return $this->blocks; - }, - ], - [ - 'name' => 'slug', - 'doc' => 'Slug', - 'type' => 'string', - 'value' => function () { - return $this->slug; - }, - ], - [ - 'name' => 'web_url', - 'doc' => 'Web URL', - 'type' => 'string', - 'value' => function () { - return url(route('issues.show', $this)); - }, - ], - [ - 'name' => 'description', - 'doc' => 'Description', - 'type' => 'string', - 'value' => function () { - return $this->description; - }, - ], - [ - 'name' => 'list_description', - 'doc' => 'List description', - 'type' => 'string', - 'value' => function () { - return $this->list_description; - }, - ], - [ - 'name' => 'issue_id', - 'doc' => 'Issue ID', - 'type' => 'integer', - 'value' => function () { - return $this->issue_id; - }, - ], - [ - 'name' => 'license_text', - 'doc' => 'License text', - 'type' => 'string', - 'value' => function () { - return $this->license_text; - }, - ], - [ - 'name' => 'abstract', - 'doc' => 'Abstract', - 'type' => 'string', - 'value' => function () { - return $this->abstract; - }, - ], - [ - 'name' => 'author_display', - 'doc' => 'Author display', - 'type' => 'string', - 'value' => function () { - return $this->author_display; - }, - ], - [ - 'name' => 'review_status', - 'doc' => 'Review status', - 'type' => 'string', - 'value' => function () { - return $this->review_status; - }, - ], - [ - 'name' => 'cite_as', - 'doc' => 'Cite as', - 'type' => 'string', - 'value' => function () { - return $this->cite_as; - }, - ], - [ - 'name' => 'type_display', - 'doc' => 'Type display', - 'type' => 'string', - 'value' => function () { - return $this->type_display; - }, - ], - ]; - } -} diff --git a/app/Models/Lightbox.php b/app/Models/Lightbox.php index 8cdd8058f..45de589a8 100644 --- a/app/Models/Lightbox.php +++ b/app/Models/Lightbox.php @@ -7,7 +7,8 @@ class Lightbox extends AbstractModel { - use HasMedias, HasMediasEloquent; + use HasMedias; + use HasMediasEloquent; protected $fillable = [ 'published', @@ -58,14 +59,14 @@ class Lightbox extends AbstractModel protected $presenter = 'App\Presenters\Admin\LightboxPresenter'; protected $presenterAdmin = 'App\Presenters\Admin\LightboxPresenter'; - const GEOTARGET_ALL = 1; - const GEOTARGET_LOCAL = 2; - const GEOTARGET_NOT_LOCAL = 3; + public const GEOTARGET_ALL = 1; + public const GEOTARGET_LOCAL = 2; + public const GEOTARGET_NOT_LOCAL = 3; - const VARIATION_DEFAULT = 1; - const VARIATION_TICKETING = 2; - const VARIATION_EMAIL = 3; - const VARIATION_NEWSLETTER = 4; + public const VARIATION_DEFAULT = 1; + public const VARIATION_TICKETING = 2; + public const VARIATION_EMAIL = 3; + public const VARIATION_NEWSLETTER = 4; public function getVariationClassAttribute() { diff --git a/app/Models/MagazineIssue.php b/app/Models/MagazineIssue.php index c757a8b45..a6bc62da2 100644 --- a/app/Models/MagazineIssue.php +++ b/app/Models/MagazineIssue.php @@ -4,7 +4,6 @@ use A17\Twill\Models\Behaviors\HasSlug; use A17\Twill\Models\Behaviors\HasRevisions; - use App\Models\Behaviors\HasBlocks; use App\Models\Behaviors\HasMedias; use App\Models\Behaviors\HasMediasEloquent; @@ -12,7 +11,12 @@ class MagazineIssue extends AbstractModel { - use HasSlug, HasRevisions, HasBlocks, HasMedias, HasMediasEloquent, HasRelated; + use HasSlug; + use HasRevisions; + use HasBlocks; + use HasMedias; + use HasMediasEloquent; + use HasRelated; protected $presenter = 'App\Presenters\Admin\MagazineIssuePresenter'; protected $presenterAdmin = 'App\Presenters\Admin\MagazineIssuePresenter'; diff --git a/app/Models/MagazineItem.php b/app/Models/MagazineItem.php index b2341f251..a84da0708 100644 --- a/app/Models/MagazineItem.php +++ b/app/Models/MagazineItem.php @@ -18,10 +18,10 @@ class MagazineItem extends Model /** * Aside from custom, these should also be defined in config('twill.block_editor.browser_route_prefixes') */ - const ITEM_TYPE_CUSTOM = 'custom'; - const ITEM_TYPE_ARTICLE = 'articles'; - const ITEM_TYPE_HIGHLIGHT = 'highlights'; - const ITEM_TYPE_EXPERIENCE = 'experiences'; + public const ITEM_TYPE_CUSTOM = 'custom'; + public const ITEM_TYPE_ARTICLE = 'articles'; + public const ITEM_TYPE_HIGHLIGHT = 'highlights'; + public const ITEM_TYPE_EXPERIENCE = 'experiences'; public static function getClassFromType($itemType) { diff --git a/app/Models/Mirador.php b/app/Models/Mirador.php index 014df864b..1403fc146 100644 --- a/app/Models/Mirador.php +++ b/app/Models/Mirador.php @@ -11,7 +11,13 @@ class Mirador extends AbstractModel { - use HasSlug, HasMedias, HasMediasEloquent, HasRevisions, HasFiles, HasBlocks, Transformable; + use HasSlug; + use HasMedias; + use HasMediasEloquent; + use HasRevisions; + use HasFiles; + use HasBlocks; + use Transformable; protected $presenter = 'App\Presenters\Admin\MiradorPresenter'; protected $presenterAdmin = 'App\Presenters\Admin\MiradorPresenter'; @@ -39,8 +45,8 @@ class Mirador extends AbstractModel public $filesParams = ['upload_manifest_file']; - const SINGLE_VIEW = 'single'; - const BOOK_VIEW = 'book'; + public const SINGLE_VIEW = 'single'; + public const BOOK_VIEW = 'book'; public static $viewTypes = [ self::SINGLE_VIEW => 'single', diff --git a/app/Models/Offer.php b/app/Models/Offer.php index 966632ced..b3c59811d 100644 --- a/app/Models/Offer.php +++ b/app/Models/Offer.php @@ -9,7 +9,9 @@ class Offer extends AbstractModel implements Sortable { - use HasMedias, HasMediasEloquent, HasPosition; + use HasMedias; + use HasMediasEloquent; + use HasPosition; protected $fillable = [ 'published', diff --git a/app/Models/Page.php b/app/Models/Page.php index 8fdfba3e3..34f9dbd71 100644 --- a/app/Models/Page.php +++ b/app/Models/Page.php @@ -13,7 +13,14 @@ class Page extends AbstractModel { - use HasSlug, HasRevisions, HasMedias, HasFiles, HasMediasEloquent, HasApiRelations, Transformable, HasRelated; + use HasSlug; + use HasRevisions; + use HasMedias; + use HasFiles; + use HasMediasEloquent; + use HasApiRelations; + use Transformable; + use HasRelated; protected $presenter = 'App\Presenters\Admin\PagePresenter'; @@ -318,7 +325,7 @@ public function locations() return $this->hasMany(Location::class)->orderBy('position'); } - public function dining_hours() + public function dining_hours() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { return $this->hasMany(DiningHour::class)->orderBy('position'); } @@ -333,7 +340,7 @@ public function families() return $this->hasMany(Family::class)->orderBy('position'); } - public function featured_hours() + public function featured_hours() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { return $this->hasMany(FeaturedHour::class)->orderBy('position'); } diff --git a/app/Models/PressRelease.php b/app/Models/PressRelease.php index d897e0d4a..82750752a 100644 --- a/app/Models/PressRelease.php +++ b/app/Models/PressRelease.php @@ -14,7 +14,14 @@ class PressRelease extends AbstractModel { - use HasBlocks, HasSlug, HasMedias, HasFiles, HasRevisions, HasMediasEloquent, Transformable, HasUnlisted; + use HasBlocks; + use HasSlug; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasMediasEloquent; + use Transformable; + use HasUnlisted; protected $fillable = [ 'short_description', @@ -68,7 +75,6 @@ class PressRelease extends AbstractModel /** * A list of file roles */ - public $filesParams = ['attachment']; protected $presenter = 'App\Presenters\Admin\GenericPresenter'; protected $presenterAdmin = 'App\Presenters\Admin\GenericPresenter'; diff --git a/app/Models/PrintedPublication.php b/app/Models/PrintedPublication.php index d84ef3377..2dba87adc 100644 --- a/app/Models/PrintedPublication.php +++ b/app/Models/PrintedPublication.php @@ -12,7 +12,14 @@ class PrintedPublication extends AbstractModel { - use HasBlocks, HasSlug, HasMedias, HasFiles, HasRevisions, HasMediasEloquent, Transformable, HasRelated; + use HasBlocks; + use HasSlug; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasMediasEloquent; + use Transformable; + use HasRelated; protected $fillable = [ 'listing_description', diff --git a/app/Models/ResearchGuide.php b/app/Models/ResearchGuide.php deleted file mode 100644 index 728bcf183..000000000 --- a/app/Models/ResearchGuide.php +++ /dev/null @@ -1,178 +0,0 @@ - [ - 'default' => [ - [ - 'name' => 'landscape', - 'ratio' => 16 / 9, - ], - ], - 'mobile' => [ - [ - 'name' => 'mobile', - 'ratio' => 1, - ], - ], - ], - 'banner' => [ - 'default' => [ - [ - 'name' => 'landscape', - 'ratio' => 200 / 24, - ], - ], - ], - ]; - - public function scopeIds($query, $ids = []) - { - return $query->whereIn('id', $ids); - } - - /** - * Generates the id-slug type of URL - */ - public function getRouteKeyName() - { - return 'id_slug'; - } - - public function getIdSlugAttribute() - { - return join('-', [$this->id, $this->getSlug()]); - } - - public function getUrlWithoutSlugAttribute() - { - return route('collection.resources.research-guides.show', $this->id); - } - - public function getSlugAttribute() - { - return route('collection.resources.research-guides.show', $this); - } - - public function getUrlAttribute() - { - return url(route('collection.resources.research-guides.show', $this->id_slug)); - } - - public function getAdminEditUrlAttribute() - { - return route('admin.collection.research_resources.researchGuides.edit', $this->id); - } - - protected function transformMappingInternal() - { - return [ - [ - 'name' => 'title', - 'doc' => 'Title', - 'type' => 'string', - 'value' => function () { - return $this->title; - } - ], - [ - 'name' => 'web_url', - 'doc' => 'Web URL', - 'type' => 'string', - 'value' => function () { - return url($this->url); - } - ], - [ - 'name' => 'slug', - 'doc' => 'Slug', - 'type' => 'string', - 'value' => function () { - return $this->getSlug(); - } - ], - [ - 'name' => 'listing_description', - 'doc' => 'Listing Description', - 'type' => 'string', - 'value' => function () { - return $this->listing_description; - } - ], - [ - 'name' => 'short_description', - 'doc' => 'Short Description', - 'type' => 'string', - 'value' => function () { - return $this->short_description; - } - ], - [ - 'name' => 'published', - 'doc' => 'Published', - 'type' => 'boolean', - 'value' => function () { - return $this->published; - } - ], - [ - 'name' => 'publish_start_date', - 'doc' => 'Publish Start Date', - 'type' => 'datetime', - 'value' => function () { - return $this->publish_start_date; - } - ], - [ - 'name' => 'publish_end_date', - 'doc' => 'Publish End Date', - 'type' => 'datetime', - 'value' => function () { - return $this->publish_end_date; - } - ], - [ - 'name' => 'content', - 'doc' => 'Content', - 'type' => 'text', - 'value' => function () { - return $this->blocks; - } - ], - ]; - } -} diff --git a/app/Models/ResourceCategory.php b/app/Models/ResourceCategory.php index 83c203ff4..d09bc4727 100644 --- a/app/Models/ResourceCategory.php +++ b/app/Models/ResourceCategory.php @@ -3,10 +3,12 @@ namespace App\Models; use A17\Twill\Models\Behaviors\HasSlug; +use A17\Twill\Models\Behaviors\HasPosition; class ResourceCategory extends AbstractModel { use HasSlug; + use HasPosition; protected $fillable = [ 'name', diff --git a/app/Models/Revisions/IssueArticleRevision.php b/app/Models/Revisions/IssueArticleRevision.php deleted file mode 100644 index 2b2867a43..000000000 --- a/app/Models/Revisions/IssueArticleRevision.php +++ /dev/null @@ -1,10 +0,0 @@ -belongsTo('App\Models\ResearchGuide'); - } -} diff --git a/app/Models/SiteTag.php b/app/Models/SiteTag.php index 98bee1594..aa4c3898e 100644 --- a/app/Models/SiteTag.php +++ b/app/Models/SiteTag.php @@ -6,7 +6,8 @@ class SiteTag extends AbstractModel { - use HasSlug, Transformable; + use HasSlug; + use Transformable; protected $fillable = [ 'name', diff --git a/app/Models/Slide.php b/app/Models/Slide.php index 3c679886f..44a64ddba 100644 --- a/app/Models/Slide.php +++ b/app/Models/Slide.php @@ -13,7 +13,12 @@ class Slide extends AbstractModel implements Sortable { - use HasBlocks, HasSlug, HasMedias, HasFiles, HasRevisions, HasPosition; + use HasBlocks; + use HasSlug; + use HasMedias; + use HasFiles; + use HasRevisions; + use HasPosition; protected $fillable = [ 'published', @@ -160,7 +165,7 @@ public function endBackgroundExperienceImages() return $this->morphMany('App\Models\ExperienceImage', 'imagable')->where('imagable_repeater_name', 'end_bg_experience_image'); } - public function ExperienceModal() + public function experienceModal() { return $this->morphMany('App\Models\ExperienceModal', 'modalble')->where('modalble_repeater_name', 'experience_modal'); } diff --git a/app/Models/Slugs/IssueArticleSlug.php b/app/Models/Slugs/IssueArticleSlug.php deleted file mode 100644 index ae87a96a2..000000000 --- a/app/Models/Slugs/IssueArticleSlug.php +++ /dev/null @@ -1,10 +0,0 @@ -entity->date_block)) { $details[] = [ - 'key' => 'Date', + 'key' => + <<Date  + + + + Dates are not always precisely known, but the Art Institute strives to present this information as consistently and legibly as possible. Dates may be represented as a range that spans decades, centuries, dynasties, or periods and may include qualifiers such as c. (circa) or BCE. + + + VALUE, 'itemprop' => 'dateCreated', 'links' => [[ 'label' => join(' ', [($this->entity->date_qualifier_title ?? ''), $this->entity->date_block]), // @see getDateBlockAttribute @@ -363,6 +374,7 @@ protected function getArtworkDetailsBlock() $details = array_merge($details, $this->formatDetailBlocks([ 'Medium' => [$this->entity->medium_display, 'material'], + 'Edition' => [$this->entity->edition], 'Inscriptions' => [$this->entity->inscriptions], 'Dimensions' => [$this->entity->dimensions, 'size'], 'Credit Line' => [$this->entity->credit_line], @@ -372,16 +384,18 @@ protected function getArtworkDetailsBlock() if ($this->entity->is_public_domain) { $details = array_merge($details, $this->formatDetailBlocks([ - 'IIIF Manifest ' - . '' - . '' - . ' ' - . ' The International Image Interoperability Framework (IIIF) represents a set of open standards that enables rich access to digital media from libraries, archives, museums, and other cultural institutions around the world.

' - . ' Learn more.' - . '
' - . '
' => [$this->getIiifManifestUrl()], + <<IIIF Manifest  + + + + The International Image Interoperability Framework (IIIF) represents a set of open standards that enables rich access to digital media from libraries, archives, museums, and other cultural institutions around the world.

+ Learn more. +
+
+ VALUE => [$this->getIiifManifestUrl()], ])); } @@ -453,13 +467,15 @@ protected function getArtworkAccordionBlocks() ]; } - if ($this->entity->multimediaResources && $this->entity->multimediaResources->isNotEmpty()) { - $resultsByType = $this->entity->multimediaResources->groupBy('api_model')->sortKeys(); + $multimediaResources = $this->entity->multimediaResources; + if ($multimediaResources && $multimediaResources->isNotEmpty()) { + $resultsByType = $multimediaResources->groupBy('api_model')->sortKeys(); $content[] = $this->buildMultimediaBlocks($resultsByType, 'Multimedia'); } - if ($this->entity->educationalResources && $this->entity->educationalResources->isNotEmpty()) { - $resultsByType = $this->entity->educationalResources->groupBy('api_model')->sort(); + $educationalResources = $this->entity->educationalResources; + if ($educationalResources && $educationalResources->isNotEmpty()) { + $resultsByType = $educationalResources->groupBy('api_model')->sort(); $content[] = $this->buildMultimediaBlocks($resultsByType, 'Educational Resources'); } @@ -469,12 +485,11 @@ protected function getArtworkAccordionBlocks() return []; } - return [ - 'type' => 'accordion', - 'content' => $content, - 'titleFont' => 'f-module-title-2' - ]; - + return [ + 'type' => 'accordion', + 'content' => $content, + 'titleFont' => 'f-module-title-2' + ]; } protected function formatDescriptionBlocks($elements) @@ -529,8 +544,9 @@ public function buildSchemaItemProps() ]; if ($this->entity->image_id) { - $itemprops['thumbnailUrl'] = DamsImageService::getBaseUrl() . '2/' . $this->entity->image_id . '/full/200,/0/default.jpg'; - $itemprops['image'] = DamsImageService::getBaseUrl() . '2/' . $this->entity->image_id; + $dams = new DamsImageService(); + $itemprops['thumbnailUrl'] = $dams->getBaseUrl() . '2/' . $this->entity->image_id . '/full/200,/0/default.jpg'; + $itemprops['image'] = $dams->getBaseUrl() . '2/' . $this->entity->image_id; } return $itemprops; diff --git a/app/Presenters/Admin/AuthorPresenter.php b/app/Presenters/Admin/AuthorPresenter.php index 792285d07..1b40b6154 100644 --- a/app/Presenters/Admin/AuthorPresenter.php +++ b/app/Presenters/Admin/AuthorPresenter.php @@ -29,12 +29,12 @@ public function loadRelatedWritings() { $writings = []; - foreach (['articles', 'highlights', 'experiences', 'issueArticles'] as $relation) { + foreach (['articles', 'highlights', 'experiences'] as $relation) { if ($this->{$relation}) { $writings[] = $this->{$relation} ->map(function ($element) use ($relation) { - return $this->_prepWriting($element, $relation); + return $this->prepWriting($element, $relation); }); } } @@ -42,7 +42,7 @@ public function loadRelatedWritings() return $this->writingsCache = collect($writings)->flatten(1)->filter()->sortByDesc('date'); } - private function _prepWriting($element, $type = 'article') + private function prepWriting($element, $type = 'article') { $element->date = $element->date ?? $element->publish_start_date ?? $element->updated_at; $element->writingType = $type; diff --git a/app/Presenters/Admin/BlockPresenter.php b/app/Presenters/Admin/BlockPresenter.php index 20599b859..e99c9426b 100644 --- a/app/Presenters/Admin/BlockPresenter.php +++ b/app/Presenters/Admin/BlockPresenter.php @@ -3,11 +3,8 @@ namespace App\Presenters\Admin; use App\Presenters\BasePresenter; - use App\Libraries\SmartyPants; - use Illuminate\Support\Str; - use DomDocument; use DOMXpath; diff --git a/app/Presenters/Admin/EventPresenter.php b/app/Presenters/Admin/EventPresenter.php index 040f091bf..fce02492f 100644 --- a/app/Presenters/Admin/EventPresenter.php +++ b/app/Presenters/Admin/EventPresenter.php @@ -3,10 +3,8 @@ namespace App\Presenters\Admin; use Carbon\Carbon; - use App\Presenters\BasePresenter; use App\Helpers\ImageHelpers; - use Illuminate\Support\Str; class EventPresenter extends BasePresenter @@ -82,11 +80,10 @@ public function formattedBlockDate() if (!empty($this->entity->forced_date)) { return $this->entity->forced_date; } - // EventRepository::getEventsFiltered() adds this from `event_metas` - if (isset($this->entity->date)) { - return $this->formatDate($this->entity->date); - } - + // EventRepository::getEventsFiltered() adds this from `event_metas` + if (isset($this->entity->date)) { + return $this->formatDate($this->entity->date); + } } public function formattedNextOccurrence() @@ -95,14 +92,13 @@ public function formattedNextOccurrence() return $this->entity->forced_date; } - if ($next = $this->entity->nextOccurrenceExclusive) { - return ''; - } - - if ($last = $this->entity->lastOccurrence) { - return ''; - } + if ($next = $this->entity->nextOccurrenceExclusive) { + return ''; + } + if ($last = $this->entity->lastOccurrence) { + return ''; + } } public function nextOccurrenceDate() diff --git a/app/Presenters/Admin/ExhibitionPresenter.php b/app/Presenters/Admin/ExhibitionPresenter.php index 57870888a..7945f455b 100644 --- a/app/Presenters/Admin/ExhibitionPresenter.php +++ b/app/Presenters/Admin/ExhibitionPresenter.php @@ -109,8 +109,7 @@ public function startAt() return new Carbon($this->entity->aic_start_at); } - return ''; - + return ''; } public function endAt() @@ -123,8 +122,7 @@ public function endAt() return new Carbon($this->entity->aic_end_at); } - return ''; - + return ''; } public function itemprops() @@ -277,11 +275,13 @@ protected function augmented() public function addInjectAttributes($variation = null) { - if (( - date('w') != 2 && date('w') != 3 && date('H') >= 10 && date('H') < 18 - ) && ( - Carbon::now()->between($this->entity->dateStart, $this->dateEnd) - )) { + if ( + ( + date('w') != 2 && date('w') != 3 && date('H') >= 10 && date('H') < 18 + ) && ( + Carbon::now()->between($this->entity->dateStart, $this->dateEnd) + ) + ) { $injectUrl = route('exhibitions.waitTime', [ 'id' => $this->entity->id, 'slug' => $this->entity->getSlug(), diff --git a/app/Presenters/Admin/HighlightPresenter.php b/app/Presenters/Admin/HighlightPresenter.php index 5ae009506..9d3e7f737 100644 --- a/app/Presenters/Admin/HighlightPresenter.php +++ b/app/Presenters/Admin/HighlightPresenter.php @@ -22,8 +22,7 @@ public function type() return $this->entity->type = $this->entity->siteTags->first()->name; } - return 'Highlights'; // For detail header - + return 'Highlights'; // For detail header } public function url() diff --git a/app/Presenters/Admin/IssueArticlePresenter.php b/app/Presenters/Admin/IssueArticlePresenter.php deleted file mode 100644 index 0b58e7347..000000000 --- a/app/Presenters/Admin/IssueArticlePresenter.php +++ /dev/null @@ -1,118 +0,0 @@ -entity->short_title_display ?? $this->entity->title_display ?? $this->entity->title; - } - - public function date() - { - if ($this->entity->date) { - return $this->entity->date->format('M j, Y'); - } - } - - public function issueNumber() - { - if ($this->entity->issue) { - return $this->entity->issue->issue_number; - } - } - - public function issueTitle() - { - if ($this->entity->issue) { - return $this->entity->issue->title_display ?? $this->entity->issue->title; - } - } - - public function listDescription() - { - return strip_tags($this->entity->list_description, ['i']); - } - - public function pdfDownloadPath() - { - if (!isset($this->entity->pdf_download_path)) { - return; - } - - return config('aic.pdf_s3_endpoint') . $this->entity->pdf_download_path; - } - - public function articlesForSidebar() - { - $currentArticle = $this->entity; - - return $this->articlesForSidebar ?? $this->articlesForSidebar = [ - [ - 'title' => 'View other articles', - 'active' => false, - 'blocks' => [ - [ - 'type' => 'link-list', - 'links' => $this->entity - ->issue - ->present() - ->articlesForLanding() - ->map(function ($article) use ($currentArticle) { - return [ - 'label' => $article->title_display ?? $article->title, - 'sublabel' => $article->showAuthors(), - 'href' => $article->url, - 'active' => $article->id === $currentArticle->id, - ]; - }), - ], - ], - ], - ]; - } - - public function getArticleType() - { - if (isset($this->entity->type_display)) { - return $this->entity->type_display; - } - - return 'Article'; - } - - /** - * PUB-146: For `_articleFeature` view on Writings - */ - public function subtype() - { - return $this->getArticleType(); - } - - /** - * PUB-84: For search results - */ - public function subtypeForSearch() - { - return 'Issue ' . $this->issueNumber() . ': ' . $this->entity->issue->title; - } - - public function references() - { - - } - - public function citeAs() - { - if (empty($this->entity->cite_as)) { - return; - } - - return $this->addCssClass($this->entity->cite_as, 'f-secondary'); - } -} diff --git a/app/Presenters/Admin/IssuePresenter.php b/app/Presenters/Admin/IssuePresenter.php deleted file mode 100644 index e41cccc07..000000000 --- a/app/Presenters/Admin/IssuePresenter.php +++ /dev/null @@ -1,25 +0,0 @@ -entity->date) { - return $this->entity->date->format('M j, Y'); - } - } - - public function articlesForLanding() - { - return $this->articlesForLanding ?? $this->articlesForLanding = $this->entity->articles() - ->ordered() - ->published() - ->get(); - } -} diff --git a/app/Presenters/Admin/JournalPresenter.php b/app/Presenters/Admin/JournalPresenter.php deleted file mode 100644 index db08e2eaa..000000000 --- a/app/Presenters/Admin/JournalPresenter.php +++ /dev/null @@ -1,25 +0,0 @@ -entity->title); - } - - public function breadCrumb() - { - return $this->getNav()['breadcrumb'] ?? []; - } - - public function navigation() - { - return $this->getNav()['nav'] ?? []; - } -} diff --git a/app/Presenters/Admin/MagazineIssuePresenter.php b/app/Presenters/Admin/MagazineIssuePresenter.php index d2f1b1fc6..dcb0af127 100644 --- a/app/Presenters/Admin/MagazineIssuePresenter.php +++ b/app/Presenters/Admin/MagazineIssuePresenter.php @@ -6,14 +6,14 @@ class MagazineIssuePresenter extends GenericPresenter { protected $linkIndex = 1; - public function hero_text() + public function hero_text() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { $p = "{<\s*a\s*(.*?)>(.*?)}i"; return preg_replace_callback($p, [$this, 'hero_text_callback'], $this->entity->hero_text); } - private function hero_text_callback($matches) + private function hero_text_callback($matches) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps { $gtmEvent = $matches[2]; // Link text preg_match("{href=\"([a-zA-Z0-9\/\:\?\#\-\_\.]+)\"}i", $matches[1], $urlMatches); diff --git a/app/Presenters/Admin/PagePresenter.php b/app/Presenters/Admin/PagePresenter.php index 865b6acce..c15c21c74 100644 --- a/app/Presenters/Admin/PagePresenter.php +++ b/app/Presenters/Admin/PagePresenter.php @@ -2,15 +2,10 @@ namespace App\Presenters\Admin; -use App\Models\Issue; -use App\Repositories\IssueRepository; - use App\Presenters\BasePresenter; class PagePresenter extends BasePresenter { - private $featuredJournalIssue; - public function introBlocks() { return [ @@ -30,29 +25,4 @@ public function exhibitionHistoryMedia() 'hideCaption' => true ]; } - - public function getFeaturedJournalIssue() - { - return $this->featuredJournalIssue ?? $this->featuredJournalIssue = (new IssueRepository(new Issue()))->getLatestIssue(); - } - - public function getFeaturedJournalArticles() - { - $featuredJournalArticles = $this->entity->getRelated('featuredJournalArticles')->where('published', true); - - if ($featuredJournalArticles->count() > 0) { - return $featuredJournalArticles; - } - - $featuredJournalIssue = $this->getFeaturedJournalIssue(); - - if (!$featuredJournalIssue) { - return; - } - - return $featuredJournalIssue - ->present() - ->articlesForLanding() - ->slice(0, 4); - } } diff --git a/app/Presenters/BasePresenter.php b/app/Presenters/BasePresenter.php index 4e699b122..b02880f8b 100644 --- a/app/Presenters/BasePresenter.php +++ b/app/Presenters/BasePresenter.php @@ -6,7 +6,6 @@ abstract class BasePresenter { - /** * This is to store the original model instance */ diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 356a1043b..9bd9b7330 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -71,8 +71,6 @@ public function registerMorphMap() 'exhibitions' => 'App\Models\Exhibition', 'departments' => 'App\Models\Department', 'blocks' => 'App\Models\Vendor\Block', - - 'issueArticles' => 'App\Models\IssueArticle', ]); } @@ -104,7 +102,7 @@ public function registerDamsImageService() public function registerClosureService() { $this->app->singleton('closureservice', function ($app) { - return new class() { + return new class () { private $checkedForClosure = false; private $cachedClosure; @@ -125,7 +123,7 @@ public function getClosure() public function registerPrintService() { $this->app->singleton('printservice', function ($app) { - return new class() { + return new class () { private $isPrintMode; public function __construct() diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index b604c7a25..78e5f9eec 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -23,6 +23,5 @@ class AuthServiceProvider extends ServiceProvider public function boot() { $this->registerPolicies(); - } } diff --git a/app/Providers/DebugServiceProvider.php b/app/Providers/DebugServiceProvider.php index 74a8cc68e..bf3d8a18e 100644 --- a/app/Providers/DebugServiceProvider.php +++ b/app/Providers/DebugServiceProvider.php @@ -9,7 +9,7 @@ class DebugServiceProvider extends ServiceProvider public function register() { $this->app->singleton('debug', function ($app) { - return new class() { + return new class () { private $output = []; public function log($class, $field, $mutator = false) diff --git a/app/Repositories/Api/ArtistRepository.php b/app/Repositories/Api/ArtistRepository.php index 581fd063c..82b17b8d8 100644 --- a/app/Repositories/Api/ArtistRepository.php +++ b/app/Repositories/Api/ArtistRepository.php @@ -162,7 +162,7 @@ public function getApiRelatedItems($item, $excludedItems = null) ->items(); - $items = array_filter($items, function($value) { + $items = array_filter($items, function ($value) { if ($value->hasAugmentedModel() && $value->getAugmentedModel()) { return $value->getAugmentedModel()->published; } diff --git a/app/Repositories/Api/AssetRepository.php b/app/Repositories/Api/AssetRepository.php index 2e84ef5a8..9ccab35bb 100644 --- a/app/Repositories/Api/AssetRepository.php +++ b/app/Repositories/Api/AssetRepository.php @@ -6,7 +6,7 @@ class AssetRepository extends BaseApiRepository { - const ALL = 100; + public const ALL = 100; public function __construct(Asset $model) { diff --git a/app/Repositories/Api/ExhibitionRepository.php b/app/Repositories/Api/ExhibitionRepository.php index 8f28da897..25172b012 100644 --- a/app/Repositories/Api/ExhibitionRepository.php +++ b/app/Repositories/Api/ExhibitionRepository.php @@ -4,12 +4,11 @@ use App\Models\Api\Exhibition; use App\Repositories\EventRepository; - use App\Models\Api\Search; class ExhibitionRepository extends BaseApiRepository { - const RELATED_EVENTS_PER_PAGE = 3; + public const RELATED_EVENTS_PER_PAGE = 3; public function __construct(Exhibition $model) { diff --git a/app/Repositories/Api/SearchRepository.php b/app/Repositories/Api/SearchRepository.php index 06556512b..13d4e80de 100644 --- a/app/Repositories/Api/SearchRepository.php +++ b/app/Repositories/Api/SearchRepository.php @@ -6,7 +6,7 @@ class SearchRepository extends BaseApiRepository { - const ALL = 100; + public const ALL = 100; public function __construct(Search $model) { diff --git a/app/Repositories/Api/TicketedEventRepository.php b/app/Repositories/Api/TicketedEventRepository.php index 1b7948b7f..af6f27202 100644 --- a/app/Repositories/Api/TicketedEventRepository.php +++ b/app/Repositories/Api/TicketedEventRepository.php @@ -7,7 +7,7 @@ class TicketedEventRepository extends BaseApiRepository { - const TICKETED_EVENTS_PER_PAGE = 20; + public const TICKETED_EVENTS_PER_PAGE = 20; public function __construct(TicketedEvent $model) { diff --git a/app/Repositories/Api/TicketedEventTypeRepository.php b/app/Repositories/Api/TicketedEventTypeRepository.php index 5cafa2b6c..f1dea0667 100644 --- a/app/Repositories/Api/TicketedEventTypeRepository.php +++ b/app/Repositories/Api/TicketedEventTypeRepository.php @@ -7,7 +7,7 @@ class TicketedEventTypeRepository extends BaseApiRepository { - const TICKETED_EVENT_TYPES_PER_PAGE = 100; + public const TICKETED_EVENT_TYPES_PER_PAGE = 100; public function __construct(TicketedEventType $model) { diff --git a/app/Repositories/ArtistRepository.php b/app/Repositories/ArtistRepository.php index 833192605..1bb347823 100644 --- a/app/Repositories/ArtistRepository.php +++ b/app/Repositories/ArtistRepository.php @@ -9,7 +9,8 @@ class ArtistRepository extends BaseApiRepository { - use HandleSlugs, HandleMedias; + use HandleSlugs; + use HandleMedias; public function __construct(Artist $model) { diff --git a/app/Repositories/AuthorRepository.php b/app/Repositories/AuthorRepository.php index 1eda02433..6f4221018 100644 --- a/app/Repositories/AuthorRepository.php +++ b/app/Repositories/AuthorRepository.php @@ -9,7 +9,9 @@ class AuthorRepository extends ModuleRepository { - use HandleSlugs, HandleMedias, HandleRevisions; + use HandleSlugs; + use HandleMedias; + use HandleRevisions; public function __construct(Author $model) { diff --git a/app/Repositories/Behaviors/Handle3DModel.php b/app/Repositories/Behaviors/Handle3DModel.php index c9e5d88a2..24ca3f84d 100644 --- a/app/Repositories/Behaviors/Handle3DModel.php +++ b/app/Repositories/Behaviors/Handle3DModel.php @@ -8,7 +8,8 @@ trait Handle3DModel { private function handle3DModel($object, $fields, $fieldName = 'aic_3d_model') { - if (!empty($fields["{$fieldName}[model_url]"]) + if ( + !empty($fields["{$fieldName}[model_url]"]) && !empty($fields["{$fieldName}[model_id]"]) && !empty($fields["{$fieldName}[camera_position]"]) && !empty($fields["{$fieldName}[camera_target]"]) @@ -39,9 +40,11 @@ private function handle3DModel($object, $fields, $fieldName = 'aic_3d_model') private function getFormFieldsFor3DModel($object, $fields, $fieldName = 'aic_3d_model') { // Render the 3d model field in repeater block - if ($object instanceof \App\Models\Slide && - $object->secondaryExperienceModal->first() && - $model3d = $object->secondaryExperienceModal->first()->model3d) { + if ( + $object instanceof \App\Models\Slide && + $object->secondaryExperienceModal->first() && + $model3d = $object->secondaryExperienceModal->first()->model3d + ) { $secondaryExperienceModal = $object->secondaryExperienceModal->first(); $aic3dFields = ['model_url', 'model_id', 'model_caption_title', 'model_caption', 'camera_position', 'guided_tour', 'camera_target', 'annotation_list', 'hide_annotation', 'hide_annotation_title']; diff --git a/app/Repositories/Behaviors/HandleApiBlocks.php b/app/Repositories/Behaviors/HandleApiBlocks.php index dfec694a6..0b02c87ee 100644 --- a/app/Repositories/Behaviors/HandleApiBlocks.php +++ b/app/Repositories/Behaviors/HandleApiBlocks.php @@ -34,13 +34,15 @@ protected function getBlockBrowsers($block) } // WEB-2271: Refactor me! - if ((( - !isset($data['thumbnail']) - ) || ( - isset($data['thumbnail']) && $data['thumbnail'] === ImageService::getTransparentFallbackUrl(['w' => 100, 'h' => 100]) - )) && ( - classHasTrait($relatedElement, \App\Models\Behaviors\HasMediasApi::class) - )) { + if ( + (( + !isset($data['thumbnail']) + ) || ( + isset($data['thumbnail']) && $data['thumbnail'] === ImageService::getTransparentFallbackUrl(['w' => 100, 'h' => 100]) + )) && ( + classHasTrait($relatedElement, \App\Models\Behaviors\HasMediasApi::class) + ) + ) { $data['thumbnail'] = $relatedElement->defaultCmsImage(['w' => 100, 'h' => 100]); } } else { @@ -85,7 +87,6 @@ protected function getModelRepository($relation, $model = null) return app($apiRepo); } - return app(config('twill.namespace') . '\\Repositories\\' . ucfirst($model) . 'Repository'); - + return app(config('twill.namespace') . '\\Repositories\\' . ucfirst($model) . 'Repository'); } } diff --git a/app/Repositories/Behaviors/HandleApiRelations.php b/app/Repositories/Behaviors/HandleApiRelations.php index 6929bf824..d1959bce3 100644 --- a/app/Repositories/Behaviors/HandleApiRelations.php +++ b/app/Repositories/Behaviors/HandleApiRelations.php @@ -154,7 +154,7 @@ public function getFormFieldsForMultiBrowserApi($object, $browser_name, $apiMode $data['thumbnail'] = $apiElement->getAugmentedModel()->defaultCmsImage(['w' => 100, 'h' => 100]); } } - // WEB-1187: Add augment route here! + // WEB-1187: Add augment route here! return [ 'id' => $apiElement->id, diff --git a/app/Repositories/DepartmentRepository.php b/app/Repositories/DepartmentRepository.php index 4c5e8c09c..44b3d8388 100644 --- a/app/Repositories/DepartmentRepository.php +++ b/app/Repositories/DepartmentRepository.php @@ -9,7 +9,8 @@ class DepartmentRepository extends BaseApiRepository { - use HandleMedias, HandleApiRelations; + use HandleMedias; + use HandleApiRelations; protected $apiBrowsers = [ 'customRelatedArtworks' => [ diff --git a/app/Repositories/DigitalPublicationRepository.php b/app/Repositories/DigitalPublicationRepository.php index 7e6fb83f9..d4ab36a6e 100644 --- a/app/Repositories/DigitalPublicationRepository.php +++ b/app/Repositories/DigitalPublicationRepository.php @@ -11,7 +11,11 @@ class DigitalPublicationRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; protected $relatedBrowsers = [ 'welcome_note_section' => [ diff --git a/app/Repositories/DiningHourRepository.php b/app/Repositories/DiningHourRepository.php index c045ebaf1..98be899ad 100644 --- a/app/Repositories/DiningHourRepository.php +++ b/app/Repositories/DiningHourRepository.php @@ -8,7 +8,8 @@ class DiningHourRepository extends ModuleRepository { - use HandleMedias, HandleTranslations; + use HandleMedias; + use HandleTranslations; public function __construct(DiningHour $model) { diff --git a/app/Repositories/EducatorResourceRepository.php b/app/Repositories/EducatorResourceRepository.php index b5721fd2e..bc929887d 100644 --- a/app/Repositories/EducatorResourceRepository.php +++ b/app/Repositories/EducatorResourceRepository.php @@ -7,9 +7,9 @@ use A17\Twill\Repositories\Behaviors\HandleMedias; use A17\Twill\Repositories\Behaviors\HandleRevisions; use A17\Twill\Repositories\Behaviors\HandleSlugs; -use App\Models\EducatorResource; - use App\Repositories\Behaviors\HandleApiBlocks; +use App\Models\EducatorResource; +use App\Models\Api\Search; class EducatorResourceRepository extends ModuleRepository { @@ -43,4 +43,13 @@ public function getShowData($item, $slug = null, $previewPage = null) 'page' => $item, ]; } + + public function searchApi($string, $perPage = null, $page = null, $columns = []) + { + $search = Search::query()->search($string)->published()->resources(['educator-resources']); + + $results = $search->getSearch($perPage, $columns, null, $page); + + return $results; + } } diff --git a/app/Repositories/EventRepository.php b/app/Repositories/EventRepository.php index bd51f02d4..a810de147 100644 --- a/app/Repositories/EventRepository.php +++ b/app/Repositories/EventRepository.php @@ -214,7 +214,7 @@ public function getEventsFiltered($start = null, $end = null, $time = null, $typ case 'weekend': $query->weekend(); - break; + break; default: if ($audience || $type) { $query->sixMonths(); @@ -222,7 +222,7 @@ public function getEventsFiltered($start = null, $end = null, $time = null, $typ $query->default(); } - break; + break; } } diff --git a/app/Repositories/ExhibitionPressRoomRepository.php b/app/Repositories/ExhibitionPressRoomRepository.php index 5c4b52064..7a5a1e508 100644 --- a/app/Repositories/ExhibitionPressRoomRepository.php +++ b/app/Repositories/ExhibitionPressRoomRepository.php @@ -11,7 +11,11 @@ class ExhibitionPressRoomRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; public function __construct(ExhibitionPressRoom $model) { diff --git a/app/Repositories/ExhibitionRepository.php b/app/Repositories/ExhibitionRepository.php index 27561373c..9edd45fd5 100644 --- a/app/Repositories/ExhibitionRepository.php +++ b/app/Repositories/ExhibitionRepository.php @@ -6,7 +6,6 @@ use A17\Twill\Repositories\Behaviors\HandleBlocks; use A17\Twill\Repositories\Behaviors\HandleMedias; use A17\Twill\Repositories\Behaviors\HandleRevisions; - use App\Repositories\Behaviors\HandleApiBlocks; use App\Repositories\Behaviors\HandleFeaturedRelated; use App\Models\Exhibition; diff --git a/app/Repositories/ExperienceImageRepository.php b/app/Repositories/ExperienceImageRepository.php index 71331aed2..27558f1f2 100644 --- a/app/Repositories/ExperienceImageRepository.php +++ b/app/Repositories/ExperienceImageRepository.php @@ -11,7 +11,10 @@ class ExperienceImageRepository extends ModuleRepository { - use HandleBlocks, HandleMedias, HandleFiles, HandleRevisions; + use HandleBlocks; + use HandleMedias; + use HandleFiles; + use HandleRevisions; public function __construct(ExperienceImage $model) { diff --git a/app/Repositories/ExperienceModalRepository.php b/app/Repositories/ExperienceModalRepository.php index 01c639c92..78eb14c83 100644 --- a/app/Repositories/ExperienceModalRepository.php +++ b/app/Repositories/ExperienceModalRepository.php @@ -12,7 +12,12 @@ class ExperienceModalRepository extends ModuleRepository { - use HandleBlocks, HandleMedias, HandleFiles, HandleRevisions, HandleExperienceModule, Handle3DModel; + use HandleBlocks; + use HandleMedias; + use HandleFiles; + use HandleRevisions; + use HandleExperienceModule; + use Handle3DModel; public function __construct(ExperienceModal $model) { diff --git a/app/Repositories/ExperienceRepository.php b/app/Repositories/ExperienceRepository.php index 5dee3f945..ce0e8dca6 100644 --- a/app/Repositories/ExperienceRepository.php +++ b/app/Repositories/ExperienceRepository.php @@ -15,7 +15,14 @@ class ExperienceRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions, HandleExperienceModule, HandleMagazine, HandleAuthors; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; + use HandleExperienceModule; + use HandleMagazine; + use HandleAuthors; protected $morphType = 'experiences'; diff --git a/app/Repositories/FamilyRepository.php b/app/Repositories/FamilyRepository.php index 644c5b8fc..5a3c57cef 100644 --- a/app/Repositories/FamilyRepository.php +++ b/app/Repositories/FamilyRepository.php @@ -8,7 +8,8 @@ class FamilyRepository extends ModuleRepository { - use HandleTranslations, HandleMedias; + use HandleTranslations; + use HandleMedias; public function __construct(Family $model) { diff --git a/app/Repositories/HighlightRepository.php b/app/Repositories/HighlightRepository.php index 99d850bf3..87efc17b5 100644 --- a/app/Repositories/HighlightRepository.php +++ b/app/Repositories/HighlightRepository.php @@ -6,10 +6,8 @@ use A17\Twill\Repositories\Behaviors\HandleMedias; use A17\Twill\Repositories\Behaviors\HandleRevisions; use A17\Twill\Repositories\Behaviors\HandleSlugs; - use App\Models\Highlight; use App\Models\Api\Search; - use App\Repositories\Behaviors\HandleApiRelations; use App\Repositories\Behaviors\HandleApiBlocks; use App\Repositories\Behaviors\HandleFeaturedRelated; diff --git a/app/Repositories/HomeArtistRepository.php b/app/Repositories/HomeArtistRepository.php index 3c0ae4e3c..d829b85e6 100644 --- a/app/Repositories/HomeArtistRepository.php +++ b/app/Repositories/HomeArtistRepository.php @@ -3,13 +3,13 @@ namespace App\Repositories; use A17\Twill\Repositories\Behaviors\HandleMedias; - use App\Models\HomeArtist; use App\Repositories\Behaviors\HandleApiRelations; class HomeArtistRepository extends ModuleRepository { - use HandleMedias, HandleApiRelations; + use HandleMedias; + use HandleApiRelations; protected $apiBrowsers = [ 'artists' => [ diff --git a/app/Repositories/InteractiveFeatureRepository.php b/app/Repositories/InteractiveFeatureRepository.php index 6df016a2d..1505ccc84 100644 --- a/app/Repositories/InteractiveFeatureRepository.php +++ b/app/Repositories/InteractiveFeatureRepository.php @@ -11,7 +11,10 @@ class InteractiveFeatureRepository extends ModuleRepository { - use HandleSlugs, HandleRevisions, HandleMedias, HandleBlocks; + use HandleSlugs; + use HandleRevisions; + use HandleMedias; + use HandleBlocks; public function __construct(InteractiveFeature $model) { diff --git a/app/Repositories/IssueArticleRepository.php b/app/Repositories/IssueArticleRepository.php deleted file mode 100644 index 0e8a72b01..000000000 --- a/app/Repositories/IssueArticleRepository.php +++ /dev/null @@ -1,30 +0,0 @@ -model = $model; - } - - public function afterSave($object, $fields) - { - parent::afterSave($object, $fields); - GeneratePdf::dispatch($object); - } -} diff --git a/app/Repositories/IssueRepository.php b/app/Repositories/IssueRepository.php deleted file mode 100644 index 2a859a1df..000000000 --- a/app/Repositories/IssueRepository.php +++ /dev/null @@ -1,40 +0,0 @@ - [ - 'relation' => 'welcome_note_article' - ] - ]; - - public function __construct(Issue $model) - { - $this->model = $model; - } - - public function getLatestIssue() - { - return Issue::query()->published()->orderBy('date', 'desc')->first(); - } - - public function getWelcomeNote($item) - { - $welcomeNotes = $item->getRelated('welcome_note_article'); - - if (!config('aic.is_preview_mode')) { - $welcomeNotes = $welcomeNotes->where('published', true); - } - - return $welcomeNotes->first(); - } -} diff --git a/app/Repositories/MiradorRepository.php b/app/Repositories/MiradorRepository.php index e96dac835..1ba9331f2 100644 --- a/app/Repositories/MiradorRepository.php +++ b/app/Repositories/MiradorRepository.php @@ -12,7 +12,11 @@ class MiradorRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; public function __construct(Mirador $model) { diff --git a/app/Repositories/ModuleRepository.php b/app/Repositories/ModuleRepository.php index 975ef06f2..d76653fe6 100644 --- a/app/Repositories/ModuleRepository.php +++ b/app/Repositories/ModuleRepository.php @@ -4,20 +4,19 @@ use A17\Twill\Repositories\ModuleRepository as BaseModuleRepository; use A17\Twill\Repositories\Behaviors\HandleRelatedBrowsers; - use App\Repositories\Behaviors\HandleApiBrowsers; use App\Helpers\StringHelpers; abstract class ModuleRepository extends BaseModuleRepository { - use HandleRelatedBrowsers, HandleApiBrowsers; + use HandleRelatedBrowsers; + use HandleApiBrowsers; /** * Remove trailing newlines from WYSIWYG fields */ public function prepareFieldsBeforeSave($object, $fields) { - // Fields foreach ($fields as $key => $field) { $fields[$key] = StringHelpers::rightTrim($field, '


'); diff --git a/app/Repositories/PageRepository.php b/app/Repositories/PageRepository.php index fa36d022a..29642ac68 100644 --- a/app/Repositories/PageRepository.php +++ b/app/Repositories/PageRepository.php @@ -12,7 +12,12 @@ class PageRepository extends ModuleRepository { - use HandleSlugs, HandleRevisions, HandleMedias, HandleFiles, HandleApiRelations, HandleTranslations; + use HandleSlugs; + use HandleRevisions; + use HandleMedias; + use HandleFiles; + use HandleApiRelations; + use HandleTranslations; protected $browsers = [ // Homepage landing @@ -62,9 +67,6 @@ class PageRepository extends ModuleRepository // Homepage landing 'homeVideos', 'homeHighlights', - - // Articles and Publications landing - 'featuredJournalArticles', ]; protected $apiBrowsers = [ diff --git a/app/Repositories/PressReleaseRepository.php b/app/Repositories/PressReleaseRepository.php index 8f8eae8fd..f4a18a32b 100644 --- a/app/Repositories/PressReleaseRepository.php +++ b/app/Repositories/PressReleaseRepository.php @@ -12,7 +12,11 @@ class PressReleaseRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; protected $browsers = [ 'sponsors' => [ diff --git a/app/Repositories/PrintedPublicationRepository.php b/app/Repositories/PrintedPublicationRepository.php index 623d55fed..fecbb6088 100644 --- a/app/Repositories/PrintedPublicationRepository.php +++ b/app/Repositories/PrintedPublicationRepository.php @@ -11,7 +11,11 @@ class PrintedPublicationRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; public function __construct(PrintedPublication $model) { diff --git a/app/Repositories/PublicationsRepository.php b/app/Repositories/PublicationsRepository.php index af6a124b3..15cdfd08d 100644 --- a/app/Repositories/PublicationsRepository.php +++ b/app/Repositories/PublicationsRepository.php @@ -26,10 +26,7 @@ public function searchApi($string, $perPage = null, $page = null, $columns = []) if ($pub) { $pub->addSearchSection($section); - } - - // If the section represents a pub we haven't found, retrieve it - else { + } else { // If the section represents a pub we haven't found, retrieve it $pub = DigitalPublication::find($section->generic_page_id ?? $section->publication_id ?? $section->digital_publication_id); if ($pub) { diff --git a/app/Repositories/ResearchGuideRepository.php b/app/Repositories/ResearchGuideRepository.php deleted file mode 100644 index c89a59767..000000000 --- a/app/Repositories/ResearchGuideRepository.php +++ /dev/null @@ -1,46 +0,0 @@ -model = $model; - } - - public function getShowData($item, $slug = null, $previewPage = null) - { - return [ - 'borderlessHeader' => !(empty($item->imageFront('banner'))), - 'subNav' => null, - 'nav' => null, - 'intro' => $item->short_description, - 'headerImage' => $item->imageFront('banner'), - 'title' => $item->title, - 'breadcrumb' => [], - 'blocks' => null, - 'nav' => [], - 'page' => $item, - ]; - } - - public function searchApi($string, $perPage = null, $page = null, $columns = []) - { - $search = Search::query()->search($string)->published()->resources(['educator-resources']); - - $results = $search->getSearch($perPage, $columns, null, $page); - - return $results; - } -} diff --git a/app/Repositories/SlideRepository.php b/app/Repositories/SlideRepository.php index 25285b2d7..8f246387e 100644 --- a/app/Repositories/SlideRepository.php +++ b/app/Repositories/SlideRepository.php @@ -13,7 +13,13 @@ class SlideRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions, HandleExperienceModule, Handle3DModel; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; + use HandleExperienceModule; + use Handle3DModel; public function __construct(Slide $model) { diff --git a/app/Repositories/VideoRepository.php b/app/Repositories/VideoRepository.php index 04b6bf887..80a34fd59 100644 --- a/app/Repositories/VideoRepository.php +++ b/app/Repositories/VideoRepository.php @@ -11,7 +11,11 @@ class VideoRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; protected $relatedBrowsers = [ 'related_videos' => [ diff --git a/app/Repositories/VirtualTourRepository.php b/app/Repositories/VirtualTourRepository.php index e274fb488..614fd1568 100644 --- a/app/Repositories/VirtualTourRepository.php +++ b/app/Repositories/VirtualTourRepository.php @@ -11,7 +11,11 @@ class VirtualTourRepository extends ModuleRepository { - use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions; + use HandleBlocks; + use HandleSlugs; + use HandleMedias; + use HandleFiles; + use HandleRevisions; public function __construct(VirtualTour $model) { diff --git a/app/Repositories/WhatToExpectRepository.php b/app/Repositories/WhatToExpectRepository.php index 0ae2c4048..6d129fb0e 100644 --- a/app/Repositories/WhatToExpectRepository.php +++ b/app/Repositories/WhatToExpectRepository.php @@ -8,7 +8,8 @@ class WhatToExpectRepository extends ModuleRepository { - use HandleTranslations, HandleRevisions; + use HandleTranslations; + use HandleRevisions; public function __construct(WhatToExpect $model) { diff --git a/composer.json b/composer.json index 60cb7a9c0..6e1d8228b 100644 --- a/composer.json +++ b/composer.json @@ -64,7 +64,6 @@ "brianium/paratest": "^6.6", "facade/ignition": "^2.5", "fakerphp/faker": "^1.9.1", - "friendsofphp/php-cs-fixer": "^3.0", "itsgoingd/clockwork": "^4.0", "laravel/sail": "^1.0.1", "mockery/mockery": "^1.4.4", @@ -99,8 +98,12 @@ "@php artisan key:generate --ansi" ], "lint": [ - "php-cs-fixer fix --diff --config vendor/aic/data-hub-foundation/.php-cs-fixer.dist.php", - "DIR='vendor/aic/data-hub-foundation' && [ -L ${DIR} ] && [ -d ${DIR} ] && cd ${DIR} && php-cs-fixer fix --diff --config .php-cs-fixer.dist.php || true" + "@putenv COMPOSER=vendor/aic/data-hub-foundation/composer.json", + "@composer lint" + ], + "format": [ + "@putenv COMPOSER=vendor/aic/data-hub-foundation/composer.json", + "@composer format" ], "test": [ "Composer\\Config::disableProcessTimeout", @@ -117,7 +120,8 @@ "preferred-install": "dist", "sort-packages": true, "allow-plugins": { - "netresearch/composer-patches-plugin": true + "netresearch/composer-patches-plugin": true, + "php-http/discovery": true } } } diff --git a/composer.lock b/composer.lock index 7bdeef9ca..10d83db95 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fe0c1f0639eaaeeec3dad77d92fd248a", + "content-hash": "3f63d9ddab4cb8eed91e32f244ba1187", "packages": [ { "name": "aic/data-hub-foundation", @@ -12,25 +12,23 @@ "source": { "type": "git", "url": "https://github.com/art-institute-of-chicago/data-hub-foundation.git", - "reference": "3ab40f975dbf456772b2ca2c699dd2c9201fdeec" + "reference": "290ef8e57acf76684e3f38af7edc4b5c97e2159b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/art-institute-of-chicago/data-hub-foundation/zipball/3ab40f975dbf456772b2ca2c699dd2c9201fdeec", - "reference": "3ab40f975dbf456772b2ca2c699dd2c9201fdeec", + "url": "https://api.github.com/repos/art-institute-of-chicago/data-hub-foundation/zipball/290ef8e57acf76684e3f38af7edc4b5c97e2159b", + "reference": "290ef8e57acf76684e3f38af7edc4b5c97e2159b", "shasum": "" }, "require": { "doctrine/dbal": "^2.6", + "friendsofphp/php-cs-fixer": "^3.5", "fruitcake/laravel-cors": "^2.0", "laravel/framework": "*", "league/fractal": "^0.16.0", "netresearch/composer-patches-plugin": "^1.3.1", - "php": "^7.3|^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.5", - "vendor/package-patches-dev": "~1.0" + "php": "^7.3|^8.0", + "squizlabs/php_codesniffer": "^3.7" }, "type": "library", "extra": { @@ -46,12 +44,6 @@ "url": "vendor/aic/data-hub-foundation/patches/API-227---remove-comments-from-migration-stubs.diff" } ], - "friendsofphp/php-cs-fixer": [ - { - "title": "API-45: Fix arrow functions in method_chaining_indentation", - "url": "vendor/aic/data-hub-foundation/patches/API-45---fix-arrow-functions-in-method-chaining-indentation.diff" - } - ], "doctrine/dbal": [ { "title": "API-316: Support reorder of database columns", @@ -66,8 +58,12 @@ } }, "scripts": { + "format": [ + "phpcbf --standard=vendor/aic/data-hub-foundation/phpcs.dist.xml . || true", + "php-cs-fixer fix --diff --config vendor/aic/data-hub-foundation/.php-cs-fixer.dist.php || true" + ], "lint": [ - "php-cs-fixer fix --diff --config .php-cs-fixer.dist.php" + "phpcs --standard=vendor/aic/data-hub-foundation/phpcs.dist.xml --warning-severity=0 ." ] }, "license": [ @@ -88,7 +84,7 @@ "source": "https://github.com/art-institute-of-chicago/data-hub-foundation/tree/laravel-8-support", "issues": "https://github.com/art-institute-of-chicago/data-hub-foundation/issues" }, - "time": "2023-02-08T21:08:20+00:00" + "time": "2023-04-06T21:54:52+00:00" }, { "name": "area17/twill", @@ -234,28 +230,28 @@ }, { "name": "astrotomic/laravel-translatable", - "version": "v11.11.0", + "version": "v11.12.1", "source": { "type": "git", "url": "https://github.com/Astrotomic/laravel-translatable.git", - "reference": "14335e33189a0902941a9795f744dea2a4a929f1" + "reference": "04de8d1a7c8299a4071fd6bede41d47d264f2d4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Astrotomic/laravel-translatable/zipball/14335e33189a0902941a9795f744dea2a4a929f1", - "reference": "14335e33189a0902941a9795f744dea2a4a929f1", + "url": "https://api.github.com/repos/Astrotomic/laravel-translatable/zipball/04de8d1a7c8299a4071fd6bede41d47d264f2d4d", + "reference": "04de8d1a7c8299a4071fd6bede41d47d264f2d4d", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0 || ^9.0", - "illuminate/database": "^8.0 || ^9.0", - "illuminate/support": "^8.0 || ^9.0", + "illuminate/contracts": "^8.0 || ^9.0 || ^10.0", + "illuminate/database": "^8.0 || ^9.0 || ^10.0", + "illuminate/support": "^8.0 || ^9.0 || ^10.0", "php": "^8.0" }, "require-dev": { "laravel/legacy-factories": "^1.0.4", "mockery/mockery": "^1.3.3", - "orchestra/testbench": "^6.0 || ^7.0", + "orchestra/testbench": "^6.0 || ^7.0 || ^8.0", "phpunit/phpunit": "^9.0" }, "type": "library", @@ -321,27 +317,31 @@ "type": "issuehunt" } ], - "time": "2022-10-10T12:35:52+00:00" + "time": "2023-02-27T10:27:10+00:00" }, { "name": "aws/aws-crt-php", - "version": "v1.0.2", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/awslabs/aws-crt-php.git", - "reference": "3942776a8c99209908ee0b287746263725685732" + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/3942776a8c99209908ee0b287746263725685732", - "reference": "3942776a8c99209908ee0b287746263725685732", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", "shasum": "" }, "require": { "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.8.35|^5.4.3" + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." }, "type": "library", "autoload": { @@ -360,7 +360,7 @@ } ], "description": "AWS Common Runtime for PHP", - "homepage": "http://aws.amazon.com/sdkforphp", + "homepage": "https://github.com/awslabs/aws-crt-php", "keywords": [ "amazon", "aws", @@ -369,26 +369,26 @@ ], "support": { "issues": "https://github.com/awslabs/aws-crt-php/issues", - "source": "https://github.com/awslabs/aws-crt-php/tree/v1.0.2" + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.1" }, - "time": "2021-09-03T22:57:30+00:00" + "time": "2023-03-24T20:22:19+00:00" }, { "name": "aws/aws-sdk-php", - "version": "3.239.1", + "version": "3.263.5", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "47aa3e427371af4449cd9cb07af7209376a535bb" + "reference": "8fc1ca5b34e6197b0d7bebbd66d2889695c8d1ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/47aa3e427371af4449cd9cb07af7209376a535bb", - "reference": "47aa3e427371af4449cd9cb07af7209376a535bb", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/8fc1ca5b34e6197b0d7bebbd66d2889695c8d1ef", + "reference": "8fc1ca5b34e6197b0d7bebbd66d2889695c8d1ef", "shasum": "" }, "require": { - "aws/aws-crt-php": "^1.0.2", + "aws/aws-crt-php": "^1.0.4", "ext-json": "*", "ext-pcre": "*", "ext-simplexml": "*", @@ -463,9 +463,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.239.1" + "source": "https://github.com/aws/aws-sdk-php/tree/3.263.5" }, - "time": "2022-10-19T18:15:49+00:00" + "time": "2023-04-06T18:22:35+00:00" }, { "name": "brick/math", @@ -655,28 +655,26 @@ "time": "2022-02-21T13:15:14+00:00" }, { - "name": "dflydev/dot-access-data", - "version": "v3.0.1", + "name": "composer/pcre", + "version": "3.1.0", "source": { "type": "git", - "url": "https://github.com/dflydev/dflydev-dot-access-data.git", - "reference": "0992cc19268b259a39e86f296da5f0677841f42c" + "url": "https://github.com/composer/pcre.git", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c", - "reference": "0992cc19268b259a39e86f296da5f0677841f42c", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.42", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", - "scrutinizer/ocular": "1.6.0", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^3.14" + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" }, "type": "library", "extra": { @@ -686,7 +684,7 @@ }, "autoload": { "psr-4": { - "Dflydev\\DotAccessData\\": "src/" + "Composer\\Pcre\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -695,72 +693,68 @@ ], "authors": [ { - "name": "Dragonfly Development Inc.", - "email": "info@dflydev.com", - "homepage": "http://dflydev.com" - }, + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.0" + }, + "funding": [ { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" + "url": "https://packagist.com", + "type": "custom" }, { - "name": "Carlos Frutos", - "email": "carlos@kiwing.it", - "homepage": "https://github.com/cfrutos" + "url": "https://github.com/composer", + "type": "github" }, { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com" + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" } ], - "description": "Given a deep data structure, access data by dot notation.", - "homepage": "https://github.com/dflydev/dflydev-dot-access-data", - "keywords": [ - "access", - "data", - "dot", - "notation" - ], - "support": { - "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", - "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1" - }, - "time": "2021-08-13T13:06:58+00:00" + "time": "2022-11-17T09:50:14+00:00" }, { - "name": "doctrine/cache", - "version": "2.2.0", + "name": "composer/semver", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", "shasum": "" }, "require": { - "php": "~7.1 || ^8.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6" + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -769,101 +763,77 @@ ], "authors": [ { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" }, { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" }, { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], - "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", - "homepage": "https://www.doctrine-project.org/projects/cache.html", + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "abstraction", - "apcu", - "cache", - "caching", - "couchdb", - "memcached", - "php", - "redis", - "xcache" + "semantic", + "semver", + "validation", + "versioning" ], "support": { - "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.2.0" + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" }, "funding": [ { - "url": "https://www.doctrine-project.org/sponsorship.html", + "url": "https://packagist.com", "type": "custom" }, { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" + "url": "https://github.com/composer", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], - "time": "2022-05-20T20:07:39+00:00" + "time": "2022-04-01T19:23:25+00:00" }, { - "name": "doctrine/dbal", - "version": "2.13.9", + "name": "composer/xdebug-handler", + "version": "3.0.3", "source": { "type": "git", - "url": "https://github.com/doctrine/dbal.git", - "reference": "c480849ca3ad6706a39c970cdfe6888fa8a058b8" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/c480849ca3ad6706a39c970cdfe6888fa8a058b8", - "reference": "c480849ca3ad6706a39c970cdfe6888fa8a058b8", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", "shasum": "" }, "require": { - "doctrine/cache": "^1.0|^2.0", - "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1.0", - "ext-pdo": "*", - "php": "^7.1 || ^8" + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" }, "require-dev": { - "doctrine/coding-standard": "9.0.0", - "jetbrains/phpstorm-stubs": "2021.1", - "phpstan/phpstan": "1.4.6", - "phpunit/phpunit": "^7.5.20|^8.5|9.5.16", - "psalm/plugin-phpunit": "0.16.1", - "squizlabs/php_codesniffer": "3.6.2", - "symfony/cache": "^4.4", - "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", - "vimeo/psalm": "4.22.0" - }, - "suggest": { - "symfony/console": "For helpful console commands such as SQL execution and import of files." + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" }, - "bin": [ - "bin/doctrine-dbal" - ], "type": "library", "autoload": { "psr-4": { - "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" + "Composer\\XdebugHandler\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -872,64 +842,388 @@ ], "authors": [ { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" } ], - "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", - "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "description": "Restarts a process without Xdebug.", "keywords": [ - "abstraction", - "database", - "db2", - "dbal", - "mariadb", - "mssql", - "mysql", - "oci8", - "oracle", - "pdo", - "pgsql", - "postgresql", - "queryobject", - "sasql", - "sql", - "sqlanywhere", - "sqlite", - "sqlserver", - "sqlsrv" + "Xdebug", + "performance" ], "support": { - "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/2.13.9" + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" }, "funding": [ { - "url": "https://www.doctrine-project.org/sponsorship.html", + "url": "https://packagist.com", "type": "custom" }, { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" + "url": "https://github.com/composer", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], - "time": "2022-05-02T20:28:55+00:00" + "time": "2022-02-25T21:32:43+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "f41715465d65213d644d3141a6a93081be5d3549" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549", + "reference": "f41715465d65213d644d3141a6a93081be5d3549", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2" + }, + "time": "2022-10-27T11:44:00+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.14.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", + "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1 || ^2", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.14.3" + }, + "time": "2023-02-01T09:20:38+00:00" + }, + { + "name": "doctrine/cache", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", + "shasum": "" + }, + "require": { + "php": "~7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", + "keywords": [ + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" + ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.2.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "type": "tidelift" + } + ], + "time": "2022-05-20T20:07:39+00:00" + }, + { + "name": "doctrine/dbal", + "version": "2.13.9", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "c480849ca3ad6706a39c970cdfe6888fa8a058b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/c480849ca3ad6706a39c970cdfe6888fa8a058b8", + "reference": "c480849ca3ad6706a39c970cdfe6888fa8a058b8", + "shasum": "" + }, + "require": { + "doctrine/cache": "^1.0|^2.0", + "doctrine/deprecations": "^0.5.3|^1", + "doctrine/event-manager": "^1.0", + "ext-pdo": "*", + "php": "^7.1 || ^8" + }, + "require-dev": { + "doctrine/coding-standard": "9.0.0", + "jetbrains/phpstorm-stubs": "2021.1", + "phpstan/phpstan": "1.4.6", + "phpunit/phpunit": "^7.5.20|^8.5|9.5.16", + "psalm/plugin-phpunit": "0.16.1", + "squizlabs/php_codesniffer": "3.6.2", + "symfony/cache": "^4.4", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", + "vimeo/psalm": "4.22.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlanywhere", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/2.13.9" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], + "time": "2022-05-02T20:28:55+00:00" }, { "name": "doctrine/deprecations", @@ -1068,23 +1362,23 @@ }, { "name": "doctrine/inflector", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392" + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", - "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^10", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-strict-rules": "^1.3", @@ -1139,7 +1433,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.5" + "source": "https://github.com/doctrine/inflector/tree/2.0.6" }, "funding": [ { @@ -1155,7 +1449,7 @@ "type": "tidelift" } ], - "time": "2022-09-07T09:01:28+00:00" + "time": "2022-10-20T09:10:12+00:00" }, { "name": "doctrine/lexer", @@ -1478,16 +1772,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.3.0", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "018dfc4e1da92ad8a1b90adc4893f476a3b41cb8" + "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/018dfc4e1da92ad8a1b90adc4893f476a3b41cb8", - "reference": "018dfc4e1da92ad8a1b90adc4893f476a3b41cb8", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/4dd1e007f22a927ac77da5a3fbb067b42d3bc224", + "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224", "shasum": "" }, "require": { @@ -1502,6 +1796,7 @@ "psr/http-factory": "^1.0" }, "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" }, "type": "library", @@ -1534,9 +1829,99 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.3.0" + "source": "https://github.com/firebase/php-jwt/tree/v6.4.0" }, - "time": "2022-07-15T16:48:45+00:00" + "time": "2023-02-09T21:01:23+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.14.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "d7cfcdc49f081bc6bfd00dfb75063a42146fd753" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/d7cfcdc49f081bc6bfd00dfb75063a42146fd753", + "reference": "d7cfcdc49f081bc6bfd00dfb75063a42146fd753", + "shasum": "" + }, + "require": { + "composer/semver": "^3.3", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^1.14.2 || ^2", + "doctrine/lexer": "^1 || ^2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", + "symfony/polyfill-mbstring": "^1.27", + "symfony/polyfill-php80": "^1.27", + "symfony/polyfill-php81": "^1.27", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" + }, + "require-dev": { + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.0", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.5.3", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy": "^1.16", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "phpunitgoodpractices/polyfill": "^1.6", + "phpunitgoodpractices/traits": "^1.9.2", + "symfony/phpunit-bridge": "^6.2.3", + "symfony/yaml": "^5.4 || ^6.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.14.1" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2023-01-29T23:43:24+00:00" }, { "name": "fruitcake/laravel-cors", @@ -1615,20 +2000,21 @@ "type": "github" } ], + "abandoned": true, "time": "2022-02-23T14:25:13+00:00" }, { "name": "google/apiclient", - "version": "v2.12.6", + "version": "v2.13.2", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client.git", - "reference": "f92aa126903a9e2da5bd41a280d9633cb249e79e" + "reference": "53c3168fd1836ec21d28a768f78a8c0e44046ec4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/f92aa126903a9e2da5bd41a280d9633cb249e79e", - "reference": "f92aa126903a9e2da5bd41a280d9633cb249e79e", + "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/53c3168fd1836ec21d28a768f78a8c0e44046ec4", + "reference": "53c3168fd1836ec21d28a768f78a8c0e44046ec4", "shasum": "" }, "require": { @@ -1683,22 +2069,22 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client/issues", - "source": "https://github.com/googleapis/google-api-php-client/tree/v2.12.6" + "source": "https://github.com/googleapis/google-api-php-client/tree/v2.13.2" }, - "time": "2022-06-06T20:00:19+00:00" + "time": "2023-04-06T14:59:47+00:00" }, { "name": "google/apiclient-services", - "version": "v0.271.0", + "version": "v0.294.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "3ab645dbdd0e511ba4c7a937fb4dc764e861ed6a" + "reference": "215a5e53790730c7e90fd93c76517652e0fff2a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/3ab645dbdd0e511ba4c7a937fb4dc764e861ed6a", - "reference": "3ab645dbdd0e511ba4c7a937fb4dc764e861ed6a", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/215a5e53790730c7e90fd93c76517652e0fff2a3", + "reference": "215a5e53790730c7e90fd93c76517652e0fff2a3", "shasum": "" }, "require": { @@ -1727,22 +2113,22 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.271.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.294.0" }, - "time": "2022-10-15T00:58:16+00:00" + "time": "2023-04-06T01:30:37+00:00" }, { "name": "google/auth", - "version": "v1.23.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "8da16102d2cd1bdc128d97f323553df465ee7701" + "reference": "f1f0d0319e2e7750ebfaa523c78819792a9ed9f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/8da16102d2cd1bdc128d97f323553df465ee7701", - "reference": "8da16102d2cd1bdc128d97f323553df465ee7701", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/f1f0d0319e2e7750ebfaa523c78819792a9ed9f7", + "reference": "f1f0d0319e2e7750ebfaa523c78819792a9ed9f7", "shasum": "" }, "require": { @@ -1755,10 +2141,10 @@ }, "require-dev": { "guzzlehttp/promises": "0.1.1|^1.3", - "kelvinmo/simplejwt": "^0.2.5|^0.5.1", - "phpseclib/phpseclib": "^2.0.31", - "phpspec/prophecy-phpunit": "^1.1", - "phpunit/phpunit": "^7.5||^8.5", + "kelvinmo/simplejwt": "0.7.0", + "phpseclib/phpseclib": "^2.0.31||^3.0", + "phpspec/prophecy-phpunit": "^1.1||^2.0", + "phpunit/phpunit": "^7.5||^9.0.0", "sebastian/comparator": ">=1.2.3", "squizlabs/php_codesniffer": "^3.5" }, @@ -1785,30 +2171,30 @@ "support": { "docs": "https://googleapis.github.io/google-auth-library-php/main/", "issues": "https://github.com/googleapis/google-auth-library-php/issues", - "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.23.0" + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.26.0" }, - "time": "2022-09-27T16:27:23+00:00" + "time": "2023-04-05T15:11:57+00:00" }, { "name": "graham-campbell/result-type", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", - "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9" + "phpoption/phpoption": "^1.9.1" }, "require-dev": { - "phpunit/phpunit": "^8.5.28 || ^9.5.21" + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" }, "type": "library", "autoload": { @@ -1837,7 +2223,7 @@ ], "support": { "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.0" + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1" }, "funding": [ { @@ -1849,7 +2235,7 @@ "type": "tidelift" } ], - "time": "2022-07-30T15:56:11+00:00" + "time": "2023-02-25T20:23:15+00:00" }, { "name": "guzzlehttp/guzzle", @@ -2477,22 +2863,22 @@ }, { "name": "kalnoy/nestedset", - "version": "v6.0.1", + "version": "v6.0.2", "source": { "type": "git", "url": "https://github.com/lazychaser/laravel-nestedset.git", - "reference": "bcfbccea5e3ddf31cb22e1bc3c6124da584505fc" + "reference": "2d5c99fe1bfbaa4004f8d6fb24475f7ff88bb526" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lazychaser/laravel-nestedset/zipball/bcfbccea5e3ddf31cb22e1bc3c6124da584505fc", - "reference": "bcfbccea5e3ddf31cb22e1bc3c6124da584505fc", + "url": "https://api.github.com/repos/lazychaser/laravel-nestedset/zipball/2d5c99fe1bfbaa4004f8d6fb24475f7ff88bb526", + "reference": "2d5c99fe1bfbaa4004f8d6fb24475f7ff88bb526", "shasum": "" }, "require": { - "illuminate/database": "^7.0|^8.0|^9.0", - "illuminate/events": "^7.0|^8.0|^9.0", - "illuminate/support": "^7.0|^8.0|^9.0", + "illuminate/database": "^7.0|^8.0|^9.0|^10.0", + "illuminate/events": "^7.0|^8.0|^9.0|^10.0", + "illuminate/support": "^7.0|^8.0|^9.0|^10.0", "php": "^7.2.5|^8.0" }, "require-dev": { @@ -2534,22 +2920,22 @@ ], "support": { "issues": "https://github.com/lazychaser/laravel-nestedset/issues", - "source": "https://github.com/lazychaser/laravel-nestedset/tree/v6.0.1" + "source": "https://github.com/lazychaser/laravel-nestedset/tree/v6.0.2" }, - "time": "2022-02-11T06:17:57+00:00" + "time": "2023-02-16T14:41:24+00:00" }, { "name": "laravel/framework", - "version": "v8.83.25", + "version": "v8.83.27", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "b77b908a9426efa41d6286a2ef4c3adbf5398ca1" + "reference": "e1afe088b4ca613fb96dc57e6d8dbcb8cc2c6b49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/b77b908a9426efa41d6286a2ef4c3adbf5398ca1", - "reference": "b77b908a9426efa41d6286a2ef4c3adbf5398ca1", + "url": "https://api.github.com/repos/laravel/framework/zipball/e1afe088b4ca613fb96dc57e6d8dbcb8cc2c6b49", + "reference": "e1afe088b4ca613fb96dc57e6d8dbcb8cc2c6b49", "shasum": "" }, "require": { @@ -2709,7 +3095,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-09-30T13:00:40+00:00" + "time": "2022-12-08T15:28:55+00:00" }, { "name": "laravel/sanctum", @@ -2778,16 +3164,16 @@ }, { "name": "laravel/serializable-closure", - "version": "v1.2.2", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae" + "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/47afb7fae28ed29057fdca37e16a84f90cc62fae", - "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f23fe9d4e95255dacee1bf3525e0810d1a1b0f37", + "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37", "shasum": "" }, "require": { @@ -2834,34 +3220,34 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2022-09-08T13:45:54+00:00" + "time": "2023-01-30T18:31:20+00:00" }, { "name": "laravel/socialite", - "version": "v5.5.5", + "version": "v5.6.1", "source": { "type": "git", "url": "https://github.com/laravel/socialite.git", - "reference": "ce8b2f967eead5a6bae74449e207be6f8046edc3" + "reference": "a14a177f2cc71d8add71e2b19e00800e83bdda09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/socialite/zipball/ce8b2f967eead5a6bae74449e207be6f8046edc3", - "reference": "ce8b2f967eead5a6bae74449e207be6f8046edc3", + "url": "https://api.github.com/repos/laravel/socialite/zipball/a14a177f2cc71d8add71e2b19e00800e83bdda09", + "reference": "a14a177f2cc71d8add71e2b19e00800e83bdda09", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/guzzle": "^6.0|^7.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0", - "illuminate/http": "^6.0|^7.0|^8.0|^9.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0", "league/oauth1-client": "^1.10.1", "php": "^7.2|^8.0" }, "require-dev": { "mockery/mockery": "^1.0", - "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0", + "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0", "phpunit/phpunit": "^8.0|^9.3" }, "type": "library", @@ -2903,26 +3289,26 @@ "issues": "https://github.com/laravel/socialite/issues", "source": "https://github.com/laravel/socialite" }, - "time": "2022-08-20T21:32:07+00:00" + "time": "2023-01-20T15:42:35+00:00" }, { "name": "laravel/tinker", - "version": "v2.7.2", + "version": "v2.8.1", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "dff39b661e827dae6e092412f976658df82dbac5" + "reference": "04a2d3bd0d650c0764f70bf49d1ee39393e4eb10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/dff39b661e827dae6e092412f976658df82dbac5", - "reference": "dff39b661e827dae6e092412f976658df82dbac5", + "url": "https://api.github.com/repos/laravel/tinker/zipball/04a2d3bd0d650c0764f70bf49d1ee39393e4eb10", + "reference": "04a2d3bd0d650c0764f70bf49d1ee39393e4eb10", "shasum": "" }, "require": { - "illuminate/console": "^6.0|^7.0|^8.0|^9.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0", "php": "^7.2.5|^8.0", "psy/psysh": "^0.10.4|^0.11.1", "symfony/var-dumper": "^4.3.4|^5.0|^6.0" @@ -2932,7 +3318,7 @@ "phpunit/phpunit": "^8.5.8|^9.3.3" }, "suggest": { - "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0)." + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0)." }, "type": "library", "extra": { @@ -2969,9 +3355,9 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.7.2" + "source": "https://github.com/laravel/tinker/tree/v2.8.1" }, - "time": "2022-03-23T12:38:24+00:00" + "time": "2023-02-15T16:40:09+00:00" }, { "name": "laravel/ui", @@ -3036,16 +3422,16 @@ }, { "name": "league/commonmark", - "version": "2.3.5", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "84d74485fdb7074f4f9dd6f02ab957b1de513257" + "reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/84d74485fdb7074f4f9dd6f02ab957b1de513257", - "reference": "84d74485fdb7074f4f9dd6f02ab957b1de513257", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d44a24690f16b8c1808bf13b1bd54ae4c63ea048", + "reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048", "shasum": "" }, "require": { @@ -3065,7 +3451,7 @@ "erusev/parsedown": "^1.0", "ext-json": "*", "github/gfm": "0.29.0", - "michelf/php-markdown": "^1.4", + "michelf/php-markdown": "^1.4 || ^2.0", "nyholm/psr7": "^1.5", "phpstan/phpstan": "^1.8.2", "phpunit/phpunit": "^9.5.21", @@ -3073,7 +3459,7 @@ "symfony/finder": "^5.3 | ^6.0", "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", "unleashedtech/php-coding-standard": "^3.1.1", - "vimeo/psalm": "^4.24.0" + "vimeo/psalm": "^4.24.0 || ^5.0.0" }, "suggest": { "symfony/yaml": "v2.3+ required if using the Front Matter extension" @@ -3081,7 +3467,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" } }, "autoload": { @@ -3138,20 +3524,20 @@ "type": "tidelift" } ], - "time": "2022-07-29T10:59:45+00:00" + "time": "2023-03-24T15:16:10+00:00" }, { "name": "league/config", - "version": "v1.1.1", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/thephpleague/config.git", - "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e" + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", - "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", "shasum": "" }, "require": { @@ -3160,7 +3546,7 @@ "php": "^7.4 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.90", + "phpstan/phpstan": "^1.8.2", "phpunit/phpunit": "^9.5.5", "scrutinizer/ocular": "^1.8.1", "unleashedtech/php-coding-standard": "^3.1", @@ -3220,38 +3606,41 @@ "type": "github" } ], - "time": "2021-08-14T12:15:32+00:00" + "time": "2022-12-11T20:36:23+00:00" }, { "name": "league/csv", - "version": "9.8.0", + "version": "9.9.0", "source": { "type": "git", "url": "https://github.com/thephpleague/csv.git", - "reference": "9d2e0265c5d90f5dd601bc65ff717e05cec19b47" + "reference": "b4418ede47fbd88facc34e40a16c8ce9153b961b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/csv/zipball/9d2e0265c5d90f5dd601bc65ff717e05cec19b47", - "reference": "9d2e0265c5d90f5dd601bc65ff717e05cec19b47", + "url": "https://api.github.com/repos/thephpleague/csv/zipball/b4418ede47fbd88facc34e40a16c8ce9153b961b", + "reference": "b4418ede47fbd88facc34e40a16c8ce9153b961b", "shasum": "" }, "require": { "ext-json": "*", "ext-mbstring": "*", - "php": "^7.4 || ^8.0" + "php": "^8.1.2" }, "require-dev": { - "ext-curl": "*", + "doctrine/collections": "^2.1.2", "ext-dom": "*", - "friendsofphp/php-cs-fixer": "^v3.4.0", - "phpstan/phpstan": "^1.3.0", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "phpunit/phpunit": "^9.5.11" + "ext-xdebug": "*", + "friendsofphp/php-cs-fixer": "^v3.14.3", + "phpbench/phpbench": "^1.2.8", + "phpstan/phpstan": "^1.10.4", + "phpstan/phpstan-deprecation-rules": "^1.1.2", + "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^10.0.14" }, "suggest": { - "ext-dom": "Required to use the XMLConverter and or the HTMLConverter classes", + "ext-dom": "Required to use the XMLConverter and the HTMLConverter classes", "ext-iconv": "Needed to ease transcoding CSV using iconv stream filters" }, "type": "library", @@ -3304,7 +3693,7 @@ "type": "github" } ], - "time": "2022-01-04T00:13:07+00:00" + "time": "2023-03-11T15:57:12+00:00" }, { "name": "league/flysystem", @@ -3580,16 +3969,16 @@ }, { "name": "league/glide", - "version": "1.7.1", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/thephpleague/glide.git", - "reference": "257e0c3612ef3dc57eb7f90cb741198151a45a5f" + "reference": "8dba756ada0b8e525bf6f1f7d1bd83c1e99e124e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/glide/zipball/257e0c3612ef3dc57eb7f90cb741198151a45a5f", - "reference": "257e0c3612ef3dc57eb7f90cb741198151a45a5f", + "url": "https://api.github.com/repos/thephpleague/glide/zipball/8dba756ada0b8e525bf6f1f7d1bd83c1e99e124e", + "reference": "8dba756ada0b8e525bf6f1f7d1bd83c1e99e124e", "shasum": "" }, "require": { @@ -3644,9 +4033,9 @@ ], "support": { "issues": "https://github.com/thephpleague/glide/issues", - "source": "https://github.com/thephpleague/glide/tree/1.7.1" + "source": "https://github.com/thephpleague/glide/tree/1.7.2" }, - "time": "2022-04-27T04:03:46+00:00" + "time": "2023-02-14T06:26:04+00:00" }, { "name": "league/glide-laravel", @@ -4090,16 +4479,16 @@ }, { "name": "monolog/monolog", - "version": "2.8.0", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "720488632c590286b88b80e62aa3d3d551ad4a50" + "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50", - "reference": "720488632c590286b88b80e62aa3d3d551ad4a50", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f259e2b15fb95494c83f52d3caad003bbf5ffaa1", + "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1", "shasum": "" }, "require": { @@ -4114,7 +4503,7 @@ "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", "guzzlehttp/guzzle": "^7.4", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", @@ -4176,7 +4565,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.8.0" + "source": "https://github.com/Seldaek/monolog/tree/2.9.1" }, "funding": [ { @@ -4188,7 +4577,7 @@ "type": "tidelift" } ], - "time": "2022-07-24T11:55:47+00:00" + "time": "2023-02-06T13:44:46+00:00" }, { "name": "mtdowling/jmespath.php", @@ -4316,16 +4705,16 @@ }, { "name": "nesbot/carbon", - "version": "2.62.1", + "version": "2.66.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a" + "reference": "496712849902241f04902033b0441b269effe001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a", - "reference": "01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/496712849902241f04902033b0441b269effe001", + "reference": "496712849902241f04902033b0441b269effe001", "shasum": "" }, "require": { @@ -4336,7 +4725,7 @@ "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { - "doctrine/dbal": "^2.0 || ^3.0", + "doctrine/dbal": "^2.0 || ^3.1.4", "doctrine/orm": "^2.7", "friendsofphp/php-cs-fixer": "^3.0", "kylekatarnls/multi-tester": "^2.0", @@ -4414,7 +4803,7 @@ "type": "tidelift" } ], - "time": "2022-09-02T07:48:13+00:00" + "time": "2023-01-29T18:53:47+00:00" }, { "name": "netresearch/composer-patches-plugin", @@ -4472,25 +4861,25 @@ }, { "name": "nette/schema", - "version": "v1.2.2", + "version": "v1.2.3", "source": { "type": "git", "url": "https://github.com/nette/schema.git", - "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df" + "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df", - "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df", + "url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", + "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", "shasum": "" }, "require": { "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", - "php": ">=7.1 <8.2" + "php": ">=7.1 <8.3" }, "require-dev": { "nette/tester": "^2.3 || ^2.4", - "phpstan/phpstan-nette": "^0.12", + "phpstan/phpstan-nette": "^1.0", "tracy/tracy": "^2.7" }, "type": "library", @@ -4528,34 +4917,36 @@ ], "support": { "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.2.2" + "source": "https://github.com/nette/schema/tree/v1.2.3" }, - "time": "2021-10-15T11:40:02+00:00" + "time": "2022-10-13T01:24:26+00:00" }, { "name": "nette/utils", - "version": "v3.2.8", + "version": "v4.0.0", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368" + "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", - "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", + "url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e", + "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e", "shasum": "" }, "require": { - "php": ">=7.2 <8.3" + "php": ">=8.0 <8.3" }, "conflict": { - "nette/di": "<3.0.6" + "nette/finder": "<3", + "nette/schema": "<1.2.2" }, "require-dev": { - "nette/tester": "~2.0", + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.4", "phpstan/phpstan": "^1.0", - "tracy/tracy": "^2.3" + "tracy/tracy": "^2.9" }, "suggest": { "ext-gd": "to use Image", @@ -4569,7 +4960,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -4613,9 +5004,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v3.2.8" + "source": "https://github.com/nette/utils/tree/v4.0.0" }, - "time": "2022-09-12T23:36:20+00:00" + "time": "2023-02-02T10:41:53+00:00" }, { "name": "nicmart/tree", @@ -4665,16 +5056,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.15.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290", + "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290", "shasum": "" }, "require": { @@ -4715,9 +5106,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2023-03-05T19:49:14+00:00" }, { "name": "nyholm/psr7", @@ -5055,38 +5446,44 @@ }, { "name": "php-http/discovery", - "version": "1.14.3", + "version": "1.15.3", "source": { "type": "git", "url": "https://github.com/php-http/discovery.git", - "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735" + "reference": "3ccd28dd9fb34b52db946abea1b538568e34eae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/31d8ee46d0215108df16a8527c7438e96a4d7735", - "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735", + "url": "https://api.github.com/repos/php-http/discovery/zipball/3ccd28dd9fb34b52db946abea1b538568e34eae8", + "reference": "3ccd28dd9fb34b52db946abea1b538568e34eae8", "shasum": "" }, "require": { + "composer-plugin-api": "^1.0|^2.0", "php": "^7.1 || ^8.0" }, "conflict": { "nyholm/psr7": "<1.0" }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, "require-dev": { + "composer/composer": "^1.0.2|^2.0", "graham-campbell/phpspec-skip-example-extension": "^5.0", "php-http/httplug": "^1.0 || ^2.0", "php-http/message-factory": "^1.0", - "phpspec/phpspec": "^5.1 || ^6.1" + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "symfony/phpunit-bridge": "^6.2" }, - "suggest": { - "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories" - }, - "type": "library", + "type": "composer-plugin", "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true }, "autoload": { "psr-4": { @@ -5103,7 +5500,7 @@ "email": "mark.sagikazar@gmail.com" } ], - "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", "homepage": "http://php-http.org", "keywords": [ "adapter", @@ -5112,13 +5509,14 @@ "factory", "http", "message", + "psr17", "psr7" ], "support": { "issues": "https://github.com/php-http/discovery/issues", - "source": "https://github.com/php-http/discovery/tree/1.14.3" + "source": "https://github.com/php-http/discovery/tree/1.15.3" }, - "time": "2022-07-11T14:04:40+00:00" + "time": "2023-03-31T14:40:37+00:00" }, { "name": "php-http/httplug", @@ -5369,24 +5767,24 @@ }, { "name": "phpoption/phpoption", - "version": "1.9.0", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", - "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e", + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8", - "phpunit/phpunit": "^8.5.28 || ^9.5.21" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" }, "type": "library", "extra": { @@ -5428,7 +5826,7 @@ ], "support": { "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.0" + "source": "https://github.com/schmittjoh/php-option/tree/1.9.1" }, "funding": [ { @@ -5440,20 +5838,20 @@ "type": "tidelift" } ], - "time": "2022-07-30T15:51:26+00:00" + "time": "2023-02-25T19:38:58+00:00" }, { "name": "phpseclib/phpseclib", - "version": "3.0.16", + "version": "3.0.19", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "7181378909ed8890be4db53d289faac5b77f8b05" + "reference": "cc181005cf548bfd8a4896383bb825d859259f95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7181378909ed8890be4db53d289faac5b77f8b05", - "reference": "7181378909ed8890be4db53d289faac5b77f8b05", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cc181005cf548bfd8a4896383bb825d859259f95", + "reference": "cc181005cf548bfd8a4896383bb825d859259f95", "shasum": "" }, "require": { @@ -5534,7 +5932,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.16" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.19" }, "funding": [ { @@ -5550,7 +5948,7 @@ "type": "tidelift" } ], - "time": "2022-09-05T18:03:08+00:00" + "time": "2023-03-05T17:13:09+00:00" }, { "name": "pragmarx/google2fa", @@ -5927,25 +6325,25 @@ }, { "name": "psr/http-message", - "version": "1.0.1", + "version": "1.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -5974,9 +6372,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/master" + "source": "https://github.com/php-fig/http-message/tree/1.1" }, - "time": "2016-08-06T14:39:51+00:00" + "time": "2023-04-04T09:50:52+00:00" }, { "name": "psr/log", @@ -6081,16 +6479,16 @@ }, { "name": "psy/psysh", - "version": "v0.11.8", + "version": "v0.11.14", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "f455acf3645262ae389b10e9beba0c358aa6994e" + "reference": "8c2e264def7a8263a68ef6f0b55ce90b77d41e17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/f455acf3645262ae389b10e9beba0c358aa6994e", - "reference": "f455acf3645262ae389b10e9beba0c358aa6994e", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/8c2e264def7a8263a68ef6f0b55ce90b77d41e17", + "reference": "8c2e264def7a8263a68ef6f0b55ce90b77d41e17", "shasum": "" }, "require": { @@ -6151,9 +6549,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.11.8" + "source": "https://github.com/bobthecow/psysh/tree/v0.11.14" }, - "time": "2022-07-28T14:25:11+00:00" + "time": "2023-03-28T03:41:01+00:00" }, { "name": "ralouphie/getallheaders", @@ -6201,42 +6599,52 @@ }, { "name": "ramsey/collection", - "version": "1.2.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a" + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a", - "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", "shasum": "" }, "require": { - "php": "^7.3 || ^8", - "symfony/polyfill-php81": "^1.23" + "php": "^8.1" }, "require-dev": { - "captainhook/captainhook": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "ergebnis/composer-normalize": "^2.6", - "fakerphp/faker": "^1.5", - "hamcrest/hamcrest-php": "^2", - "jangregor/phpstan-prophecy": "^0.8", - "mockery/mockery": "^1.3", + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1", - "phpstan/phpstan": "^0.12.32", - "phpstan/phpstan-mockery": "^0.12.5", - "phpstan/phpstan-phpunit": "^0.12.11", - "phpunit/phpunit": "^8.5 || ^9", - "psy/psysh": "^0.10.4", - "slevomat/coding-standard": "^6.3", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.4" + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } }, - "type": "library", "autoload": { "psr-4": { "Ramsey\\Collection\\": "src/" @@ -6264,7 +6672,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.2.2" + "source": "https://github.com/ramsey/collection/tree/2.0.0" }, "funding": [ { @@ -6276,28 +6684,27 @@ "type": "tidelift" } ], - "time": "2021-10-10T03:01:02+00:00" + "time": "2022-12-31T21:50:55+00:00" }, { "name": "ramsey/uuid", - "version": "4.5.1", + "version": "4.7.3", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "a161a26d917604dc6d3aa25100fddf2556e9f35d" + "reference": "433b2014e3979047db08a17a205f410ba3869cf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/a161a26d917604dc6d3aa25100fddf2556e9f35d", - "reference": "a161a26d917604dc6d3aa25100fddf2556e9f35d", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/433b2014e3979047db08a17a205f410ba3869cf2", + "reference": "433b2014e3979047db08a17a205f410ba3869cf2", "shasum": "" }, "require": { "brick/math": "^0.8.8 || ^0.9 || ^0.10", - "ext-ctype": "*", "ext-json": "*", "php": "^8.0", - "ramsey/collection": "^1.0" + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -6326,7 +6733,6 @@ }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", @@ -6358,7 +6764,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.5.1" + "source": "https://github.com/ramsey/uuid/tree/4.7.3" }, "funding": [ { @@ -6370,20 +6776,20 @@ "type": "tidelift" } ], - "time": "2022-09-16T03:22:46+00:00" + "time": "2023-01-12T18:13:24+00:00" }, { "name": "rlanvin/php-rrule", - "version": "v2.3.2", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/rlanvin/php-rrule.git", - "reference": "2221e8cdac037f3ead5bd17a8e19b0771534d4e7" + "reference": "2acd9950e803ea65514d6440212d39096df9c528" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rlanvin/php-rrule/zipball/2221e8cdac037f3ead5bd17a8e19b0771534d4e7", - "reference": "2221e8cdac037f3ead5bd17a8e19b0771534d4e7", + "url": "https://api.github.com/repos/rlanvin/php-rrule/zipball/2acd9950e803ea65514d6440212d39096df9c528", + "reference": "2acd9950e803ea65514d6440212d39096df9c528", "shasum": "" }, "require": { @@ -6417,9 +6823,9 @@ ], "support": { "issues": "https://github.com/rlanvin/php-rrule/issues", - "source": "https://github.com/rlanvin/php-rrule/tree/v2.3.2" + "source": "https://github.com/rlanvin/php-rrule/tree/v2.4.0" }, - "time": "2022-05-03T13:11:22+00:00" + "time": "2023-01-06T10:19:10+00:00" }, { "name": "robrichards/wse-php", @@ -6569,6 +6975,72 @@ }, "time": "2021-10-26T20:46:29+00:00" }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-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", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, { "name": "sentry/sdk", "version": "3.3.0", @@ -6628,32 +7100,31 @@ }, { "name": "sentry/sentry", - "version": "3.10.0", + "version": "3.17.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "2fdbda9b3569df08dd4a300db8a563d0ec7241f9" + "reference": "95d2e932383cf684f77acff0d2a5aef5ad2f1933" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/2fdbda9b3569df08dd4a300db8a563d0ec7241f9", - "reference": "2fdbda9b3569df08dd4a300db8a563d0ec7241f9", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/95d2e932383cf684f77acff0d2a5aef5ad2f1933", + "reference": "95d2e932383cf684f77acff0d2a5aef5ad2f1933", "shasum": "" }, "require": { "ext-json": "*", "ext-mbstring": "*", "guzzlehttp/promises": "^1.4", - "guzzlehttp/psr7": "^1.8.4|^2.1.1", "jean85/pretty-package-versions": "^1.5|^2.0.4", "php": "^7.2|^8.0", "php-http/async-client-implementation": "^1.0", "php-http/client-common": "^1.5|^2.0", - "php-http/discovery": "^1.11", + "php-http/discovery": "^1.15", "php-http/httplug": "^1.1|^2.0", "php-http/message": "^1.5", "psr/http-factory": "^1.0", - "psr/http-message-implementation": "^1.0", + "psr/http-factory-implementation": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "symfony/options-resolver": "^3.4.43|^4.4.30|^5.0.11|^6.0", "symfony/polyfill-php80": "^1.17" @@ -6664,6 +7135,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.19|3.4.*", + "guzzlehttp/psr7": "^1.8.4|^2.1.1", "http-interop/http-factory-guzzle": "^1.0", "monolog/monolog": "^1.6|^2.0|^3.0", "nikic/php-parser": "^4.10.3", @@ -6682,7 +7154,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.10.x-dev" + "dev-master": "3.13.x-dev" } }, "autoload": { @@ -6695,7 +7167,7 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { @@ -6716,7 +7188,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/3.10.0" + "source": "https://github.com/getsentry/sentry-php/tree/3.17.0" }, "funding": [ { @@ -6728,7 +7200,7 @@ "type": "custom" } ], - "time": "2022-10-19T09:28:02+00:00" + "time": "2023-03-26T21:54:06+00:00" }, { "name": "sentry/sentry-laravel", @@ -6820,16 +7292,16 @@ }, { "name": "spatie/browsershot", - "version": "3.57.2", + "version": "3.57.6", "source": { "type": "git", "url": "https://github.com/spatie/browsershot.git", - "reference": "7125719979b7de1257bbf699ff1d3bff3125b228" + "reference": "41382e013a00a62a7b2f2945a615d73e59b3a907" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/browsershot/zipball/7125719979b7de1257bbf699ff1d3bff3125b228", - "reference": "7125719979b7de1257bbf699ff1d3bff3125b228", + "url": "https://api.github.com/repos/spatie/browsershot/zipball/41382e013a00a62a7b2f2945a615d73e59b3a907", + "reference": "41382e013a00a62a7b2f2945a615d73e59b3a907", "shasum": "" }, "require": { @@ -6874,7 +7346,7 @@ "webpage" ], "support": { - "source": "https://github.com/spatie/browsershot/tree/3.57.2" + "source": "https://github.com/spatie/browsershot/tree/3.57.6" }, "funding": [ { @@ -6882,30 +7354,30 @@ "type": "github" } ], - "time": "2022-08-19T16:43:07+00:00" + "time": "2023-01-03T19:12:47+00:00" }, { "name": "spatie/calendar-links", - "version": "1.8.0", + "version": "1.8.5", "source": { "type": "git", "url": "https://github.com/spatie/calendar-links.git", - "reference": "654fc0174e6279539b9bf0abdc3339e34c5286d7" + "reference": "d6f6c5e7ff916e2a55e2160d4db4f15875cb6e07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/calendar-links/zipball/654fc0174e6279539b9bf0abdc3339e34c5286d7", - "reference": "654fc0174e6279539b9bf0abdc3339e34c5286d7", + "url": "https://api.github.com/repos/spatie/calendar-links/zipball/d6f6c5e7ff916e2a55e2160d4db4f15875cb6e07", + "reference": "d6f6c5e7ff916e2a55e2160d4db4f15875cb6e07", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" + "php": "^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.0", - "phpunit/phpunit": "^9.5", - "spatie/phpunit-snapshot-assertions": "^4.0", - "vimeo/psalm": "^4.20" + "friendsofphp/php-cs-fixer": "^3.14", + "phpunit/phpunit": "^9.6 || ^10.0", + "spatie/phpunit-snapshot-assertions": "^4.2 || ^5.0", + "vimeo/psalm": "^5.6" }, "type": "library", "autoload": { @@ -6933,7 +7405,7 @@ ], "support": { "issues": "https://github.com/spatie/calendar-links/issues", - "source": "https://github.com/spatie/calendar-links/tree/1.8.0" + "source": "https://github.com/spatie/calendar-links/tree/1.8.5" }, "funding": [ { @@ -6941,7 +7413,7 @@ "type": "custom" } ], - "time": "2022-08-20T12:59:17+00:00" + "time": "2023-03-02T16:05:13+00:00" }, { "name": "spatie/crawler", @@ -7077,16 +7549,16 @@ }, { "name": "spatie/image-optimizer", - "version": "1.6.2", + "version": "1.6.4", "source": { "type": "git", "url": "https://github.com/spatie/image-optimizer.git", - "reference": "6db75529cbf8fa84117046a9d513f277aead90a0" + "reference": "d997e01ba980b2769ddca2f00badd3b80c2a2512" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/image-optimizer/zipball/6db75529cbf8fa84117046a9d513f277aead90a0", - "reference": "6db75529cbf8fa84117046a9d513f277aead90a0", + "url": "https://api.github.com/repos/spatie/image-optimizer/zipball/d997e01ba980b2769ddca2f00badd3b80c2a2512", + "reference": "d997e01ba980b2769ddca2f00badd3b80c2a2512", "shasum": "" }, "require": { @@ -7096,6 +7568,7 @@ "symfony/process": "^4.2|^5.0|^6.0" }, "require-dev": { + "pestphp/pest": "^1.21", "phpunit/phpunit": "^8.5.21|^9.4.4", "symfony/var-dumper": "^4.2|^5.0|^6.0" }, @@ -7125,9 +7598,9 @@ ], "support": { "issues": "https://github.com/spatie/image-optimizer/issues", - "source": "https://github.com/spatie/image-optimizer/tree/1.6.2" + "source": "https://github.com/spatie/image-optimizer/tree/1.6.4" }, - "time": "2021-12-21T10:08:05+00:00" + "time": "2023-03-10T08:43:19+00:00" }, { "name": "spatie/laravel-activitylog", @@ -7695,6 +8168,63 @@ ], "time": "2022-08-23T07:15:15+00:00" }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2023-02-22T23:07:41+00:00" + }, { "name": "swiftmailer/swiftmailer", "version": "v6.3.0", @@ -7773,16 +8303,16 @@ }, { "name": "symfony/cache", - "version": "v5.4.13", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "89bb6a0fe27205636d80e568ffaf9bbb52f691e3" + "reference": "5ed986c4ef65f0dea5e9753630b5cb1f07f847d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/89bb6a0fe27205636d80e568ffaf9bbb52f691e3", - "reference": "89bb6a0fe27205636d80e568ffaf9bbb52f691e3", + "url": "https://api.github.com/repos/symfony/cache/zipball/5ed986c4ef65f0dea5e9753630b5cb1f07f847d6", + "reference": "5ed986c4ef65f0dea5e9753630b5cb1f07f847d6", "shasum": "" }, "require": { @@ -7850,7 +8380,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v5.4.13" + "source": "https://github.com/symfony/cache/tree/v5.4.22" }, "funding": [ { @@ -7866,7 +8396,7 @@ "type": "tidelift" } ], - "time": "2022-09-06T13:23:31+00:00" + "time": "2023-03-29T20:01:08+00:00" }, { "name": "symfony/cache-contracts", @@ -7949,16 +8479,16 @@ }, { "name": "symfony/console", - "version": "v5.4.14", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "984ea2c0f45f42dfed01d2f3987b187467c4b16d" + "reference": "3cd51fd2e6c461ca678f84d419461281bd87a0a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/984ea2c0f45f42dfed01d2f3987b187467c4b16d", - "reference": "984ea2c0f45f42dfed01d2f3987b187467c4b16d", + "url": "https://api.github.com/repos/symfony/console/zipball/3cd51fd2e6c461ca678f84d419461281bd87a0a8", + "reference": "3cd51fd2e6c461ca678f84d419461281bd87a0a8", "shasum": "" }, "require": { @@ -8023,12 +8553,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.14" + "source": "https://github.com/symfony/console/tree/v5.4.22" }, "funding": [ { @@ -8044,20 +8574,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-03-25T09:27:28+00:00" }, { "name": "symfony/css-selector", - "version": "v6.1.3", + "version": "v6.2.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443" + "reference": "aedf3cb0f5b929ec255d96bbb4909e9932c769e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/0dd5e36b80e1de97f8f74ed7023ac2b837a36443", - "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/aedf3cb0f5b929ec255d96bbb4909e9932c769e0", + "reference": "aedf3cb0f5b929ec255d96bbb4909e9932c769e0", "shasum": "" }, "require": { @@ -8093,7 +8623,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.1.3" + "source": "https://github.com/symfony/css-selector/tree/v6.2.7" }, "funding": [ { @@ -8109,7 +8639,7 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2023-02-14T08:44:56+00:00" }, { "name": "symfony/deprecation-contracts", @@ -8180,16 +8710,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v5.4.12", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "291c1e92281a09152dda089f782e23dedd34bd4f" + "reference": "4c633facee8da59998e0c90e337a586cf07a21e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/291c1e92281a09152dda089f782e23dedd34bd4f", - "reference": "291c1e92281a09152dda089f782e23dedd34bd4f", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4c633facee8da59998e0c90e337a586cf07a21e7", + "reference": "4c633facee8da59998e0c90e337a586cf07a21e7", "shasum": "" }, "require": { @@ -8235,7 +8765,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v5.4.12" + "source": "https://github.com/symfony/dom-crawler/tree/v5.4.22" }, "funding": [ { @@ -8251,20 +8781,20 @@ "type": "tidelift" } ], - "time": "2022-08-03T13:09:21+00:00" + "time": "2023-03-06T21:29:33+00:00" }, { "name": "symfony/error-handler", - "version": "v5.4.14", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "5fe6d42ffeb68b094df8fdbf3acf23f391cc6be0" + "reference": "56a94aa8cb5a5fbc411551d8d014a296b5456549" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/5fe6d42ffeb68b094df8fdbf3acf23f391cc6be0", - "reference": "5fe6d42ffeb68b094df8fdbf3acf23f391cc6be0", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/56a94aa8cb5a5fbc411551d8d014a296b5456549", + "reference": "56a94aa8cb5a5fbc411551d8d014a296b5456549", "shasum": "" }, "require": { @@ -8306,7 +8836,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.4.14" + "source": "https://github.com/symfony/error-handler/tree/v5.4.21" }, "funding": [ { @@ -8322,20 +8852,20 @@ "type": "tidelift" } ], - "time": "2022-10-03T15:15:50+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.1.0", + "version": "v6.2.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347" + "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a0449a7ad7daa0f7c0acd508259f80544ab5a347", - "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339", + "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339", "shasum": "" }, "require": { @@ -8389,7 +8919,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.1.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.8" }, "funding": [ { @@ -8405,20 +8935,20 @@ "type": "tidelift" } ], - "time": "2022-05-05T16:51:07+00:00" + "time": "2023-03-20T16:06:02+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.1.1", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "02ff5eea2f453731cfbc6bc215e456b781480448" + "reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/02ff5eea2f453731cfbc6bc215e456b781480448", - "reference": "02ff5eea2f453731cfbc6bc215e456b781480448", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ad3b6f1e4e2da5690fefe075cd53a238646d8dd", + "reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd", "shasum": "" }, "require": { @@ -8431,7 +8961,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -8468,7 +8998,70 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-03-01T10:32:47+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "82b6c62b959f642d000456f08c6d219d749215b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/82b6c62b959f642d000456f08c6d219d749215b3", + "reference": "82b6c62b959f642d000456f08c6d219d749215b3", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.2.7" }, "funding": [ { @@ -8484,20 +9077,20 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2023-02-14T08:44:56+00:00" }, { "name": "symfony/finder", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", + "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19", + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19", "shasum": "" }, "require": { @@ -8531,7 +9124,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.11" + "source": "https://github.com/symfony/finder/tree/v5.4.21" }, "funding": [ { @@ -8547,25 +9140,26 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:37:50+00:00" + "time": "2023-02-16T09:33:00+00:00" }, { "name": "symfony/http-client", - "version": "v6.1.6", + "version": "v6.2.8", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "c8c887f4813370550147afd27d9eb8a8523e53b2" + "reference": "66391ba3a8862c560e1d9134c96d9bd2a619b477" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/c8c887f4813370550147afd27d9eb8a8523e53b2", - "reference": "c8c887f4813370550147afd27d9eb8a8523e53b2", + "url": "https://api.github.com/repos/symfony/http-client/zipball/66391ba3a8862c560e1d9134c96d9bd2a619b477", + "reference": "66391ba3a8862c560e1d9134c96d9bd2a619b477", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/http-client-contracts": "^3", "symfony/service-contracts": "^1.0|^2|^3" }, @@ -8614,8 +9208,11 @@ ], "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", + "keywords": [ + "http" + ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.1.6" + "source": "https://github.com/symfony/http-client/tree/v6.2.8" }, "funding": [ { @@ -8631,20 +9228,20 @@ "type": "tidelift" } ], - "time": "2022-10-12T05:10:31+00:00" + "time": "2023-03-31T09:14:44+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.1.1", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800" + "reference": "df2ecd6cb70e73c1080e6478aea85f5f4da2c48b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/fd038f08c623ab5d22b26e9ba35afe8c79071800", - "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/df2ecd6cb70e73c1080e6478aea85f5f4da2c48b", + "reference": "df2ecd6cb70e73c1080e6478aea85f5f4da2c48b", "shasum": "" }, "require": { @@ -8656,7 +9253,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -8696,7 +9293,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.2.1" }, "funding": [ { @@ -8712,20 +9309,20 @@ "type": "tidelift" } ], - "time": "2022-04-22T07:30:54+00:00" + "time": "2023-03-01T10:32:47+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.4.14", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e7c7b395c3a61d746919c21e915f51f0039c3f75" + "reference": "05cd1acdd0e3ce8473aaba1d86c188321d85f313" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e7c7b395c3a61d746919c21e915f51f0039c3f75", - "reference": "e7c7b395c3a61d746919c21e915f51f0039c3f75", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/05cd1acdd0e3ce8473aaba1d86c188321d85f313", + "reference": "05cd1acdd0e3ce8473aaba1d86c188321d85f313", "shasum": "" }, "require": { @@ -8772,7 +9369,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.14" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.22" }, "funding": [ { @@ -8788,20 +9385,20 @@ "type": "tidelift" } ], - "time": "2022-10-01T21:59:28+00:00" + "time": "2023-03-28T07:28:17+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.14", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "6f77fabc1a37c2dceecc6f78cca44772705dc52f" + "reference": "2d3a8be2c756353627398827c409af6f126c096d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6f77fabc1a37c2dceecc6f78cca44772705dc52f", - "reference": "6f77fabc1a37c2dceecc6f78cca44772705dc52f", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2d3a8be2c756353627398827c409af6f126c096d", + "reference": "2d3a8be2c756353627398827c409af6f126c096d", "shasum": "" }, "require": { @@ -8810,7 +9407,7 @@ "symfony/deprecation-contracts": "^2.1|^3", "symfony/error-handler": "^4.4|^5.0|^6.0", "symfony/event-dispatcher": "^5.0|^6.0", - "symfony/http-foundation": "^5.3.7|^6.0", + "symfony/http-foundation": "^5.4.21|^6.2.7", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", "symfony/polyfill-php80": "^1.16" @@ -8884,7 +9481,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.14" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.22" }, "funding": [ { @@ -8900,20 +9497,20 @@ "type": "tidelift" } ], - "time": "2022-10-12T07:12:21+00:00" + "time": "2023-03-31T11:54:37+00:00" }, { "name": "symfony/mime", - "version": "v5.4.14", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "1c118b253bb3495d81e95a6e3ec6c2766a98a0c4" + "reference": "ef57d9fb9cdd5e6b2ffc567d109865d10b6920cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/1c118b253bb3495d81e95a6e3ec6c2766a98a0c4", - "reference": "1c118b253bb3495d81e95a6e3ec6c2766a98a0c4", + "url": "https://api.github.com/repos/symfony/mime/zipball/ef57d9fb9cdd5e6b2ffc567d109865d10b6920cd", + "reference": "ef57d9fb9cdd5e6b2ffc567d109865d10b6920cd", "shasum": "" }, "require": { @@ -8931,7 +9528,7 @@ "symfony/serializer": "<5.4.14|>=6.0,<6.0.14|>=6.1,<6.1.6" }, "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1", + "egulias/email-validator": "^2.1.10|^3.1|^4", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/property-access": "^4.4|^5.1|^6.0", @@ -8968,7 +9565,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.14" + "source": "https://github.com/symfony/mime/tree/v5.4.21" }, "funding": [ { @@ -8984,20 +9581,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-02-21T19:46:44+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.1.0", + "version": "v6.2.7", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4" + "reference": "aa0e85b53bbb2b4951960efd61d295907eacd629" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a3016f5442e28386ded73c43a32a5b68586dd1c4", - "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/aa0e85b53bbb2b4951960efd61d295907eacd629", + "reference": "aa0e85b53bbb2b4951960efd61d295907eacd629", "shasum": "" }, "require": { @@ -9035,7 +9632,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.1.0" + "source": "https://github.com/symfony/options-resolver/tree/v6.2.7" }, "funding": [ { @@ -9051,20 +9648,20 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2023-02-14T08:44:56+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "shasum": "" }, "require": { @@ -9079,7 +9676,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9117,7 +9714,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" }, "funding": [ { @@ -9133,20 +9730,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "143f1881e655bebca1312722af8068de235ae5dc" + "reference": "927013f3aac555983a5059aada98e1907d842695" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/143f1881e655bebca1312722af8068de235ae5dc", - "reference": "143f1881e655bebca1312722af8068de235ae5dc", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/927013f3aac555983a5059aada98e1907d842695", + "reference": "927013f3aac555983a5059aada98e1907d842695", "shasum": "" }, "require": { @@ -9161,7 +9758,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9200,7 +9797,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.27.0" }, "funding": [ { @@ -9216,20 +9813,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "433d05519ce6990bf3530fba6957499d327395c2" + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", - "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", "shasum": "" }, "require": { @@ -9241,7 +9838,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9281,7 +9878,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" }, "funding": [ { @@ -9297,20 +9894,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8" + "reference": "639084e360537a19f9ee352433b84ce831f3d2da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da", "shasum": "" }, "require": { @@ -9324,7 +9921,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9368,7 +9965,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" }, "funding": [ { @@ -9384,20 +9981,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "shasum": "" }, "require": { @@ -9409,7 +10006,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9452,7 +10049,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" }, "funding": [ { @@ -9468,20 +10065,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "shasum": "" }, "require": { @@ -9496,7 +10093,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9535,7 +10132,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" }, "funding": [ { @@ -9551,20 +10148,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", "shasum": "" }, "require": { @@ -9573,7 +10170,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9611,7 +10208,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" }, "funding": [ { @@ -9627,20 +10224,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", "shasum": "" }, "require": { @@ -9649,7 +10246,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9690,7 +10287,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0" }, "funding": [ { @@ -9706,20 +10303,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "shasum": "" }, "require": { @@ -9728,7 +10325,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9773,7 +10370,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" }, "funding": [ { @@ -9789,20 +10386,20 @@ "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", "shasum": "" }, "require": { @@ -9811,7 +10408,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -9852,7 +10449,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" }, "funding": [ { @@ -9868,20 +10465,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/process", - "version": "v5.4.11", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" + "reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", + "url": "https://api.github.com/repos/symfony/process/zipball/4b850da0cc3a2a9181c1ed407adbca4733dc839b", + "reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b", "shasum": "" }, "require": { @@ -9914,7 +10511,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.11" + "source": "https://github.com/symfony/process/tree/v5.4.22" }, "funding": [ { @@ -9930,20 +10527,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2023-03-06T21:29:33+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v2.1.3", + "version": "v2.1.4", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "d444f85dddf65c7e57c58d8e5b3a4dbb593b1840" + "reference": "a125b93ef378c492e274f217874906fb9babdebb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/d444f85dddf65c7e57c58d8e5b3a4dbb593b1840", - "reference": "d444f85dddf65c7e57c58d8e5b3a4dbb593b1840", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/a125b93ef378c492e274f217874906fb9babdebb", + "reference": "a125b93ef378c492e274f217874906fb9babdebb", "shasum": "" }, "require": { @@ -10002,7 +10599,7 @@ ], "support": { "issues": "https://github.com/symfony/psr-http-message-bridge/issues", - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.3" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.4" }, "funding": [ { @@ -10018,20 +10615,20 @@ "type": "tidelift" } ], - "time": "2022-09-05T10:34:54+00:00" + "time": "2022-11-28T22:46:34+00:00" }, { "name": "symfony/routing", - "version": "v5.4.11", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226" + "reference": "c2ac11eb34947999b7c38fb4c835a57306907e6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/3e01ccd9b2a3a4167ba2b3c53612762300300226", - "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226", + "url": "https://api.github.com/repos/symfony/routing/zipball/c2ac11eb34947999b7c38fb4c835a57306907e6d", + "reference": "c2ac11eb34947999b7c38fb4c835a57306907e6d", "shasum": "" }, "require": { @@ -10046,7 +10643,7 @@ "symfony/yaml": "<4.4" }, "require-dev": { - "doctrine/annotations": "^1.12", + "doctrine/annotations": "^1.12|^2", "psr/log": "^1|^2|^3", "symfony/config": "^5.3|^6.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", @@ -10092,7 +10689,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v5.4.11" + "source": "https://github.com/symfony/routing/tree/v5.4.22" }, "funding": [ { @@ -10108,7 +10705,7 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2023-03-14T14:59:20+00:00" }, { "name": "symfony/service-contracts", @@ -10156,26 +10753,88 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-30T19:17:29+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "f3adc98c1061875dd2edcd45e5b04e63d0e29f8f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f3adc98c1061875dd2edcd45e5b04e63d0e29f8f", + "reference": "f3adc98c1061875dd2edcd45e5b04e63d0e29f8f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/service-contracts": "^1|^2|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to writing services", + "description": "Provides a way to profile code", "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/stopwatch/tree/v6.2.7" }, "funding": [ { @@ -10191,20 +10850,20 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:29+00:00" + "time": "2023-02-14T08:44:56+00:00" }, { "name": "symfony/string", - "version": "v6.1.6", + "version": "v6.2.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "7e7e0ff180d4c5a6636eaad57b65092014b61864" + "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/7e7e0ff180d4c5a6636eaad57b65092014b61864", - "reference": "7e7e0ff180d4c5a6636eaad57b65092014b61864", + "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef", + "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef", "shasum": "" }, "require": { @@ -10220,6 +10879,7 @@ "require-dev": { "symfony/error-handler": "^5.4|^6.0", "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", "symfony/translation-contracts": "^2.0|^3.0", "symfony/var-exporter": "^5.4|^6.0" }, @@ -10260,7 +10920,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.1.6" + "source": "https://github.com/symfony/string/tree/v6.2.8" }, "funding": [ { @@ -10276,20 +10936,20 @@ "type": "tidelift" } ], - "time": "2022-10-10T09:34:31+00:00" + "time": "2023-03-20T16:06:02+00:00" }, { "name": "symfony/translation", - "version": "v6.1.6", + "version": "v6.2.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "e6cd330e5a072518f88d65148f3f165541807494" + "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/e6cd330e5a072518f88d65148f3f165541807494", - "reference": "e6cd330e5a072518f88d65148f3f165541807494", + "url": "https://api.github.com/repos/symfony/translation/zipball/817535dbb1721df8b3a8f2489dc7e50bcd6209b5", + "reference": "817535dbb1721df8b3a8f2489dc7e50bcd6209b5", "shasum": "" }, "require": { @@ -10309,6 +10969,7 @@ "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { + "nikic/php-parser": "^4.13", "psr/log": "^1|^2|^3", "symfony/config": "^5.4|^6.0", "symfony/console": "^5.4|^6.0", @@ -10323,6 +10984,7 @@ "symfony/yaml": "^5.4|^6.0" }, "suggest": { + "nikic/php-parser": "To use PhpAstExtractor", "psr/log-implementation": "To use logging capability in translator", "symfony/config": "", "symfony/yaml": "" @@ -10356,7 +11018,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.1.6" + "source": "https://github.com/symfony/translation/tree/v6.2.8" }, "funding": [ { @@ -10372,20 +11034,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:04:03+00:00" + "time": "2023-03-31T09:14:44+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.1.1", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc" + "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/606be0f48e05116baef052f7f3abdb345c8e02cc", - "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dfec258b9dd17a6b24420d464c43bffe347441c8", + "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8", "shasum": "" }, "require": { @@ -10397,7 +11059,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -10437,7 +11099,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.2.1" }, "funding": [ { @@ -10453,20 +11115,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2023-03-01T10:32:47+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.4.14", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "6894d06145fefebd9a4c7272baa026a1c394a430" + "reference": "e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/6894d06145fefebd9a4c7272baa026a1c394a430", - "reference": "6894d06145fefebd9a4c7272baa026a1c394a430", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4", + "reference": "e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4", "shasum": "" }, "require": { @@ -10526,7 +11188,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.14" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.22" }, "funding": [ { @@ -10542,20 +11204,20 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:01:20+00:00" + "time": "2023-03-25T09:27:28+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.1.3", + "version": "v6.2.8", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "b49350f45cebbba6e5286485264b912f2bcfc9ef" + "reference": "8302bb670204500d492c6b8c595ee9a27da62cd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b49350f45cebbba6e5286485264b912f2bcfc9ef", - "reference": "b49350f45cebbba6e5286485264b912f2bcfc9ef", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/8302bb670204500d492c6b8c595ee9a27da62cd6", + "reference": "8302bb670204500d492c6b8c595ee9a27da62cd6", "shasum": "" }, "require": { @@ -10595,10 +11257,12 @@ "export", "hydrate", "instantiate", + "lazy-loading", + "proxy", "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.1.3" + "source": "https://github.com/symfony/var-exporter/tree/v6.2.8" }, "funding": [ { @@ -10614,20 +11278,20 @@ "type": "tidelift" } ], - "time": "2022-07-04T16:01:56+00:00" + "time": "2023-03-14T15:48:45+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", - "version": "2.2.5", + "version": "2.2.6", "source": { "type": "git", "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19" + "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/4348a3a06651827a27d989ad1d13efec6bb49b19", - "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/c42125b83a4fa63b187fdf29f9c93cb7733da30c", + "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c", "shasum": "" }, "require": { @@ -10665,9 +11329,9 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "support": { "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.5" + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.6" }, - "time": "2022-09-12T13:28:28+00:00" + "time": "2023-01-03T09:29:04+00:00" }, { "name": "vendor/package-patches", @@ -10861,283 +11525,24 @@ }, "require": { "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - }, - { - "name": "yeslogic/prince-php-wrapper", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/yeslogic/prince-php-wrapper.git", - "reference": "fd7b974e1251d1fbcdc30a261897d5ccb3fd5447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/yeslogic/prince-php-wrapper/zipball/fd7b974e1251d1fbcdc30a261897d5ccb3fd5447", - "reference": "fd7b974e1251d1fbcdc30a261897d5ccb3fd5447", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Prince\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Day", - "email": "mikeday@yeslogic.com" - } - ], - "description": "PHP wrapper class for Prince HTML to PDF formatter", - "support": { - "issues": "https://github.com/yeslogic/prince-php-wrapper/issues", - "source": "https://github.com/yeslogic/prince-php-wrapper/tree/1.5.0" - }, - "time": "2023-02-09T02:22:09+00:00" - } - ], - "packages-dev": [ - { - "name": "brianium/paratest", - "version": "v6.6.4", - "source": { - "type": "git", - "url": "https://github.com/paratestphp/paratest.git", - "reference": "4ce800dc32fd0292a4f05c00f347142dce1ecdda" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/4ce800dc32fd0292a4f05c00f347142dce1ecdda", - "reference": "4ce800dc32fd0292a4f05c00f347142dce1ecdda", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-simplexml": "*", - "jean85/pretty-package-versions": "^2.0.5", - "php": "^7.3 || ^8.0", - "phpunit/php-code-coverage": "^9.2.17", - "phpunit/php-file-iterator": "^3.0.6", - "phpunit/php-timer": "^5.0.3", - "phpunit/phpunit": "^9.5.24", - "sebastian/environment": "^5.1.4", - "symfony/console": "^5.4.12 || ^6.1.4", - "symfony/process": "^5.4.11 || ^6.1.3" - }, - "require-dev": { - "doctrine/coding-standard": "^10.0.0", - "ext-pcov": "*", - "ext-posix": "*", - "infection/infection": "^0.26.14", - "malukenho/mcbumpface": "^1.1.5", - "squizlabs/php_codesniffer": "^3.7.1", - "symfony/filesystem": "^5.4.12 || ^6.1.4", - "vimeo/psalm": "^4.27.0" - }, - "bin": [ - "bin/paratest", - "bin/paratest.bat", - "bin/paratest_for_phpstorm" - ], - "type": "library", - "autoload": { - "psr-4": { - "ParaTest\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brian Scaturro", - "email": "scaturrob@gmail.com", - "role": "Developer" - }, - { - "name": "Filippo Tessarotto", - "email": "zoeslam@gmail.com", - "role": "Developer" - } - ], - "description": "Parallel testing for PHP", - "homepage": "https://github.com/paratestphp/paratest", - "keywords": [ - "concurrent", - "parallel", - "phpunit", - "testing" - ], - "support": { - "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v6.6.4" - }, - "funding": [ - { - "url": "https://github.com/sponsors/Slamdunk", - "type": "github" - }, - { - "url": "https://paypal.me/filippotessarotto", - "type": "paypal" - } - ], - "time": "2022-09-13T10:47:01+00:00" - }, - { - "name": "composer/pcre", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], - "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.0.0" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-02-25T20:21:48+00:00" - }, - { - "name": "composer/semver", - "version": "3.3.2", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", - "shasum": "" + "php": "^7.2 || ^8.0" }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpunit/phpunit": "^8.5.13" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.x-dev" + "dev-master": "1.10-dev" } }, "autoload": { "psr-4": { - "Composer\\Semver\\": "src" + "Webmozart\\Assert\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -11146,77 +11551,43 @@ ], "authors": [ { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", + "description": "Assertions to validate method input/output with nice error messages.", "keywords": [ - "semantic", - "semver", - "validation", - "versioning" + "assert", + "check", + "validate" ], "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-04-01T19:23:25+00:00" + "time": "2022-06-03T18:03:27+00:00" }, { - "name": "composer/xdebug-handler", - "version": "3.0.3", + "name": "yeslogic/prince-php-wrapper", + "version": "1.5.0", "source": { "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" + "url": "https://github.com/yeslogic/prince-php-wrapper.git", + "reference": "fd7b974e1251d1fbcdc30a261897d5ccb3fd5447" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "url": "https://api.github.com/repos/yeslogic/prince-php-wrapper/zipball/fd7b974e1251d1fbcdc30a261897d5ccb3fd5447", + "reference": "fd7b974e1251d1fbcdc30a261897d5ccb3fd5447", "shasum": "" }, "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" - }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" + "php": ">=5.3.0" }, "type": "library", "autoload": { "psr-4": { - "Composer\\XdebugHandler\\": "src" + "Prince\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -11225,68 +11596,69 @@ ], "authors": [ { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" + "name": "Michael Day", + "email": "mikeday@yeslogic.com" } ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], + "description": "PHP wrapper class for Prince HTML to PDF formatter", "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + "issues": "https://github.com/yeslogic/prince-php-wrapper/issues", + "source": "https://github.com/yeslogic/prince-php-wrapper/tree/1.5.0" }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-02-25T21:32:43+00:00" - }, + "time": "2023-02-09T02:22:09+00:00" + } + ], + "packages-dev": [ { - "name": "doctrine/annotations", - "version": "1.13.3", + "name": "brianium/paratest", + "version": "v6.9.1", "source": { "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "648b0343343565c4a056bfc8392201385e8d89f0" + "url": "https://github.com/paratestphp/paratest.git", + "reference": "51691208db882922c55d6c465be3e7d95028c449" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", - "reference": "648b0343343565c4a056bfc8392201385e8d89f0", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/51691208db882922c55d6c465be3e7d95028c449", + "reference": "51691208db882922c55d6c465be3e7d95028c449", "shasum": "" }, "require": { - "doctrine/lexer": "1.*", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-simplexml": "*", + "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1", + "jean85/pretty-package-versions": "^2.0.5", + "php": "^7.3 || ^8.0", + "phpunit/php-code-coverage": "^9.2.25", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-timer": "^5.0.3", + "phpunit/phpunit": "^9.6.4", + "sebastian/environment": "^5.1.5", + "symfony/console": "^5.4.21 || ^6.2.7", + "symfony/process": "^5.4.21 || ^6.2.7" }, "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^1.4.10 || ^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2", - "vimeo/psalm": "^4.10" + "doctrine/coding-standard": "^10.0.0", + "ext-pcov": "*", + "ext-posix": "*", + "infection/infection": "^0.26.19", + "squizlabs/php_codesniffer": "^3.7.2", + "symfony/filesystem": "^5.4.21 || ^6.2.7", + "vimeo/psalm": "^5.7.7" }, + "bin": [ + "bin/paratest", + "bin/paratest.bat", + "bin/paratest_for_phpstorm" + ], "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + "ParaTest\\": [ + "src/" + ] } }, "notification-url": "https://packagist.org/downloads/", @@ -11295,65 +11667,66 @@ ], "authors": [ { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" }, { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" } ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", "keywords": [ - "annotations", - "docblock", - "parser" + "concurrent", + "parallel", + "phpunit", + "testing" ], "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.3" + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v6.9.1" }, - "time": "2022-07-02T10:48:51+00:00" + "funding": [ + { + "url": "https://github.com/sponsors/Slamdunk", + "type": "github" + }, + { + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" + } + ], + "time": "2023-03-03T09:35:17+00:00" }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -11380,7 +11753,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -11396,7 +11769,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "facade/flare-client-php", @@ -11465,16 +11838,16 @@ }, { "name": "facade/ignition", - "version": "2.17.6", + "version": "2.17.7", "source": { "type": "git", "url": "https://github.com/facade/ignition.git", - "reference": "6acd82e986a2ecee89e2e68adfc30a1936d1ab7c" + "reference": "b4f5955825bb4b74cba0f94001761c46335c33e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facade/ignition/zipball/6acd82e986a2ecee89e2e68adfc30a1936d1ab7c", - "reference": "6acd82e986a2ecee89e2e68adfc30a1936d1ab7c", + "url": "https://api.github.com/repos/facade/ignition/zipball/b4f5955825bb4b74cba0f94001761c46335c33e9", + "reference": "b4f5955825bb4b74cba0f94001761c46335c33e9", "shasum": "" }, "require": { @@ -11539,7 +11912,7 @@ "issues": "https://github.com/facade/ignition/issues", "source": "https://github.com/facade/ignition" }, - "time": "2022-06-30T18:26:59+00:00" + "time": "2023-01-26T12:34:59+00:00" }, { "name": "facade/ignition-contracts", @@ -11596,20 +11969,20 @@ }, { "name": "fakerphp/faker", - "version": "v1.20.0", + "version": "v1.21.0", "source": { "type": "git", "url": "https://github.com/FakerPHP/Faker.git", - "reference": "37f751c67a5372d4e26353bd9384bc03744ec77b" + "reference": "92efad6a967f0b79c499705c69b662f738cc9e4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/37f751c67a5372d4e26353bd9384bc03744ec77b", - "reference": "37f751c67a5372d4e26353bd9384bc03744ec77b", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/92efad6a967f0b79c499705c69b662f738cc9e4d", + "reference": "92efad6a967f0b79c499705c69b662f738cc9e4d", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0", + "php": "^7.4 || ^8.0", "psr/container": "^1.0 || ^2.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" }, @@ -11620,7 +11993,8 @@ "bamarni/composer-bin-plugin": "^1.4.1", "doctrine/persistence": "^1.3 || ^2.0", "ext-intl": "*", - "symfony/phpunit-bridge": "^4.4 || ^5.2" + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" }, "suggest": { "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", @@ -11632,7 +12006,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "v1.20-dev" + "dev-main": "v1.21-dev" } }, "autoload": { @@ -11657,46 +12031,42 @@ ], "support": { "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.20.0" + "source": "https://github.com/FakerPHP/Faker/tree/v1.21.0" }, - "time": "2022-07-20T13:12:54+00:00" + "time": "2022-12-13T13:54:32+00:00" }, { - "name": "filp/whoops", - "version": "2.14.5", + "name": "fidry/cpu-core-counter", + "version": "0.5.1", "source": { "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/b58e5a3933e541dc286cc91fc4f3898bbc6f1623", + "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623", "shasum": "" }, "require": { - "php": "^5.5.9 || ^7.0 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "mockery/mockery": "^0.9 || ^1.0", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" + "fidry/makefile": "^0.2.0", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^9.5.26 || ^8.5.31", + "theofidry/php-cs-fixer-config": "^1.0", + "webmozarts/strict-phpunit": "^7.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, "autoload": { "psr-4": { - "Whoops\\": "src/Whoops/" + "Fidry\\CpuCoreCounter\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -11705,93 +12075,63 @@ ], "authors": [ { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" } ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", + "description": "Tiny utility to get the number of CPU cores.", "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" + "CPU", + "core" ], "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.5" + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/0.5.1" }, "funding": [ { - "url": "https://github.com/denis-sokolov", + "url": "https://github.com/theofidry", "type": "github" } ], - "time": "2022-01-07T12:00:00+00:00" + "time": "2022-12-24T12:35:10+00:00" }, { - "name": "friendsofphp/php-cs-fixer", - "version": "v3.12.0", + "name": "filp/whoops", + "version": "2.15.1", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "eae11d945e2885d86e1c080eec1bb30a2aa27998" + "url": "https://github.com/filp/whoops.git", + "reference": "e864ac957acd66e1565f25efda61e37791a5db0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/eae11d945e2885d86e1c080eec1bb30a2aa27998", - "reference": "eae11d945e2885d86e1c080eec1bb30a2aa27998", + "url": "https://api.github.com/repos/filp/whoops/zipball/e864ac957acd66e1565f25efda61e37791a5db0b", + "reference": "e864ac957acd66e1565f25efda61e37791a5db0b", "shasum": "" }, "require": { - "composer/semver": "^3.2", - "composer/xdebug-handler": "^3.0.3", - "doctrine/annotations": "^1.13", - "ext-json": "*", - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0", - "sebastian/diff": "^4.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/event-dispatcher": "^5.4 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", - "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.25", - "symfony/polyfill-php81": "^1.25", - "symfony/process": "^5.4 || ^6.0", - "symfony/stopwatch": "^5.4 || ^6.0" + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "require-dev": { - "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^1.5", - "mikey179/vfsstream": "^1.6.10", - "php-coveralls/php-coveralls": "^2.5.2", - "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.15", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "phpunitgoodpractices/polyfill": "^1.6", - "phpunitgoodpractices/traits": "^1.9.2", - "symfony/phpunit-bridge": "^6.0", - "symfony/yaml": "^5.4 || ^6.0" + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" }, "suggest": { - "ext-dom": "For handling output formats in XML", - "ext-mbstring": "For handling non-UTF8 characters." + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", "autoload": { "psr-4": { - "PhpCsFixer\\": "src/" + "Whoops\\": "src/Whoops/" } }, "notification-url": "https://packagist.org/downloads/", @@ -11800,26 +12140,32 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" } ], - "description": "A tool to automatically fix PHP code style", + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], "support": { - "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.12.0" + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.15.1" }, "funding": [ { - "url": "https://github.com/keradus", + "url": "https://github.com/denis-sokolov", "type": "github" } ], - "time": "2022-10-12T14:20:51+00:00" + "time": "2023-03-06T18:09:13+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -11943,22 +12289,22 @@ }, { "name": "laravel/sail", - "version": "v1.16.2", + "version": "v1.19.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "7d1ed5f856ec8b9708712e3fc0708fcabe114659" + "reference": "4f230634a3163f3442def6a4e6ffdb02b02e14d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/7d1ed5f856ec8b9708712e3fc0708fcabe114659", - "reference": "7d1ed5f856ec8b9708712e3fc0708fcabe114659", + "url": "https://api.github.com/repos/laravel/sail/zipball/4f230634a3163f3442def6a4e6ffdb02b02e14d6", + "reference": "4f230634a3163f3442def6a4e6ffdb02b02e14d6", "shasum": "" }, "require": { - "illuminate/console": "^8.0|^9.0", - "illuminate/contracts": "^8.0|^9.0", - "illuminate/support": "^8.0|^9.0", + "illuminate/console": "^8.0|^9.0|^10.0", + "illuminate/contracts": "^8.0|^9.0|^10.0", + "illuminate/support": "^8.0|^9.0|^10.0", "php": "^7.3|^8.0" }, "bin": [ @@ -11999,7 +12345,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2022-09-28T13:13:22+00:00" + "time": "2023-01-31T13:37:57+00:00" }, { "name": "mockery/mockery", @@ -12075,16 +12421,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -12122,7 +12468,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -12130,7 +12476,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "nunomaduro/collision", @@ -12221,25 +12567,25 @@ }, { "name": "orchestra/testbench", - "version": "v6.25.1", + "version": "v6.27.1", "source": { "type": "git", "url": "https://github.com/orchestral/testbench.git", - "reference": "0516123d26d64117bc04f7e9cb982eae2624e750" + "reference": "b78f91f17bb86981e73dfbe786f055064c11539d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench/zipball/0516123d26d64117bc04f7e9cb982eae2624e750", - "reference": "0516123d26d64117bc04f7e9cb982eae2624e750", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/b78f91f17bb86981e73dfbe786f055064c11539d", + "reference": "b78f91f17bb86981e73dfbe786f055064c11539d", "shasum": "" }, "require": { - "laravel/framework": "^8.75", + "laravel/framework": "^8.83.26", "mockery/mockery": "^1.4.4", - "orchestra/testbench-core": "^6.29.1", + "orchestra/testbench-core": "^6.31.1", "php": "^7.3 || ^8.0", "phpunit/phpunit": "^8.5.21 || ^9.5.10", - "spatie/laravel-ray": "^1.26.2" + "spatie/laravel-ray": "^1.29.7" }, "type": "library", "extra": { @@ -12270,32 +12616,22 @@ ], "support": { "issues": "https://github.com/orchestral/testbench/issues", - "source": "https://github.com/orchestral/testbench/tree/v6.25.1" + "source": "https://github.com/orchestral/testbench/tree/v6.27.1" }, - "funding": [ - { - "url": "https://paypal.me/crynobone", - "type": "custom" - }, - { - "url": "https://liberapay.com/crynobone", - "type": "liberapay" - } - ], - "time": "2022-10-11T14:01:10+00:00" + "time": "2023-04-03T01:20:40+00:00" }, { "name": "orchestra/testbench-core", - "version": "v6.29.1", + "version": "v6.31.1", "source": { "type": "git", "url": "https://github.com/orchestral/testbench-core.git", - "reference": "29a7586915885f89b8d2203efe20f76afe9cf956" + "reference": "8c6dfa9522d68788398d547fcb4af0cb29adb1f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/29a7586915885f89b8d2203efe20f76afe9cf956", - "reference": "29a7586915885f89b8d2203efe20f76afe9cf956", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/8c6dfa9522d68788398d547fcb4af0cb29adb1f2", + "reference": "8c6dfa9522d68788398d547fcb4af0cb29adb1f2", "shasum": "" }, "require": { @@ -12305,7 +12641,7 @@ "vlucas/phpdotenv": "^5.1" }, "require-dev": { - "laravel/framework": "^8.75", + "laravel/framework": "^8.83.27", "laravel/laravel": "8.x-dev", "mockery/mockery": "^1.4.4", "orchestra/canvas": "^6.1", @@ -12314,7 +12650,7 @@ "symfony/process": "^5.0" }, "suggest": { - "laravel/framework": "Required for testing (^8.75).", + "laravel/framework": "Required for testing (^8.83.26).", "mockery/mockery": "Allow using Mockery for testing (^1.4.4).", "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^6.0).", "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^6.0).", @@ -12353,26 +12689,16 @@ "keywords": [ "BDD", "TDD", + "dev", "laravel", - "orchestra-platform", - "orchestral", + "laravel-packages", "testing" ], "support": { "issues": "https://github.com/orchestral/testbench/issues", "source": "https://github.com/orchestral/testbench-core" }, - "funding": [ - { - "url": "https://paypal.me/crynobone", - "type": "custom" - }, - { - "url": "https://liberapay.com/crynobone", - "type": "liberapay" - } - ], - "time": "2022-10-11T12:12:52+00:00" + "time": "2023-04-02T16:02:01+00:00" }, { "name": "phar-io/manifest", @@ -12487,23 +12813,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "9.2.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -12518,8 +12844,8 @@ "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "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": { @@ -12552,7 +12878,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" }, "funding": [ { @@ -12560,7 +12886,7 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2023-03-06T12:58:08+00:00" }, { "name": "phpunit/php-file-iterator", @@ -12805,20 +13131,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.25", + "version": "9.6.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d" + "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b65d59a059d3004a040c16a82e07bbdf6cfdd115", + "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -12847,8 +13173,8 @@ "sebastian/version": "^3.0.2" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -12856,7 +13182,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -12887,7 +13213,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.25" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.6" }, "funding": [ { @@ -12903,7 +13230,7 @@ "type": "tidelift" } ], - "time": "2022-09-25T03:44:45+00:00" + "time": "2023-03-27T11:43:46+00:00" }, { "name": "pimple/pimple", @@ -13256,84 +13583,18 @@ ], "time": "2020-10-26T15:52:27+00:00" }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -13375,7 +13636,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -13383,7 +13644,7 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", @@ -13697,16 +13958,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -13745,10 +14006,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -13756,7 +14017,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -13815,16 +14076,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -13859,7 +14120,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -13867,7 +14128,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -13924,16 +14185,16 @@ }, { "name": "spatie/backtrace", - "version": "1.2.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/spatie/backtrace.git", - "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b" + "reference": "ec4dd16476b802dbdc6b4467f84032837e316b8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", - "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/ec4dd16476b802dbdc6b4467f84032837e316b8c", + "reference": "ec4dd16476b802dbdc6b4467f84032837e316b8c", "shasum": "" }, "require": { @@ -13942,6 +14203,7 @@ "require-dev": { "ext-json": "*", "phpunit/phpunit": "^9.3", + "spatie/phpunit-snapshot-assertions": "^4.2", "symfony/var-dumper": "^5.1" }, "type": "library", @@ -13969,8 +14231,7 @@ "spatie" ], "support": { - "issues": "https://github.com/spatie/backtrace/issues", - "source": "https://github.com/spatie/backtrace/tree/1.2.1" + "source": "https://github.com/spatie/backtrace/tree/1.4.0" }, "funding": [ { @@ -13982,41 +14243,42 @@ "type": "other" } ], - "time": "2021-11-09T10:57:15+00:00" + "time": "2023-03-04T08:57:24+00:00" }, { "name": "spatie/laravel-ray", - "version": "1.31.0", + "version": "1.32.4", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ray.git", - "reference": "7394694afd89d05879e7a69c54abab73c1199acd" + "reference": "2274653f0a90dd87fbb887437be1c1ea1388a47c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/7394694afd89d05879e7a69c54abab73c1199acd", - "reference": "7394694afd89d05879e7a69c54abab73c1199acd", + "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/2274653f0a90dd87fbb887437be1c1ea1388a47c", + "reference": "2274653f0a90dd87fbb887437be1c1ea1388a47c", "shasum": "" }, "require": { "ext-json": "*", - "illuminate/contracts": "^7.20|^8.19|^9.0", - "illuminate/database": "^7.20|^8.19|^9.0", - "illuminate/queue": "^7.20|^8.19|^9.0", - "illuminate/support": "^7.20|^8.19|^9.0", - "php": "^7.3|^8.0", + "illuminate/contracts": "^7.20|^8.19|^9.0|^10.0", + "illuminate/database": "^7.20|^8.19|^9.0|^10.0", + "illuminate/queue": "^7.20|^8.19|^9.0|^10.0", + "illuminate/support": "^7.20|^8.19|^9.0|^10.0", + "php": "^7.4|^8.0", "spatie/backtrace": "^1.0", - "spatie/ray": "^1.33", + "spatie/ray": "^1.37", "symfony/stopwatch": "4.2|^5.1|^6.0", "zbateson/mail-mime-parser": "^1.3.1|^2.0" }, "require-dev": { "guzzlehttp/guzzle": "^7.3", - "laravel/framework": "^7.20|^8.19|^9.0", - "orchestra/testbench-core": "^5.0|^6.0|^7.0", + "laravel/framework": "^7.20|^8.19|^9.0|^10.0", + "orchestra/testbench-core": "^5.0|^6.0|^7.0|^8.0", + "pestphp/pest": "^1.22", "phpstan/phpstan": "^0.12.93", "phpunit/phpunit": "^9.3", - "spatie/phpunit-snapshot-assertions": "^4.2" + "spatie/pest-plugin-snapshots": "^1.1" }, "type": "library", "extra": { @@ -14054,7 +14316,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-ray/issues", - "source": "https://github.com/spatie/laravel-ray/tree/1.31.0" + "source": "https://github.com/spatie/laravel-ray/tree/1.32.4" }, "funding": [ { @@ -14066,7 +14328,7 @@ "type": "other" } ], - "time": "2022-09-20T13:13:22+00:00" + "time": "2023-03-23T08:04:54+00:00" }, { "name": "spatie/macroable", @@ -14120,16 +14382,16 @@ }, { "name": "spatie/ray", - "version": "1.36.0", + "version": "1.37.1", "source": { "type": "git", "url": "https://github.com/spatie/ray.git", - "reference": "4a4def8cda4806218341b8204c98375aa8c34323" + "reference": "a915e327f04c0fbed3bdd26e076e39feea091062" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ray/zipball/4a4def8cda4806218341b8204c98375aa8c34323", - "reference": "4a4def8cda4806218341b8204c98375aa8c34323", + "url": "https://api.github.com/repos/spatie/ray/zipball/a915e327f04c0fbed3bdd26e076e39feea091062", + "reference": "a915e327f04c0fbed3bdd26e076e39feea091062", "shasum": "" }, "require": { @@ -14144,8 +14406,9 @@ }, "require-dev": { "illuminate/support": "6.x|^8.18|^9.0", - "nesbot/carbon": "^2.43", - "phpstan/phpstan": "^0.12.92", + "nesbot/carbon": "^2.63", + "pestphp/pest": "^1.22", + "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.5", "spatie/phpunit-snapshot-assertions": "^4.2", "spatie/test-time": "^1.2" @@ -14179,7 +14442,7 @@ ], "support": { "issues": "https://github.com/spatie/ray/issues", - "source": "https://github.com/spatie/ray/tree/1.36.0" + "source": "https://github.com/spatie/ray/tree/1.37.1" }, "funding": [ { @@ -14191,145 +14454,20 @@ "type": "other" } ], - "time": "2022-08-11T14:04:18+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v6.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "4d216a2beef096edf040a070117c39ca2abce307" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/4d216a2beef096edf040a070117c39ca2abce307", - "reference": "4d216a2beef096edf040a070117c39ca2abce307", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.1.5" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-09-21T20:29:40+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v6.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/266636bb8f3fbdccc302491df7b3a1b9a8c238a7", - "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/service-contracts": "^1|^2|^3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides a way to profile code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.1.5" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-09-28T16:00:52+00:00" + "time": "2023-03-06T07:22:28+00:00" }, { "name": "symfony/yaml", - "version": "v5.4.14", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e83fe9a72011f07c662da46a05603d66deeeb487" + "reference": "3713e20d93e46e681e51605d213027e48dab3469" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e83fe9a72011f07c662da46a05603d66deeeb487", - "reference": "e83fe9a72011f07c662da46a05603d66deeeb487", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3713e20d93e46e681e51605d213027e48dab3469", + "reference": "3713e20d93e46e681e51605d213027e48dab3469", "shasum": "" }, "require": { @@ -14375,7 +14513,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.4.14" + "source": "https://github.com/symfony/yaml/tree/v5.4.21" }, "funding": [ { @@ -14391,7 +14529,7 @@ "type": "tidelift" } ], - "time": "2022-10-03T15:15:50+00:00" + "time": "2023-02-21T19:46:44+00:00" }, { "name": "theseer/tokenizer", @@ -14445,28 +14583,30 @@ }, { "name": "zbateson/mail-mime-parser", - "version": "2.2.3", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/zbateson/mail-mime-parser.git", - "reference": "295c7f82a8c44af685680d9df6714beb812e90ff" + "reference": "20b3e48eb799537683780bc8782fbbe9bc25934a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/295c7f82a8c44af685680d9df6714beb812e90ff", - "reference": "295c7f82a8c44af685680d9df6714beb812e90ff", + "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/20b3e48eb799537683780bc8782fbbe9bc25934a", + "reference": "20b3e48eb799537683780bc8782fbbe9bc25934a", "shasum": "" }, "require": { "guzzlehttp/psr7": "^1.7.0|^2.0", - "php": ">=5.4", + "php": ">=7.1", "pimple/pimple": "^3.0", "zbateson/mb-wrapper": "^1.0.1", "zbateson/stream-decorators": "^1.0.6" }, "require-dev": { + "friendsofphp/php-cs-fixer": "*", "mikey179/vfsstream": "^1.6.0", - "sanmai/phpunit-legacy-adapter": "^6.3 || ^8.2" + "phpstan/phpstan": "*", + "phpunit/phpunit": "<10" }, "suggest": { "ext-iconv": "For best support/performance", @@ -14514,29 +14654,31 @@ "type": "github" } ], - "time": "2022-09-28T16:31:49+00:00" + "time": "2023-02-14T22:58:03+00:00" }, { "name": "zbateson/mb-wrapper", - "version": "1.1.2", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/zbateson/mb-wrapper.git", - "reference": "5d9d190ef18ce6d424e3ac6f5ebe13901f92b74a" + "reference": "faf35dddfacfc5d4d5f9210143eafd7a7fe74334" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/5d9d190ef18ce6d424e3ac6f5ebe13901f92b74a", - "reference": "5d9d190ef18ce6d424e3ac6f5ebe13901f92b74a", + "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/faf35dddfacfc5d4d5f9210143eafd7a7fe74334", + "reference": "faf35dddfacfc5d4d5f9210143eafd7a7fe74334", "shasum": "" }, "require": { - "php": ">=5.4", + "php": ">=7.1", "symfony/polyfill-iconv": "^1.9", "symfony/polyfill-mbstring": "^1.9" }, "require-dev": { - "sanmai/phpunit-legacy-adapter": "^6.3 || ^8" + "friendsofphp/php-cs-fixer": "*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "<=9.0" }, "suggest": { "ext-iconv": "For best support/performance", @@ -14573,7 +14715,7 @@ ], "support": { "issues": "https://github.com/zbateson/mb-wrapper/issues", - "source": "https://github.com/zbateson/mb-wrapper/tree/1.1.2" + "source": "https://github.com/zbateson/mb-wrapper/tree/1.2.0" }, "funding": [ { @@ -14581,29 +14723,31 @@ "type": "github" } ], - "time": "2022-05-26T15:55:05+00:00" + "time": "2023-01-11T23:05:44+00:00" }, { "name": "zbateson/stream-decorators", - "version": "1.0.7", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/zbateson/stream-decorators.git", - "reference": "8f8ca208572963258b7e6d91106181706deacd10" + "reference": "7466ff45d249c86b96267a83cdae68365ae1787e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zbateson/stream-decorators/zipball/8f8ca208572963258b7e6d91106181706deacd10", - "reference": "8f8ca208572963258b7e6d91106181706deacd10", + "url": "https://api.github.com/repos/zbateson/stream-decorators/zipball/7466ff45d249c86b96267a83cdae68365ae1787e", + "reference": "7466ff45d249c86b96267a83cdae68365ae1787e", "shasum": "" }, "require": { - "guzzlehttp/psr7": "^1.7.0|^2.0", - "php": ">=5.4", + "guzzlehttp/psr7": "^1.9 | ^2.0", + "php": ">=7.1", "zbateson/mb-wrapper": "^1.0.0" }, "require-dev": { - "sanmai/phpunit-legacy-adapter": "^6.3 || ^8" + "friendsofphp/php-cs-fixer": "*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "<=9.0" }, "type": "library", "autoload": { @@ -14634,7 +14778,7 @@ ], "support": { "issues": "https://github.com/zbateson/stream-decorators/issues", - "source": "https://github.com/zbateson/stream-decorators/tree/1.0.7" + "source": "https://github.com/zbateson/stream-decorators/tree/1.1.0" }, "funding": [ { @@ -14642,7 +14786,7 @@ "type": "github" } ], - "time": "2022-09-08T15:44:55+00:00" + "time": "2023-01-11T23:22:44+00:00" } ], "aliases": [], diff --git a/config/aic.php b/config/aic.php index 7d58a9bd2..8b987cbea 100644 --- a/config/aic.php +++ b/config/aic.php @@ -6,6 +6,8 @@ 'iiif_s3_endpoint' => env('IIIF_S3_ENDPOINT'), 'sales_site_url' => env('SALES_SITE_URL', 'https://sales.artic.edu'), 'vtour_bucket' => env('AWS_VTOUR_BUCKET'), + 'http_username' => env('HTTP_USERNAME'), + 'http_password' => env('HTTP_PASSWORD'), // ART-48: For "Research Center"; see Departments filter 'department_archive_title' => env('DEPARTMENT_ARCHIVE_TITLE', 'AIC Archives'), @@ -29,4 +31,5 @@ 'show_artist_gender' => (bool) env('SHOW_ARTIST_GENDER', false), 'show_hours_in_footer' => (bool) env('SHOW_HOURS_IN_FOOTER', false), 'disable_captcha' => (bool) env('DISABLE_CAPTCHA', false), + 'show_default_related_items' => (bool) env('SHOW_DEFAULT_RELATED_ITEMS', true), ]; diff --git a/config/twill-navigation.php b/config/twill-navigation.php index 994bbc6bd..3141a9dcb 100644 --- a/config/twill-navigation.php +++ b/config/twill-navigation.php @@ -154,10 +154,6 @@ 'title' => 'Landing', 'route' => 'admin.collection.research_resources.landing', ], - 'researchGuides' => [ - 'title' => 'Research Guides', - 'module' => true, - ], 'educatorResources' => [ 'title' => 'Educator Resources', 'module' => true, @@ -202,10 +198,6 @@ 'title' => 'Authors', 'module' => true, ], - 'issues' => [ - 'title' => 'Issues', - 'module' => true, - ] ] ], 'generic' => [ diff --git a/config/twill/block_editor.php b/config/twill/block_editor.php index e63f70c99..3ec7f00f1 100644 --- a/config/twill/block_editor.php +++ b/config/twill/block_editor.php @@ -228,6 +228,7 @@ 'image_slider', 'mirador_embed', 'mirador_modal', - 'vtour_embed' + 'vtour_embed', + 'layered_image_viewer' ] ]; diff --git a/database/factories/Api/ApiFactory.php b/database/factories/Api/ApiFactory.php new file mode 100644 index 000000000..cc995c8f2 --- /dev/null +++ b/database/factories/Api/ApiFactory.php @@ -0,0 +1,672 @@ +count = $count; + $this->states = $states ?: new Collection(); + $this->has = $has ?: new Collection(); + $this->for = $for ?: new Collection(); + $this->afterMaking = $afterMaking ?: new Collection(); + $this->afterCreating = $afterCreating ?: new Collection(); + $this->connection = $connection; + $this->faker = $this->withFaker(); + } + + /** + * Define the model's default state. + */ + abstract public function definition(): array; + + /** + * Get a new factory instance for the given attributes. + */ + public static function new(callable|array $attributes = []): static + { + return (new static())->state($attributes)->configure(); + } + + /** + * Get a new factory instance for the given number of models. + */ + public static function times(int $count): static + { + return static::new()->count($count); + } + + /** + * Configure the factory. + */ + public function configure() + { + return $this; + } + + /** + * Get the raw attributes generated by the factory. + */ + public function raw(array $attributes = [], ?ApiModel $parent = null): array + { + if ($this->count === null) { + return $this->state($attributes)->getExpandedAttributes($parent); + } + + return array_map(function () use ($attributes, $parent) { + return $this->state($attributes)->getExpandedAttributes($parent); + }, range(1, $this->count)); + } + + /** + * Create a single model and persist it to the database. + */ + public function createOne(array $attributes = []): ApiModel + { + return $this->count(null)->create($attributes); + } + + /** + * Create a single model and persist it to the database. + */ + public function createOneQuietly(array $attributes = []): ApiModel + { + return $this->count(null)->createQuietly($attributes); + } + + /** + * Create a collection of models and persist them to the database. + */ + public function createMany(iterable $records): EloquentCollection + { + return new EloquentCollection( + collect($records)->map(function ($record) { + return $this->state($record)->create(); + }) + ); + } + + /** + * Create a collection of models and persist them to the database. + */ + public function createManyQuietly(iterable $records): EloquentCollection + { + return ApiModel::withoutEvents(function () use ($records) { + return $this->createMany($records); + }); + } + + /** + * Create a collection of models and persist them to the database. + */ + public function create(array $attributes = [], ?ApiModel $parent = null): EloquentCollection|ApiModel + { + if (! empty($attributes)) { + return $this->state($attributes)->create([], $parent); + } + + $results = $this->make($attributes, $parent); + + if ($results instanceof ApiModel) { + $this->store(collect([$results])); + + $this->callAfterCreating(collect([$results]), $parent); + } else { + $this->store($results); + + $this->callAfterCreating($results, $parent); + } + + return $results; + } + + /** + * Create a collection of models and persist them to the database. + */ + public function createQuietly(array $attributes = [], ?ApiModel $parent = null): EloquentCollection|ApiModel + { + return ApiModel::withoutEvents(function () use ($attributes, $parent) { + return $this->create($attributes, $parent); + }); + } + + /** + * Create a callback that persists a model in the database when invoked. + */ + public function lazy(array $attributes = [], ?ApiModel $parent = null): Closure + { + return function () use ($attributes, $parent) { + return $this->create($attributes, $parent); + }; + } + + /** + * Do NOT store result models. + */ + protected function store($results) + { + // no-op + } + + /** + * Create the children for the given model. + */ + protected function createChildren(ApiModel $model): void + { + ApiModel::unguarded(function () use ($model) { + $this->has->each(function ($has) use ($model) { + $has->createFor($model); + }); + }); + } + + /** + * Make a single instance of the model. + */ + public function makeOne(callable|array $attributes = []): ApiModel + { + return $this->count(null)->make($attributes); + } + + /** + * Create a collection of models. + */ + public function make(array $attributes = [], ?ApiModel $parent = null): EloquentCollection|ApiModel + { + if (! empty($attributes)) { + return $this->state($attributes)->make([], $parent); + } + + if ($this->count === null) { + return tap($this->makeInstance($parent), function ($instance) { + $this->callAfterMaking(collect([$instance])); + }); + } + + if ($this->count < 1) { + return $this->newModel()->newCollection(); + } + + $instances = $this->newModel()->newCollection(array_map(function () use ($parent) { + return $this->makeInstance($parent); + }, range(1, $this->count))); + + $this->callAfterMaking($instances); + + return $instances; + } + + /** + * Make an instance of the model with the given attributes. + */ + protected function makeInstance(?ApiModel $parent): ApiModel + { + return ApiModel::unguarded(function () use ($parent) { + return tap($this->newModel($this->getExpandedAttributes($parent)), function ($instance) { + if (isset($this->connection)) { + $instance->setConnection($this->connection); + } + }); + }); + } + + /** + * Get a raw attributes array for the model. + */ + protected function getExpandedAttributes(?ApiModel $parent): mixed + { + return $this->expandAttributes($this->getRawAttributes($parent)); + } + + /** + * Get the raw attributes for the model as an array. + */ + protected function getRawAttributes(?ApiModel $parent): array + { + return $this->states->pipe(function ($states) { + return $this->for->isEmpty() ? $states : new Collection(array_merge([function () { + return $this->parentResolvers(); + }], $states->all())); + })->reduce(function ($carry, $state) use ($parent) { + if ($state instanceof Closure) { + $state = $state->bindTo($this); + } + + return array_merge($carry, $state($carry, $parent)); + }, $this->definition()); + } + + /** + * Create the parent relationship resolvers (as deferred Closures). + */ + protected function parentResolvers(): array + { + $model = $this->newModel(); + + return $this->for->map(function (BelongsToRelationship $for) use ($model) { + return $for->attributesFor($model); + })->collapse()->all(); + } + + /** + * Expand all attributes to their underlying values. + */ + protected function expandAttributes(array $definition): array + { + return collect($definition)->map(function ($attribute, $key) use (&$definition) { + if (is_callable($attribute) && ! is_string($attribute) && ! is_array($attribute)) { + $attribute = $attribute($definition); + } + + if ($attribute instanceof self) { + $attribute = $attribute->create()->getKey(); + } elseif ($attribute instanceof ApiModel) { + $attribute = $attribute->getKey(); + } + + $definition[$key] = $attribute; + + return $attribute; + })->all(); + } + + /** + * Add a new state transformation to the model definition. + */ + public function state(callable|array $state): static + { + return $this->newInstance([ + 'states' => $this->states->concat([ + is_callable($state) ? $state : function () use ($state) { + return $state; + }, + ]), + ]); + } + + /** + * Add a new sequenced state transformation to the model definition. + */ + public function sequence(...$sequence): static + { + return $this->state(new Sequence(...$sequence)); + } + + /** + * Add a new cross joined sequenced state transformation to the model definition. + */ + public function crossJoinSequence(...$sequence): static + { + return $this->state(new CrossJoinSequence(...$sequence)); + } + + /** + * Define a child relationship for the model. + */ + public function has(self $factory, ?string $relationship = null): static + { + return $this->newInstance([ + 'has' => $this->has->concat([new Relationship( + $factory, + $relationship ?: $this->guessRelationship($factory->modelName()) + )]), + ]); + } + + /** + * Attempt to guess the relationship name for a "has" relationship. + */ + protected function guessRelationship(string $related): string + { + $guess = Str::camel(Str::plural(class_basename($related))); + + return method_exists($this->modelName(), $guess) ? $guess : Str::singular($guess); + } + + /** + * Define an attached relationship for the model. + */ + public function hasAttached( + ApiFactory|Collection|ApiModel $factory, + callable|array $pivot = [], + ?string $relationship = null, + ): static { + return $this->newInstance([ + 'has' => $this->has->concat([new BelongsToManyRelationship( + $factory, + $pivot, + $relationship ?: Str::camel(Str::plural(class_basename( + $factory instanceof ApiFactory + ? $factory->modelName() + : Collection::wrap($factory)->first() + ))) + )]), + ]); + } + + /** + * Define a parent relationship for the model. + */ + public function for(ApiFactory|ApiModel $factory, ?string $relationship = null): static + { + return $this->newInstance(['for' => $this->for->concat([new BelongsToRelationship( + $factory, + $relationship ?: Str::camel(class_basename( + $factory instanceof ApiFactory ? $factory->modelName() : $factory + )) + )])]); + } + + /** + * Add a new "after making" callback to the model definition. + */ + public function afterMaking(Closure $callback): static + { + return $this->newInstance(['afterMaking' => $this->afterMaking->concat([$callback])]); + } + + /** + * Add a new "after creating" callback to the model definition. + */ + public function afterCreating(Closure $callback): static + { + return $this->newInstance(['afterCreating' => $this->afterCreating->concat([$callback])]); + } + + /** + * Call the "after making" callbacks for the given model instances. + */ + protected function callAfterMaking(Collection $instances): void + { + $instances->each(function ($model) { + $this->afterMaking->each(function ($callback) use ($model) { + $callback($model); + }); + }); + } + + /** + * Call the "after creating" callbacks for the given model instances. + */ + protected function callAfterCreating(Collection $instances, ?ApiModel $parent = null): void + { + $instances->each(function ($model) use ($parent) { + $this->afterCreating->each(function ($callback) use ($model, $parent) { + $callback($model, $parent); + }); + }); + } + + /** + * Specify how many models should be generated. + */ + public function count(?int $count): static + { + return $this->newInstance(['count' => $count]); + } + + /** + * Specify the database connection that should be used to generate models. + */ + public function connection(string $connection): static + { + return $this->newInstance(['connection' => $connection]); + } + + /** + * Create a new instance of the factory builder with the given mutated properties. + */ + protected function newInstance(array $arguments = []): static + { + return new static(...array_values(array_merge([ + 'count' => $this->count, + 'states' => $this->states, + 'has' => $this->has, + 'for' => $this->for, + 'afterMaking' => $this->afterMaking, + 'afterCreating' => $this->afterCreating, + 'connection' => $this->connection, + ], $arguments))); + } + + /** + * Get a new model instance. + */ + public function newModel(array $attributes = []): ApiModel + { + $model = $this->modelName(); + + return new $model($attributes); + } + + /** + * Get the name of the model that is generated by the factory. + */ + public function modelName(): string + { + $resolver = static::$modelNameResolver ?: function (self $factory) { + $namespacedFactoryBasename = Str::replaceLast( + 'Factory', + '', + Str::replaceFirst(static::$namespace, '', get_class($factory)) + ); + + $factoryBasename = Str::replaceLast('Factory', '', class_basename($factory)); + + $appNamespace = static::appNamespace(); + + return class_exists($appNamespace . 'Models\\Api\\' . $namespacedFactoryBasename) + ? $appNamespace . 'Models\\Api\\' . $namespacedFactoryBasename + : $appNamespace . $factoryBasename; + }; + + return $this->model ?: $resolver($this); + } + + /** + * Specify the callback that should be invoked to guess model names based on factory names. + */ + public static function guessModelNamesUsing(callable $callback): void + { + static::$modelNameResolver = $callback; + } + + /** + * Specify the default namespace that contains the application's model factories. + */ + public static function useNamespace(string $namespace): void + { + static::$namespace = $namespace; + } + + /** + * Get a new factory instance for the given model name. + */ + public static function factoryForModel(string $modelName): static + { + $factory = static::resolveFactoryName($modelName); + + return $factory::new(); + } + + /** + * Specify the callback that should be invoked to guess factory names based on dynamic relationship names. + */ + public static function guessFactoryNamesUsing(callable $callback): void + { + static::$factoryNameResolver = $callback; + } + + /** + * Get a new Faker instance. + */ + protected function withFaker(): FakerGenerator + { + return Container::getInstance()->make(FakerGenerator::class); + } + + /** + * Get the factory name for the given model name. + */ + public static function resolveFactoryName(string $modelName): string + { + $resolver = static::$factoryNameResolver ?: function (string $modelName) { + $appNamespace = static::appNamespace(); + + $modelName = Str::startsWith($modelName, $appNamespace . 'Models\\Api\\') + ? Str::after($modelName, $appNamespace . 'Models\\Api\\') + : Str::after($modelName, $appNamespace); + + return static::$namespace . $modelName . 'Factory'; + }; + + return $resolver($modelName); + } + + /** + * Get the application namespace for the application. + */ + protected static function appNamespace(): string + { + try { + return Container::getInstance() + ->make(Application::class) + ->getNamespace(); + } catch (Throwable $e) { + return 'App\\'; + } + } + + /** + * Proxy dynamic factory methods onto their proper methods. + */ + public function __call(string $method, array $parameters): mixed + { + if (static::hasMacro($method)) { + return $this->macroCall($method, $parameters); + } + + if (! Str::startsWith($method, ['for', 'has'])) { + static::throwBadMethodCallException($method); + } + + $relationship = Str::camel(Str::substr($method, 3)); + + $relatedModel = get_class($this->newModel()->{$relationship}()->getRelated()); + + if (method_exists($relatedModel, 'newFactory')) { + $factory = $relatedModel::newFactory() ?: static::factoryForModel($relatedModel); + } else { + $factory = static::factoryForModel($relatedModel); + } + + if (Str::startsWith($method, 'for')) { + return $this->for($factory->state($parameters[0] ?? []), $relationship); + } elseif (Str::startsWith($method, 'has')) { + return $this->has( + $factory + ->count(is_numeric($parameters[0] ?? null) ? $parameters[0] : 1) + ->state((is_callable($parameters[0] ?? null) || is_array($parameters[0] ?? null)) ? $parameters[0] : ($parameters[1] ?? [])), + $relationship + ); + } + } +} diff --git a/database/factories/Api/ArtworkFactory.php b/database/factories/Api/ArtworkFactory.php new file mode 100644 index 000000000..ebab65e88 --- /dev/null +++ b/database/factories/Api/ArtworkFactory.php @@ -0,0 +1,19 @@ + $this->faker->randomNumber(nbDigits: 5), + 'title' => ucfirst($this->faker->words(nb: 5, asText: true)), + 'edition' => "{$this->faker->randomNumber()} of {$this->faker->randomNumber(nbDigits: 2, strict: true)}", + ]; + } +} diff --git a/database/factories/Api/HasApiFactory.php b/database/factories/Api/HasApiFactory.php new file mode 100644 index 000000000..c5b55b155 --- /dev/null +++ b/database/factories/Api/HasApiFactory.php @@ -0,0 +1,29 @@ +count(is_numeric($parameters[0] ?? null) ? $parameters[0] : null) + ->state(is_array($parameters[0] ?? null) ? $parameters[0] : ($parameters[1] ?? [])); + } + + /** + * Create a new factory instance for the model. + */ + protected static function newFactory() + { + // + } +} diff --git a/database/factories/ArticleFactory.php b/database/factories/ArticleFactory.php new file mode 100644 index 000000000..e89ae54ad --- /dev/null +++ b/database/factories/ArticleFactory.php @@ -0,0 +1,77 @@ + $this->faker->name(), + 'citation' => null, + 'citations' => '

*' . $this->faker->sentence() . '

', + 'content' => null, + 'date' => now(), + 'heading' => '

' . $this->faker->sentence() . '

', + 'hero_caption' => '

' . $this->faker->sentence() . '

', + 'is_in_magazine' => $this->faker->boolean(), + 'is_unlisted' => $this->faker->boolean(), + 'layout_type' => (int) $this->faker->boolean(), + 'list_description' => '

' . $this->faker->sentence() . '

', + 'meta_description' => null, + 'meta_title' => null, + 'migrated_at' => null, + 'migrated_node_id' => null, + 'publish_end_date' => null, + 'publish_start_date' => null, + 'published' => $this->faker->boolean(), + 'subtype' => ucfirst($this->faker->word()), + 'title' => ucfirst($this->faker->words(5, true)), + 'title_display' => '' . ucfirst($this->faker->words(5, true)) . '', + ]; + } + + public function configure() + { + return $this->afterCreating(function (Article $article) { + $article->medias()->attach( + Media::create(['uuid' => $this->faker->uuid(), 'width' => 1, 'height' => 1 ]), + ['crop' => 'default', 'role' => 'hero'], + ); + }); + } + + public function published() + { + return $this->state(function (array $attributes) { + return [ + 'published' => true, + ]; + }); + } + + public function visible() + { + return $this->state(function (array $attributes) { + return [ + 'publish_end_date' => now()->addDay(), + 'publish_start_date' => now()->subDay(), + ]; + }); + } + + public function notUnlisted() + { + return $this->state(function (array $attributes) { + return [ + 'is_unlisted' => false, + ]; + }); + } +} diff --git a/database/factories/IssueArticleFactory.php b/database/factories/IssueArticleFactory.php deleted file mode 100644 index 758baad24..000000000 --- a/database/factories/IssueArticleFactory.php +++ /dev/null @@ -1,28 +0,0 @@ - true, - ]; - } -} diff --git a/database/factories/IssueFactory.php b/database/factories/IssueFactory.php deleted file mode 100644 index 0f4396317..000000000 --- a/database/factories/IssueFactory.php +++ /dev/null @@ -1,28 +0,0 @@ - true, - ]; - } -} diff --git a/database/migrations/2017_11_15_192240_create_segments_tables.php b/database/migrations/2017_11_15_192240_create_segments_tables.php index 8b76ecc72..5725313d8 100644 --- a/database/migrations/2017_11_15_192240_create_segments_tables.php +++ b/database/migrations/2017_11_15_192240_create_segments_tables.php @@ -1,4 +1,4 @@ - string('visit_become_member_label')->nullable(); }); } - } diff --git a/database/migrations/2018_07_21_000747_add_event_programs_data.php b/database/migrations/2018_07_21_000747_add_event_programs_data.php index add23270d..5c6b5ce7e 100644 --- a/database/migrations/2018_07_21_000747_add_event_programs_data.php +++ b/database/migrations/2018_07_21_000747_add_event_programs_data.php @@ -1,7 +1,6 @@ string('local_title', 150)->nullable(); + $table->string('local_subtype', 150)->nullable(); + }); + } + + public function down() + { + Schema::table('category_terms', function (Blueprint $table) { + $table->dropColumn(['local_title', 'local_subtype']); + }); + } +} diff --git a/database/migrations/2023_03_20_152705_add_meta_title_and_meta_description_to_videos.php b/database/migrations/2023_03_20_152705_add_meta_title_and_meta_description_to_videos.php new file mode 100644 index 000000000..1b7c5d244 --- /dev/null +++ b/database/migrations/2023_03_20_152705_add_meta_title_and_meta_description_to_videos.php @@ -0,0 +1,26 @@ +string('meta_title')->nullable(); + $table->text('meta_description')->nullable(); + $table->text('search_tags')->nullable(); + }); + } + + public function down() + { + Schema::table('videos', function (Blueprint $table) { + $table->dropColumn('meta_title'); + $table->dropColumn('meta_description'); + $table->dropColumn('search_tags'); + }); + } +} diff --git a/database/migrations/2023_04_05_133342_delete_research_guides_table.php b/database/migrations/2023_04_05_133342_delete_research_guides_table.php new file mode 100644 index 000000000..d5eb17b32 --- /dev/null +++ b/database/migrations/2023_04_05_133342_delete_research_guides_table.php @@ -0,0 +1,21 @@ + + + diff --git a/frontend/icons/reset--24.svg b/frontend/icons/reset--24.svg new file mode 100644 index 000000000..3ec45ac21 --- /dev/null +++ b/frontend/icons/reset--24.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/js/behaviors/core/infoButtonTrigger.js b/frontend/js/behaviors/core/infoButtonTrigger.js index d860c6891..8f4866e23 100644 --- a/frontend/js/behaviors/core/infoButtonTrigger.js +++ b/frontend/js/behaviors/core/infoButtonTrigger.js @@ -79,7 +79,7 @@ const infoButtonTrigger = function(container) { } function _clicksOutside(event) { - if (infoOpen) { + if (infoOpen && !infoButtonInfo.contains(document.activeElement)) { event.preventDefault(); event.stopPropagation(); _closeInfoButtonInfo(); diff --git a/frontend/js/behaviors/layeredImageViewer/index.js b/frontend/js/behaviors/layeredImageViewer/index.js new file mode 100644 index 000000000..ec8a6d0b1 --- /dev/null +++ b/frontend/js/behaviors/layeredImageViewer/index.js @@ -0,0 +1 @@ +export { default as layeredImageViewer } from './layeredImageViewer'; diff --git a/frontend/js/behaviors/layeredImageViewer/layeredImageViewer.js b/frontend/js/behaviors/layeredImageViewer/layeredImageViewer.js new file mode 100644 index 000000000..963dfe328 --- /dev/null +++ b/frontend/js/behaviors/layeredImageViewer/layeredImageViewer.js @@ -0,0 +1,1339 @@ +import OpenSeadragon from '../../libs/openseadragon4.min'; + + +/** + * (OpenSeadragon) Layered image viewer + * @class + * @param {HTMLElement} viewerEl - The element to initialise the viewer into. Contains HTML used for priming the initial state. + */ +class LayeredImageViewer { + constructor(viewerEl) { + // Check for presence of OSD before proceeding + if (typeof OpenSeadragon !== 'function') { + return console.error( + 'Error: OpenSeadragon is required to run the layered image viewer' + ); + } + + // Prevent possibility of double init + if (viewerEl.layeredImageViewer) return; + + this.element = viewerEl; + this.element.layeredImageViewer = this; + this.osdMountEl = null; + this.browerSupportsFullscreen = + typeof document.fullscreenElement !== 'undefined'; + this.size = this.element.dataset.size || 'm'; + this.aspect = 1; + this.id = 0; + + // Store how viewer should behave on first load + // (Needs to include all keys) + // Added to viewer instance when interactoin setter first runs + this.baseGestureSettings = { + mouse: { + dragToPan: true, + scrollToZoom: false, + clickToZoom: true, + dblClickToZoom: false, + dblClickDragToZoom: false, + pinchToZoom: false, + zoomToRefPoint: true, + flickEnabled: false, + flickMinSpeed: 120, + flickMomentum: 0.25, + pinchRotate: false, + }, + touch: { + dragToPan: true, + scrollToZoom: false, + clickToZoom: false, + dblClickToZoom: true, + dblClickDragToZoom: true, + pinchToZoom: true, + zoomToRefPoint: true, + flickEnabled: true, + flickMinSpeed: 120, + flickMomentum: 0.25, + pinchRotate: false, + }, + } + + this.captionTitleEl = null; + this.captionEl = null; + this.images = { + items: [], + active: { + a: null, + b: null, + }, + }; + this.overlays = { + items: [], + active: [], + default: [], + }; + this.toolbar = { + viewer: { + buttons: {}, + }, + layers: { + controls: {} + }, + }; + this.isFullscreen = false; + + // Bind to store referenceable event handler with correct context set explictly + // Could use arrow functions, but transpiler might interfere + this.boundExitFullscreenHandler = this._exitFullscreenHandler.bind(this); + this.boundOsdEnableDefault = this._osdEnableDefault.bind(this); + this.boundHandleExternalClick = this._handleExternalClick.bind(this); + this.boundHandleClickInteraction = this._handleClickInteraction.bind(this); + this.boundHandlePointerEnterInteraction = this._handlePointerEnterInteraction.bind(this); + + this.setInitialState(); + this._initViewer(); + } + + /** + * Handler to use for OSD inner events when browser scrolling + * At time of writing this is required + * See: https://github.com/openseadragon/openseadragon/issues/2151 + * @private + * @method + * @param {Event} e The event object + */ + _osdEnableDefault(e) { + e.preventDefault = false; + e.preventDefaultAction = false; + } + + /** + * Handle click / tap events that fire when interaction is enabled + * @private + * @method + * @param {Event} e The event object + */ + _handleExternalClick(e) { + if (!this.viewer.element.contains(e.target)) { + this.interaction = false; + // Turn off tracking when scrolling is released to the browser + // Deciding for better or for worse that a stylus is more like a mouse than a finger + // Tracker should be halted only for touch, enabling drag by mouse + if (e.pointerType === 'touch') { + this.viewer.innerTracker.setTracking(false); + } else { + this.viewer.innerTracker.setTracking(true); + } + } + } + + /** + * Handle click / tap interaction within the viewer area + * @private + * @method + * @param {Event} e The event object + */ + _handleClickInteraction(e) { + // Menu opening specifically disables clickToZoom + // ::: Exclude clicks inside menu from counting + // as internal and activating clickToZoom + if ( + this.toolbar.layers.controls.menu && + this.toolbar.layers.controls.menu.contains(e.target) + ) return; + this.interaction = true; + this.viewer.innerTracker.setTracking(true); + } + + /** + * Handle any kind of pointer entering the viewer + * @private + * @method + * @param {Event} e The event object + */ + _handlePointerEnterInteraction(e) { + // N.B. if we wanted to do more advanced handling that needed e.touches this would + // have to be called on a touch event + if (!this.interaction && e.pointerType === 'touch') { + // Stop tracking for touch to prevent warnings + this.viewer.innerTracker.setTracking(false); + } + } + + /** + * Getter for _interaction + * @public + */ + get interaction() { + return this._interaction; + } + + /** + * Setter for _interaction + * @param {Boolean} value - New value for interaction + * @public + */ + set interaction(value) { + // Either indicate touch-scroll will be captured or be released + this.viewer.container.style.touchAction = value + ? 'none' + : 'manipulation'; + this.viewer.canvas.style.touchAction = value ? 'none' : 'manipulation'; + + // Release internal event tracking in OSD + this.viewer.addHandler( + 'canvas-scroll', + this.boundOsdEnableDefault + ); + + // Set gestureSettings + // Spread operator not allowed, workaround: + Object.assign(this.viewer.gestureSettingsMouse, this.baseGestureSettings.mouse); + this.viewer.gestureSettingsMouse.scrollToZoom = this.isFullscreen && true; + + Object.assign(this.viewer.gestureSettingsTouch, this.baseGestureSettings.touch); + if (value) { + this.viewer.gestureSettingsTouch.dragToPan = true; + this.viewer.gestureSettingsTouch.flickEnabled = true; + } + + // Add or remove event listeners + // It's probably best to not remove these contingent on interaction, + // in case we need more logic inside the handler + this.viewer.element.addEventListener( + 'click', + this.boundHandleClickInteraction, + true + ); + this.viewer.element. + addEventListener('pointerenter', this.boundHandlePointerEnterInteraction, true); + + // This can be removed contingent on interaction + ['click', 'touchend'].forEach((event) => { + document.body[value ? 'addEventListener' : 'removeEventListener']( + event, + this.boundHandleExternalClick, + true + ); + }) + + // Complete property assignment + this._interaction = value; + } + + /** + * Attach resize observer to viewer element + * @private + * @method + */ + _setViewerResizeObserver() { + // Watch for resize on main element + this.viewerResizeObserver = new ResizeObserver((entries) => { + this.viewer.element.style.setProperty( + '--viewer-height', + `${entries[0].contentRect.height}px` + ); + + this.viewer.element.style.setProperty( + '--viewer-width', + `${entries[0].contentRect.width}px` + ); + }); + + this.viewerResizeObserver.observe(this.viewer.element); + } + + /** + * Take the view back to its (editor defined) starting position + * @private + * @method + */ + _setCropRegion() { + if (!this.cropRegion) return; + + const cropRegion = this.viewer.world + .getItemAt(0) + .imageToViewportRectangle( + this.cropRegion.x, + this.cropRegion.y, + this.cropRegion.width, + this.cropRegion.height + ); + + // For now this has to be set with the immediately flag, see: + // https://github.com/openseadragon/openseadragon/issues/2292 + this.viewer.viewport.fitBoundsWithConstraints(cropRegion, true); + } + + /** + * Process and store all types of image data in the same way + * @private + * @method + * @param {String} type - The label to identify and store data + * @param {NodeList} imgEls - The list of items (imgs) to process + */ + _processImages(type, imgEls) { + if (!imgEls.length) return; + + // Store state required for each type + imgEls.forEach((imgEl, i) => { + const figureEl = imgEl.closest('figure'); + const itemState = {}; + itemState.url = imgEl.dataset.viewerSrc; + itemState.alt = imgEl.alt; + itemState.label = 'Unknown'; + + // Handle either figcaption or title + if (imgEl.title) { + itemState.label = imgEl.title; + } else if (figureEl && figureEl.querySelector('figcaption')) { + itemState.label = figureEl.querySelector('figcaption').innerText.trim(); + } + + // Set default active overlays + if (type === 'overlays') { + const overlayEl = imgEl.closest('.o-layered-image-viewer__overlay'); + + if (typeof overlayEl.dataset.activeOverlay !== 'undefined') { + this.overlays.default.push(i); + } + } + + // Use the first image to skim the aspect ratio + if (type === 'images' && i === 0) { + this.aspect = imgEl.height / imgEl.width; + } + + // Add ID for internal reference + imgEl.id = `layered-image-viewer-${this.id}-${type}-${i}`; + + this[type].items = this[type].items.concat(itemState); + }); + } + + /** + * Skim data from the HTML included in the viewerEl and store it on this instance. + * @public + * @method + */ + setInitialState() { + // Zero indexed ID of the viewer inferred from other initialised viewers document + this.id = document.querySelectorAll('.o-layered-image-viewer__osd').length - 1; + + // Set the size + this.size = this.element.dataset.size; + + // Store ref to containers container + this.images.element = this.element.querySelector( + '.o-layered-image-viewer__images' + ); + this.overlays.element = this.element.querySelector( + '.o-layered-image-viewer__overlays' + ); + + // Get caption and caption title nodes + this.captionTitleEl = this.element.querySelector( + '.o-layered-image-viewer__caption-title' + ); + this.captionEl = this.element.querySelector( + '.o-layered-image-viewer__caption-text' + ); + + // Extract initial crop / zoom if set + if (this.element.dataset.cropRegion) { + this.cropRegion = JSON.parse( + this.element.dataset.cropRegion.replace(/"/g, '"') + ); + } + + // Process each image + if (this.images.element) { + this._processImages('images', this.images.element.querySelectorAll('img')); + } + + // Process each overlay + if (this.overlays.element) { + this._processImages( + 'overlays', + this.overlays.element.querySelectorAll('img') + ); + } + } + + /** + * Enter or exit fullscreen mode using the fullscreen API if available + * Falls back to CSS if not + * @private + * @method + * @param {Boolean} enter - What the target state should be + */ + _setFullscreen(enter) { + this.isFullscreen = true; + if (enter) { + // Enter fullscreen + // CSS applied when class is added to html element + document.documentElement.classList.add( + 's-layered-image-viewer-modal-active' + ); + + // Perform API request if necessary and bind event listeners + if (this.browerSupportsFullscreen) { + this.osdMountEl.requestFullscreen(); + + document.addEventListener( + 'fullscreenchange', + this.boundExitFullscreenHandler + ); + } else { + // Move into dialog el if non-fullscreen + this.modalEl.appendChild(this.osdMountEl); + this.modalEl.showModal(); + // refocus after move + this.toolbar.viewer.buttons.fullscreen.focus(); + document.addEventListener('keydown', this.boundExitFullscreenHandler); + } + // This should be true already, but ensure full screen viewer + // has gestures matching post-interaction state + this.interaction = true; + this.toolbar.viewer.buttons.fullscreen.ariaLabel = 'Exit'; + } else { + // Exit fullscreen + // Hide viewer by removing class + document.documentElement.classList.remove( + 's-layered-image-viewer-modal-active' + ); + this.isFullscreen = false; + + // Remove event listeners + if (this.browerSupportsFullscreen) { + if (document.fullscreenElement) { + document.exitFullscreen(); + } + document.removeEventListener( + 'fullscreenchange', + this.boundExitFullscreenHandler + ); + } else { + // For non-fullscreen + this.modalEl.close(); + this.element + .querySelector('.o-layered-image-viewer__osd') + .appendChild(this.osdMountEl); + // refocus after move + this.toolbar.viewer.buttons.fullscreen.focus(); + document.removeEventListener( + 'keydown', + this.boundExitFullscreenHandler + ); + } + // Revert gestures to pre-interaction state + this.interaction = false; + this.toolbar.viewer.buttons.fullscreen.ariaLabel = 'Fullscreen'; + } + } + + /** + * Handle exiting fullscreen + * Will fire (without effect) when fullscreenchange enters fullscreen + * @private + * @method + * @param {Event} e The event object form the fullscreenchange or keydown handler + */ + _exitFullscreenHandler(e) { + // For non-supporting browsers fullscreenElement is undefined + // The escape key needs to be handled + if ( + !this.browerSupportsFullscreen && + e.type === 'keydown' && + e.key === 'Escape' + ) { + this._setFullscreen(false); + } + // Escape or the browser inserted close button both trigger the fullscreenchange event + // Only handle this when exiting + if (e.type === 'fullscreenchange' && !document.fullscreenElement) { + this._setFullscreen(false); + } + } + + /** + * Reach into the current state and set the aria-label for the viewer + * @private + * @method + */ + _setMainAriaLabel() { + // Get label for each active overlay + const overlayLabels = this.overlays.active.map((activeIndex) => { + return `'${this.overlays.items[activeIndex].label}'`; + }); + + // 'b' label will only exist if initialised with multple images + const imageLabels = [`'${this.images.items[this.images.active.a].label}'`]; + this.images.active.b !== null && + imageLabels.push(`'${this.images.items[this.images.active.b].label}'`); + + // Convert labels array into string + const overlaysString = LayeredImageViewer.stringifyList(overlayLabels); + + const imagesString = LayeredImageViewer.stringifyList(imageLabels); + + const overlayNoun = overlayLabels.length > 1 ? 'overlays' : 'overlay'; + const imageNoun = imageLabels.length > 1 ? 'images' : 'image'; + + // Use label to describe the intent, and the current state. This will be announced before description. + this.viewer.canvas.ariaLabel = `Interactive image viewer. Currently showing ${imagesString} ${imageNoun}${ + overlayLabels.length + ? `, overlayed with ${overlaysString} ${overlayNoun}` + : '.' + }`; + } + + /** + * Initialise OpenSeadragon + * @private + * @method + */ + _initViewer() { + // OSD expects no siblings, keep it an orphan + // the destroy() method will preserve the initial HTML + + const mediaTemplate = document.createElement('template'); + let captionMarkup = ''; + + // Markup to be inserted if captionTitle / caption exist + if (this.captionEl || this.captionTitleEl) { + captionMarkup = `
`; + if (this.captionTitleEl) { + captionMarkup += ` +
+ ${this.captionTitleEl.innerHTML} +
`; + } + if (this.captionEl) { + captionMarkup += ` +
+ ${this.captionEl.innerHTML} +
`; + } + captionMarkup += `
`; + } + + // Markup to surround viewer with + // Modelled around the media molecule + mediaTemplate.innerHTML = ` +
+
+
+
+ ${captionMarkup} +
+ `; + + // Insert into class element + this.element.insertAdjacentElement( + 'beforeend', + mediaTemplate.content.firstElementChild + ); + + // Store reference of OSD element + this.osdMountEl = this.element.querySelector( + '.o-layered-image-viewer__osd-mount' + ); + + // Apect ratio for styling + this.osdMountEl.style.setProperty('--viewer-aspect', this.aspect); + + this.osdMountEl.style.display = 'block'; + + // Add modal container if necessary (no fullscreen support) + this.modalEl = document.querySelector('#layered-image-viewer-modal'); + if (!this.modalEl && !this.browerSupportsFullscreen) { + // Dialog element has the advantage of handling semantics and focus trap + this.modalEl = document.createElement('dialog'); + this.modalEl.id = 'layered-image-viewer-modal'; + this.modalEl.classList.add('o-layered-image-viewer__modal'); + document.body.appendChild(this.modalEl); + } + + // Initialise with default buttons / controls removed + // See: http://openseadragon.github.io/docs/OpenSeadragon.html#.Options + this.viewer = new OpenSeadragon({ + element: this.osdMountEl, + crossOriginPolicy: 'Anonymous', + showSequenceControl: false, + showHomeControl: false, + showZoomControl: false, + showFullPageControl: false, + visibilityRatio: 0.3, + homeFillsViewer: false, + autoHideControls: true, + showNavigator: true, + navigatorPosition: 'TOP_LEFT', + navigatorAutoFade: true, + tileSources: { + type: 'image', + url: this.images.items[0].url, // First image from markup by default + }, + }); + + this.osdMountEl.style.display = ''; + + this.viewer.addHandler('open', () => { + this._addControls(); + + // Assign initial active image layers + this.assignImageToLayer(0, 'a'); + this.assignImageToLayer(1, 'b'); + + // Set the start position if predefined + this._setCropRegion(); + + // Set the role to application to enable arrows while using screenreader + this.viewer.canvas.role = 'application'; + + // Set the descriptive text for the viewer + this._setMainAriaLabel(); + + // Description populated by the alt text. + // This is supplemental and read second to the label (skipped in some cicrumstances) + // ariaDescription due to become standard in ARIA 1.3, for now describedBy has better compatability + // described-by also allows multiple ID's + this.viewer.canvas.setAttribute( + 'aria-describedby', + `layered-image-viewer-${this.id}-images-0` + ); + + // Activate default overlays + const changeEvent = new Event('change'); + + this.overlays.default.forEach((index)=> { + this.overlays.items[index].checkboxEl.checked = true; + this.overlays.items[index].checkboxEl.dispatchEvent(changeEvent); + }); + + // Add resizeObserver + this._setViewerResizeObserver(); + + // Force interaction setter function to fire + this.interaction = false; + }); + } + + /** + * Destroy Viewer + * @public + * @static + * @method + * @param {HTMLElement} viewerEl - Element which was used to initialise the viewer to be destroyed + */ + static destroy(viewerEl) { + // Qualifying elements should have a layeredImageViewer stored inside + const instance = viewerEl.layeredImageViewer + + if (!instance) return; + + // Stop observers + instance.viewerResizeObserver.disconnect(); + + // Destroy OSD and remove elements added by this class + instance.viewer.destroy(); + viewerEl.querySelector('.o-layered-image-viewer__osd').remove(); + + // Cull events added outside the scope of the viewer + ['click', 'touchend'].forEach((event) => { + document.body.removeEventListener( + event, + instance.boundHandleExternalClick, + true + ); + }); + + delete viewerEl.layeredImageViewer; + } + + /** + * Transform string into kebab-case + * @public + * @static + * @method + * @param {String} string - String to transform + * @returns {String} - Kebab-case string + */ + static toKebabCase(string) { + return string.toLowerCase().replace(' ', '-'); + } + + /** + * Transform string into camelCase + * @public + * @static + * @method + * @param {String} string - String to transform + * @returns {String} - camelCase string + */ + static toCamelCase(string) { + return string + .toLowerCase() + .replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase()); + } + + /** + * Transform an array of strings into a sentenace-like string + * @public + * @static + * @method + * @param {Array} list - List of strings to serialize + * @returns {String} - String of joined array items + */ + static stringifyList(list) { + let string = ''; + if (list.length > 1) { + if (list.length === 2) { + string = list.join(' and '); + } else { + // With an Oxford comma + string = `${list.slice(0, -1).join(', ')}, and ${list.slice(-1)}`; + } + } else { + string = list.toString(); + } + return string; + } + + /** + * Create a button element for the viewer + * + * @private + * @method + * @param {Object} options - Label and icon to use + * @param {Array} classes - Classes to use on the button element + * @returns {HTMLButtonElement} - The complete button element + */ + _createIconButton(options, classes) { + const {label, icon, interaction } = options; + + this.buttonTemplate = + this.buttonTemplate || document.createElement('template'); + + this.buttonTemplate.innerHTML = ` + + `; + return this.buttonTemplate.content.firstElementChild; + } + + /** + * Add custom controls to OpenSeadragon + * @private + * @method + */ + _addControls() { + // The OSD mechanism for adding controls is a bit clunky + // The best way is probably to construct accessible markup and insert in one go + // (without really interacting with the OSD API) + // N.B. Deliberate decision against role=toolbar for now, there is potentially complex behviour to handle if we apply that role + // More info: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/toolbar_role + const viewerControls = [ + { + label: 'Fullscreen', + icon: 'icon--zoom--24', + interaction: 'modal', + }, + { + label: 'Zoom in', + icon: 'icon--zoom-in--24', + interaction: 'zoom', + }, + { + label: 'Zoom out', + icon: 'icon--zoom-out--24', + interaction: 'zoom' + }, + ]; + this.toolbar.viewer.element = document.createElement('div'); + this.toolbar.viewer.element.classList.add( + 'o-layered-image-viewer__viewer-toolbar' + ); + + // Add each standard button and register with instance for easy access + const standardButtonClasses = ['btn', 'btn--septenary', 'btn--icon-sq']; + viewerControls.forEach((control) => { + const buttonClasses = standardButtonClasses.concat( + `o-layered-image-viewer__${LayeredImageViewer.toKebabCase( + control.label + )}` + ); + const buttonEl = this._createIconButton(control, buttonClasses); + + // This seems to be announced anyway, but should probably be live + if (control.label === 'Fullscreen') { + buttonEl.ariaLive = 'polite'; + } + + this.toolbar.viewer.element.appendChild(buttonEl); + this.toolbar.viewer.buttons[ + LayeredImageViewer.toCamelCase(control.label) + ] = buttonEl; + }); + + // Add the completed toolbar to OSD + this.viewer.controls.topright.appendChild(this.toolbar.viewer.element); + + // Zoom In + this.toolbar.viewer.buttons.zoomIn.addEventListener('click', () => { + this.viewer.viewport.zoomBy(this.viewer.zoomPerClick / 1.0); + this.viewer.viewport.applyConstraints(); + }); + + // Zoom Out + this.toolbar.viewer.buttons.zoomOut.addEventListener('click', () => { + this.viewer.viewport.zoomBy(1.0 / this.viewer.zoomPerClick); + this.viewer.viewport.applyConstraints(); + }); + + // Fullscreen + this.toolbar.viewer.buttons.fullscreen.addEventListener('click', () => { + if (!this.isFullscreen) { + this._setFullscreen(true); + } else { + this._setFullscreen(false); + } + }); + + this.toolbar.layers.element = document.createElement('div'); + this.toolbar.layers.element.classList.add( + 'o-layered-image-viewer__layers-toolbar' + ); + + this.viewer.controls.bottomright.appendChild(this.toolbar.layers.element); + + // Control for opacity (if more than one image) + this._addOpacityControl(); + + // Control menu for image layer controls if neccessary + // (overlays present/more than one image) + this._addImageLayerControlMenu(); + + // Reset + // Add button to layers controls + this.toolbar.layers.reset = this._createIconButton( + { + label: 'Reset to initial state', + icon: 'icon--reset--24', + }, + standardButtonClasses.concat('o-layered-image-viewer__reset') + ); + + // Add to toolbar element + this.toolbar.layers.element.appendChild(this.toolbar.layers.reset); + + // Bind event handling + this.toolbar.layers.reset.addEventListener('click', () => { + // Set the viewer position to its initial state + if (this.cropRegion) { + this._setCropRegion(); + } else { + this.viewer.viewport.goHome(); + } + + // Set overlays to initial state + // (Requires events to be dispatched manually to trigger) + const changeEvent = new Event('change'); + this.overlays.items.forEach((overlay, i) => { + overlay.checkboxEl.checked = this.overlays.default.includes(i); + overlay.checkboxEl.dispatchEvent(changeEvent); + }); + + // Reset layers + this.assignImageToLayer(0, 'a'); + this.assignImageToLayer(1, 'b'); + + // Reset opacity + this.setOpacity(0); + }); + } + + /** + * + * @private + * @method + */ + _addOpacityControl() { + if (this.images.items.length < 2) return; + + const opacityTemplate = document.createElement('template'); + opacityTemplate.innerHTML = ` +
+ +
+ A + + B +
+
+ `; + + const opacityWrapperEl = opacityTemplate.content.firstElementChild; + this.opacitySliderEl = opacityWrapperEl.querySelector('input'); + + // Insert control + this.toolbar.layers.element.append(opacityWrapperEl); + + // Add event listener for slider + this.opacitySliderEl.addEventListener('input', (e) => { + // Invert value from slider + this.setOpacity(e.target.value); + }); + } + + /** + * Set opacity + * The closer to 1 this is the more of image A is shown + * + * @method + * @param {Number} opacity - Opacity to set. Should be integer between 0 and 100 + * @public + */ + setOpacity(opacity) { + // Invert value, set slider and update world item + this.opacitySliderEl.value = opacity; + this.viewer.world.getItemAt(1).setOpacity((100 - opacity) / 100); + + // Set custom prop for styling + this.opacitySliderEl.style.setProperty('--percent', opacity); + } + + /** + * Add a menu switching layers and toggling overlays + * @private + * @method + */ + _addImageLayerControlMenu() { + // Only show if overlays or multiple images exist + if (!this.overlays.items.length && this.images.items.length < 2) return; + + // Create template markup + const detailsTemplate = document.createElement('template'); + detailsTemplate.innerHTML = ` +
+ + Image layer options + + +
+ +
+
`; + const detailsEl = detailsTemplate.content.firstElementChild; + this.toolbar.layers.controls = { + element: detailsEl, + menu: detailsEl.querySelector('.o-layered-image-viewer-details__menu'), + }; + + // Handle actions that should close menu + const closeHandler = (e) => { + if ( + (e.type === 'click' && !detailsEl.contains(e.target)) || + (e.type === 'keydown' && e.key === 'Escape') + ) { + detailsEl.open = false; + } + }; + detailsEl + .querySelector(`#o-layered-image-viewer-${this.id}-details__close`) + .addEventListener('click', (e) => { + e.target.closest('details').querySelector('summary').click() + }); + const menuEl = detailsEl.lastElementChild; + + // Attach / remove listeners to close as menu toggles + detailsEl.addEventListener('toggle', () => { + if (detailsEl.open) { + // Set scroll to top when opening + menuEl.scrollTop = 0; + + // Disable click to zoom + this.viewer.gestureSettingsMouse.clickToZoom = false; + + this.viewer.element.addEventListener('click', closeHandler, true); + this.viewer.element.addEventListener('keydown', closeHandler, true); + } else { + // Re-enable click to zoom + this.viewer.gestureSettingsMouse.clickToZoom = true; + + this.viewer.element.removeEventListener('click', closeHandler); + this.viewer.element.removeEventListener('keydown', closeHandler); + } + }); + + // Output images + if (this.images.items.length > 1) { + const imagesTemplate = document.createElement('template'); + imagesTemplate.innerHTML = ` +
+

Image layers

+
+

Select two views to compare on screen.

+

Layer A

+

Layer B

+
+
+
+
`; + const imagesWrapperEl = imagesTemplate.content.firstElementChild; + + // Build up markup for the images + // Each item becoming a radio button / label combo + const imagesFieldTemplate = document.createElement('template'); + this.images.items.forEach((item, i) => { + imagesFieldTemplate.innerHTML = ` +
+
+ ${item.label} + + + + + + + + + + + + +
+
+ `; + + const rowEl = imagesFieldTemplate.content.firstElementChild; + const rowOptEls = rowEl.querySelectorAll('input'); + item.controlEls = { + a: rowOptEls[0], + b: rowOptEls[1], + }; + + imagesWrapperEl.lastElementChild.appendChild(rowEl); + menuEl.appendChild(imagesWrapperEl); + + // Add event listener to radio buttons + // When any button changes: + rowOptEls.forEach((optEl) => { + optEl.addEventListener('change', (e) => { + this._handleControlImageChange( + parseInt(e.target.dataset.index, 10), + e.target.id.slice(-1) + ); + }); + }); + }); + } + + // Output overlays + if (this.overlays.items.length) { + const overlaysTemplate = document.createElement('template'); + overlaysTemplate.innerHTML = ` +
+

Overlays

+
+
+
`; + const overlaysWrapperEl = overlaysTemplate.content.firstElementChild; + + // Build up markup for the overlays + // Each item becoming a checkbox / label combo + const overlayFieldTemplate = document.createElement('template'); + this.overlays.items.forEach((item, i) => { + overlayFieldTemplate.innerHTML = ` +
+ + + + + + +
+ `; + + const rowEl = overlayFieldTemplate.content.firstElementChild; + this.overlays.items[i].checkboxEl = + rowEl.firstElementChild.firstElementChild; + + // Attach toggle handling + this.overlays.items[i].checkboxEl.addEventListener('change', (e) => { + if (e.target.checked) { + // Turn overlay on + this.activateOverlay(parseInt(e.target.dataset.index, 10)); + } else { + // Turn overlay off + this.deactivateOverlay(parseInt(e.target.dataset.index, 10)); + } + // Update aria label + this._setMainAriaLabel(); + }); + + // Add completed row to wrapper + overlaysWrapperEl.lastElementChild.appendChild(rowEl); + }); + + // Add wrapper to menu + menuEl.appendChild(overlaysWrapperEl); + } + + // Add menu to toolbar + this.toolbar.layers.element.appendChild(detailsEl); + } + + /** + * Use the URL's for the active images to set appropriate images in OSD + * @private + * @method + */ + _setWorldItems() { + const worldItemCount = this.viewer.world.getItemCount(); + const worldItems = { + a: this.viewer.world.getItemAt(worldItemCount === 1 ? 0 : 1), + }; + const activeItems = { + a: this.images.items[this.images.active.a], + b: this.images.items[this.images.active.b], + }; + + // Require 'a' and 'b' to be set + if (!activeItems.a || !activeItems.b) return; + + // Set worldItem.b if it exists (after initialisation) + if (worldItemCount > 1) { + worldItems.b = this.viewer.world.getItemAt(0); + } + + if (worldItems['a'].source.url === activeItems['b'].url) { + // Detect flip and swap world items + // Reset / reapply UI opacity to world items + this.viewer.world.getItemAt(1).setOpacity(0.999); + this.viewer.world.setItemIndex(this.viewer.world.getItemAt(0), 1); + this.viewer.world.getItemAt(1).setOpacity(1 - this.opacitySliderEl.value / 100); + } else { + // Loop active items and set images + ['a', 'b'].forEach((key) => { + // If a / b exists + if (worldItems[key]) { + if (worldItems[key].source.url !== activeItems[key].url) { + // Add new image on top ([2, 1, 0]) + this.viewer.addSimpleImage({ + url: activeItems[key].url, + index: 2, + opacity: 0.999, + preload: true, + success: () => { + // From this point query world directly to get fresh references + // Remove the image this replaces + this.viewer.world.removeItem( + this.viewer.world.getItemAt(key === 'a' ? 1 : 0) + ); + // Set the new image to 'a' top, or 'b' bottom + this.viewer.world.setItemIndex( + this.viewer.world.getItemAt(1), + key === 'a' ? 1 : 0 + ); + + // If layer 'a' changes, reapply to world item only + this.setOpacity(this.opacitySliderEl.value / 100); + }, + }); + } + } else { + // Create if necessary (initialisation) + this.viewer.addSimpleImage({ + url: activeItems[key].url, + index: key === 'b' ? 0 : 1, + opacity: 0.999, + success: () => { + // Set initial opacity + // The class method updates the UI + world item + this.setOpacity(0); + }, + }); + } + }); + } + } + + /** + * Handle change events on image controls + * @private + * @method + * @param {Number} index - Integer for target image control + * @param {'a'|'b'} layer - Layer to handle change on + */ + _handleControlImageChange(index, layer) { + const targetEl = this.images.items[index].controlEls[layer]; + + // Move to parent and checked items + const allCheckedOptEls = targetEl + .closest('.layered-image-viewer-details__section--images') + .querySelectorAll('input:checked'); + + // 2 = perform flip on the non-target adjacent + // not null checks because initalise/assign may enter here and cause unintended flip + if ( + allCheckedOptEls.length === 2 && + this.images.active.a !== null && + this.images.active.b !== null + ) { + Array.prototype.filter + .call(allCheckedOptEls, (item) => { + return item !== targetEl; + }) + .forEach((item) => { + // flipEl is somehow adjacent, layer === a is next and vice-versa + const flipEl = + layer !== 'a' + ? item.closest('.radio').previousElementSibling.firstElementChild + : item.closest('.radio').nextElementSibling.firstElementChild; + + // Update DOM + item.checked = false; + flipEl.checked = true; + + // Update state + this.images.active[layer === 'a' ? 'a' : 'b'] = index; + this.images.active[layer === 'a' ? 'b' : 'a'] = parseInt( + flipEl.dataset.index + ); + }); + } + + // More than 2 (only 3 should be possible) = unset any in column matching target + // Excluding target + else if (allCheckedOptEls.length > 2) { + Array.prototype.filter + .call(allCheckedOptEls, (item) => { + return item.id.slice(-1) === layer && item !== targetEl; + }) + .forEach((item) => { + // Update DOM + item.checked = false; + + // Update state + this.images.active[layer] = index; + }); + } else { + // Should only trigger when initialising + this.images.items[index].controlEls[layer].checked = true; + this.images.active[layer] = index; + } + + // Update images in viewer + this._setWorldItems(); + + // Update aria label + this._setMainAriaLabel(); + } + + /** + * Set a given image index to a named layer + * @public + * @method + * @param {Number} index - Integer for target image element + * @param {'a'|'b'} layer - Layer to assign image to + */ + assignImageToLayer(index, layer) { + if (!this.images.items[index]) return; + + // Control elements only present for multiple images + if (this.images.items.length > 1) { + // Set active to null to prevent flip operations + this.images.active[layer] = null; + + const changeEvent = new Event('change'); + this.images.items[index].controlEls[layer].checked = true; + this.images.items[index].controlEls[layer].dispatchEvent(changeEvent); + } else { + // Manually set layer for single image + this.images.active[layer] = index; + } + + } + + /** + * Activate an overlay by the internally tracked index + * @public + * @method + * @param {Number} index - Index of overlay to activate. Mirrors the order of the initial HTML + */ + activateOverlay(index) { + if (!this.overlays.items[index]) return; + + // There's two potential ways of doing this AFAIK + // 1. Add an image. This doesn't work well with SVG + // 2. Add an overlay. This works with imgs/svgs/html + // There's also OpenSeadragon svgOverlay plugin, which from what I can tell + // seems to be if you're working with arbitrary SVG code and not really suited to our files. + + // Clone our overlay, otherwise OSD seems to want to move it + // (which makes destruction cleanup hard) + const cloneEl = this.overlays.element + .querySelector(`#layered-image-viewer-${this.id}-overlays-${index}`) + .cloneNode(); + cloneEl.id = `layered-image-viewer-${this.id}-overlays-${index}-clone`; + + // May already be active (e.g. if on by default + reset) + if (!this.overlays.active.includes(index)) { + + // Add to active list + this.overlays.active.push(index); + + this.viewer.addOverlay({ + element: cloneEl, + location: new OpenSeadragon.Point(0, 0), + width: 1, // (viewport unit) + index: index, + opacity: 0.4, + }); + } + + } + + /** + * Deactivate an overlay by the internally tracked index + * @public + * @method + * @param {Number} index - Index of overlay to activate. Mirrors the order of the initial HTML + */ + deactivateOverlay(index) { + if (!this.overlays.items[index]) return; + + // Remove from active list + this.overlays.active = this.overlays.active.filter( + (item) => item !== index + ); + + this.viewer.removeOverlay( + `layered-image-viewer-${this.id}-overlays-${index}-clone` + ); + } +} + +const layeredImageViewer = function(container) { + this.init = function() { + new LayeredImageViewer(container); + }; + this.destroy = function() { + LayeredImageViewer.destroy(container); + }; +}; + +export default layeredImageViewer; diff --git a/frontend/js/layeredImageViewer.js b/frontend/js/layeredImageViewer.js new file mode 100644 index 000000000..55407a31b --- /dev/null +++ b/frontend/js/layeredImageViewer.js @@ -0,0 +1,6 @@ +import { manageBehaviors } from '@area17/a17-helpers'; +import * as Behaviors from './behaviors/layeredImageViewer'; + +document.addEventListener('DOMContentLoaded', function() { + manageBehaviors(Behaviors); +}); diff --git a/frontend/js/libs/openseadragon4.min.js b/frontend/js/libs/openseadragon4.min.js new file mode 100644 index 000000000..e0887f983 --- /dev/null +++ b/frontend/js/libs/openseadragon4.min.js @@ -0,0 +1,8 @@ +//! openseadragon 4.0.0 +//! Built on 2022-12-16 +//! Git commit: v4.0.0-0-8e6196a +//! http://openseadragon.github.io +//! License: http://openseadragon.github.io/license/ + + +function OpenSeadragon(e){return new OpenSeadragon.Viewer(e)}!function(n){n.version={versionStr:"4.0.0",major:parseInt("4",10),minor:parseInt("0",10),revision:parseInt("0",10)};var t={"[object Boolean]":"boolean","[object Number]":"number","[object String]":"string","[object Function]":"function","[object Array]":"array","[object Date]":"date","[object RegExp]":"regexp","[object Object]":"object"},i=Object.prototype.toString,o=Object.prototype.hasOwnProperty;n.isFunction=function(e){return"function"===n.type(e)};n.isArray=Array.isArray||function(e){return"array"===n.type(e)};n.isWindow=function(e){return e&&"object"==typeof e&&"setInterval"in e};n.type=function(e){return null==e?String(e):t[i.call(e)]||"object"};n.isPlainObject=function(e){if(!e||"object"!==OpenSeadragon.type(e)||e.nodeType||n.isWindow(e))return!1;if(e.constructor&&!o.call(e,"constructor")&&!o.call(e.constructor.prototype,"isPrototypeOf"))return!1;var t;for(var i in e)t=i;return void 0===t||o.call(e,t)};n.isEmptyObject=function(e){for(var t in e)return!1;return!0};n.freezeObject=function(e){Object.freeze?n.freezeObject=Object.freeze:n.freezeObject=function(e){return e};return n.freezeObject(e)};n.supportsCanvas=(e=document.createElement("canvas"),!(!n.isFunction(e.getContext)||!e.getContext("2d")));var e;n.isCanvasTainted=function(e){var t=!1;try{e.getContext("2d").getImageData(0,0,1,1)}catch(e){t=!0}return t};n.supportsAddEventListener=!(!document.documentElement.addEventListener||!document.addEventListener);n.supportsRemoveEventListener=!(!document.documentElement.removeEventListener||!document.removeEventListener);n.supportsEventListenerOptions=function(){var t=0;if(n.supportsAddEventListener)try{var e={get capture(){t++;return!1},get once(){t++;return!1},get passive(){t++;return!1}};window.addEventListener("test",null,e);window.removeEventListener("test",null,e)}catch(e){t=0}return 3<=t}();n.getCurrentPixelDensityRatio=function(){if(n.supportsCanvas){var e=document.createElement("canvas").getContext("2d");var t=window.devicePixelRatio||1;e=e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return Math.max(t,1)/e}return 1};n.pixelDensityRatio=n.getCurrentPixelDensityRatio()}(OpenSeadragon);!function(u){u.extend=function(){var e,t,i,n,o,r=arguments[0]||{},s=arguments.length,a=!1,l=1;if("boolean"==typeof r){a=r;r=arguments[1]||{};l=2}"object"==typeof r||OpenSeadragon.isFunction(r)||(r={});if(s===l){r=this;--l}for(;l=i.x&&t.x=i.y},getMousePosition:function(e){if("number"==typeof e.pageX)u.getMousePosition=function(e){var t=new u.Point;t.x=e.pageX;t.y=e.pageY;return t};else{if("number"!=typeof e.clientX)throw new Error("Unknown event mouse position, no known technique.");u.getMousePosition=function(e){var t=new u.Point;t.x=e.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;t.y=e.clientY+document.body.scrollTop+document.documentElement.scrollTop;return t}}return u.getMousePosition(e)},getPageScroll:function(){var e=document.documentElement||{},t=document.body||{};if("number"==typeof window.pageXOffset)u.getPageScroll=function(){return new u.Point(window.pageXOffset,window.pageYOffset)};else if(t.scrollLeft||t.scrollTop)u.getPageScroll=function(){return new u.Point(document.body.scrollLeft,document.body.scrollTop)};else{if(!e.scrollLeft&&!e.scrollTop)return new u.Point(0,0);u.getPageScroll=function(){return new u.Point(document.documentElement.scrollLeft,document.documentElement.scrollTop)}}return u.getPageScroll()},setPageScroll:function(e){if(void 0!==window.scrollTo)u.setPageScroll=function(e){window.scrollTo(e.x,e.y)};else{var t=u.getPageScroll();if(t.x===e.x&&t.y===e.y)return;document.body.scrollLeft=e.x;document.body.scrollTop=e.y;var i=u.getPageScroll();if(i.x!==t.x&&i.y!==t.y){u.setPageScroll=function(e){document.body.scrollLeft=e.x;document.body.scrollTop=e.y};return}document.documentElement.scrollLeft=e.x;document.documentElement.scrollTop=e.y;if((i=u.getPageScroll()).x!==t.x&&i.y!==t.y){u.setPageScroll=function(e){document.documentElement.scrollLeft=e.x;document.documentElement.scrollTop=e.y};return}u.setPageScroll=function(e){}}u.setPageScroll(e)},getWindowSize:function(){var e=document.documentElement||{},t=document.body||{};if("number"==typeof window.innerWidth)u.getWindowSize=function(){return new u.Point(window.innerWidth,window.innerHeight)};else if(e.clientWidth||e.clientHeight)u.getWindowSize=function(){return new u.Point(document.documentElement.clientWidth,document.documentElement.clientHeight)};else{if(!t.clientWidth&&!t.clientHeight)throw new Error("Unknown window size, no known technique.");u.getWindowSize=function(){return new u.Point(document.body.clientWidth,document.body.clientHeight)}}return u.getWindowSize()},makeCenteredNode:function(e){e=u.getElement(e);var t=[u.makeNeutralElement("div"),u.makeNeutralElement("div"),u.makeNeutralElement("div")];u.extend(t[0].style,{display:"table",height:"100%",width:"100%"});u.extend(t[1].style,{display:"table-row"});u.extend(t[2].style,{display:"table-cell",verticalAlign:"middle",textAlign:"center"});t[0].appendChild(t[1]);t[1].appendChild(t[2]);t[2].appendChild(e);return t[0]},makeNeutralElement:function(e){var t=document.createElement(e),e=t.style;e.background="transparent none";e.border="none";e.margin="0px";e.padding="0px";e.position="static";return t},now:function(){Date.now?u.now=Date.now:u.now=function(){return(new Date).getTime()};return u.now()},makeTransparentImage:function(e){var t=u.makeNeutralElement("img");t.src=e;return t},setElementOpacity:function(e,t,i){e=u.getElement(e);i&&!u.Browser.alpha&&(t=Math.round(t));if(u.Browser.opacity)e.style.opacity=t<1?t:"";else if(t<1){t=Math.round(100*t);e.style.filter="alpha(opacity="+t+")"}else e.style.filter=""},setElementTouchActionNone:function(e){void 0!==(e=u.getElement(e)).style.touchAction?e.style.touchAction="none":void 0!==e.style.msTouchAction&&(e.style.msTouchAction="none")},setElementPointerEvents:function(e,t){void 0!==(e=u.getElement(e)).style&&void 0!==e.style.pointerEvents&&(e.style.pointerEvents=t)},setElementPointerEventsNone:function(e){u.setElementPointerEvents(e,"none")},addClass:function(e,t){(e=u.getElement(e)).className?-1===(" "+e.className+" ").indexOf(" "+t+" ")&&(e.className+=" "+t):e.className=t},indexOf:function(e,t,i){Array.prototype.indexOf?this.indexOf=function(e,t,i){return e.indexOf(t,i)}:this.indexOf=function(e,t,i){var n,o,i=i||0;if(!e)throw new TypeError;if(0===(o=e.length)||o<=i)return-1;for(n=i=i<0?o-Math.abs(i):i;nt.touches.length-r&&c.console.warn("Tracked touch contact count doesn't match event.touches.length");var a={originalEvent:t,eventType:"pointerdown",pointerType:"touch",isEmulated:!1};H(e,a);for(n=0;n\s*$/))n=m.parseXml(n);else if(n.match(/^\s*[{[].*[}\]]\s*$/))try{var e=m.parseJSON(n);n=e}catch(e){}function l(e,t){if(e.ready)r(e);else{e.addHandler("ready",function(){r(e)});e.addHandler("open-failed",function(e){s({message:e.message,source:t})})}}setTimeout(function(){if("string"===m.type(n))(n=new m.TileSource({url:n,crossOriginPolicy:(void 0!==o.crossOriginPolicy?o:i).crossOriginPolicy,ajaxWithCredentials:i.ajaxWithCredentials,ajaxHeaders:o.ajaxHeaders||i.ajaxHeaders,splitHashDataForPost:i.splitHashDataForPost,useCanvas:i.useCanvas,success:function(e){r(e.tileSource)}})).addHandler("open-failed",function(e){s(e)});else if(m.isPlainObject(n)||n.nodeType){void 0!==n.crossOriginPolicy||void 0===o.crossOriginPolicy&&void 0===i.crossOriginPolicy||(n.crossOriginPolicy=(void 0!==o.crossOriginPolicy?o:i).crossOriginPolicy);void 0===n.ajaxWithCredentials&&(n.ajaxWithCredentials=i.ajaxWithCredentials);void 0===n.useCanvas&&(n.useCanvas=i.useCanvas);if(m.isFunction(n.getTileUrl)){var e=new m.TileSource(n);e.getTileUrl=n.getTileUrl;r(e)}else{var t=m.TileSource.determineType(a,n);if(t){e=t.prototype.configure.apply(a,[n]);l(new t(e),n)}else s({message:"Unable to load TileSource",source:n})}}else l(n,n)})}(this,i.tileSource,i,function(e){o.tileSource=e;s()},function(e){e.options=i;t(e);s()})}function s(){var e,t;for(;n._loadQueue.length&&(e=n._loadQueue[0]).tileSource;){n._loadQueue.splice(0,1);if(e.options.replace){var i=n.world.getIndexOfItem(e.options.replaceItem);-1!==i&&(e.options.index=i);n.world.removeItem(e.options.replaceItem)}t=new m.TiledImage({viewer:n,source:e.tileSource,viewport:n.viewport,drawer:n.drawer,tileCache:n.tileCache,imageLoader:n.imageLoader,x:e.options.x,y:e.options.y,width:e.options.width,height:e.options.height,fitBounds:e.options.fitBounds,fitBoundsPlacement:e.options.fitBoundsPlacement,clip:e.options.clip,placeholderFillStyle:e.options.placeholderFillStyle,opacity:e.options.opacity,preload:e.options.preload,degrees:e.options.degrees,flipped:e.options.flipped,compositeOperation:e.options.compositeOperation,springStiffness:n.springStiffness,animationTime:n.animationTime,minZoomImageRatio:n.minZoomImageRatio,wrapHorizontal:n.wrapHorizontal,wrapVertical:n.wrapVertical,immediateRender:n.immediateRender,blendTime:n.blendTime,alwaysBlend:n.alwaysBlend,minPixelRatio:n.minPixelRatio,smoothTileEdgesMinZoom:n.smoothTileEdgesMinZoom,iOSDevice:n.iOSDevice,crossOriginPolicy:e.options.crossOriginPolicy,ajaxWithCredentials:e.options.ajaxWithCredentials,loadTilesWithAjax:e.options.loadTilesWithAjax,ajaxHeaders:e.options.ajaxHeaders,debugMode:n.debugMode,subPixelRoundingForTransparency:n.subPixelRoundingForTransparency});n.collectionMode&&n.world.setAutoRefigureSizes(!1);if(n.navigator){i=m.extend({},e.options,{replace:!1,originalTiledImage:t,tileSource:e.tileSource});n.navigator.addTiledImage(i)}n.world.addItem(t,{index:e.options.index});0===n._loadQueue.length&&r(e);1!==n.world.getItemCount()||n.preserveViewport||n.viewport.goHome(!0);e.options.success&&e.options.success({item:t})}}},addSimpleImage:function(e){m.console.assert(e,"[Viewer.addSimpleImage] options is required");m.console.assert(e.url,"[Viewer.addSimpleImage] options.url is required");e=m.extend({},e,{tileSource:{type:"image",url:e.url}});delete e.url;this.addTiledImage(e)},addLayer:function(t){var i=this;m.console.error("[Viewer.addLayer] this function is deprecated; use Viewer.addTiledImage() instead.");var e=m.extend({},t,{success:function(e){i.raiseEvent("add-layer",{options:t,drawer:e.item})},error:function(e){i.raiseEvent("add-layer-failed",e)}});this.addTiledImage(e);return this},getLayerAtLevel:function(e){m.console.error("[Viewer.getLayerAtLevel] this function is deprecated; use World.getItemAt() instead.");return this.world.getItemAt(e)},getLevelOfLayer:function(e){m.console.error("[Viewer.getLevelOfLayer] this function is deprecated; use World.getIndexOfItem() instead.");return this.world.getIndexOfItem(e)},getLayersCount:function(){m.console.error("[Viewer.getLayersCount] this function is deprecated; use World.getItemCount() instead.");return this.world.getItemCount()},setLayerLevel:function(e,t){m.console.error("[Viewer.setLayerLevel] this function is deprecated; use World.setItemIndex() instead.");return this.world.setItemIndex(e,t)},removeLayer:function(e){m.console.error("[Viewer.removeLayer] this function is deprecated; use World.removeItem() instead.");return this.world.removeItem(e)},forceRedraw:function(){c[this.hash].forceRedraw=!0;return this},forceResize:function(){c[this.hash].needsResize=!0;c[this.hash].forceResize=!0},bindSequenceControls:function(){var e=m.delegate(this,v),t=m.delegate(this,f),i=m.delegate(this,this.goToNextPage),n=m.delegate(this,this.goToPreviousPage),o=this.navImages,r=!0;if(this.showSequenceControl){(this.previousButton||this.nextButton)&&(r=!1);this.previousButton=new m.Button({element:this.previousButton?m.getElement(this.previousButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.PreviousPage"),srcRest:B(this.prefixUrl,o.previous.REST),srcGroup:B(this.prefixUrl,o.previous.GROUP),srcHover:B(this.prefixUrl,o.previous.HOVER),srcDown:B(this.prefixUrl,o.previous.DOWN),onRelease:n,onFocus:e,onBlur:t});this.nextButton=new m.Button({element:this.nextButton?m.getElement(this.nextButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.NextPage"),srcRest:B(this.prefixUrl,o.next.REST),srcGroup:B(this.prefixUrl,o.next.GROUP),srcHover:B(this.prefixUrl,o.next.HOVER),srcDown:B(this.prefixUrl,o.next.DOWN),onRelease:i,onFocus:e,onBlur:t});this.navPrevNextWrap||this.previousButton.disable();this.tileSources&&this.tileSources.length||this.nextButton.disable();if(r){this.paging=new m.ButtonGroup({buttons:[this.previousButton,this.nextButton],clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold});this.pagingControl=this.paging.element;this.toolbar?this.toolbar.addControl(this.pagingControl,{anchor:m.ControlAnchor.BOTTOM_RIGHT}):this.addControl(this.pagingControl,{anchor:this.sequenceControlAnchor||m.ControlAnchor.TOP_LEFT})}}return this},bindStandardControls:function(){var e=m.delegate(this,z),t=m.delegate(this,L),i=m.delegate(this,F),n=m.delegate(this,H),o=m.delegate(this,M),r=m.delegate(this,A),s=m.delegate(this,U),a=m.delegate(this,W),l=m.delegate(this,V),h=m.delegate(this,G),c=m.delegate(this,v),u=m.delegate(this,f),d=this.navImages,p=[],g=!0;if(this.showNavigationControl){(this.zoomInButton||this.zoomOutButton||this.homeButton||this.fullPageButton||this.rotateLeftButton||this.rotateRightButton||this.flipButton)&&(g=!1);if(this.showZoomControl){p.push(this.zoomInButton=new m.Button({element:this.zoomInButton?m.getElement(this.zoomInButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.ZoomIn"),srcRest:B(this.prefixUrl,d.zoomIn.REST),srcGroup:B(this.prefixUrl,d.zoomIn.GROUP),srcHover:B(this.prefixUrl,d.zoomIn.HOVER),srcDown:B(this.prefixUrl,d.zoomIn.DOWN),onPress:e,onRelease:t,onClick:i,onEnter:e,onExit:t,onFocus:c,onBlur:u}));p.push(this.zoomOutButton=new m.Button({element:this.zoomOutButton?m.getElement(this.zoomOutButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.ZoomOut"),srcRest:B(this.prefixUrl,d.zoomOut.REST),srcGroup:B(this.prefixUrl,d.zoomOut.GROUP),srcHover:B(this.prefixUrl,d.zoomOut.HOVER),srcDown:B(this.prefixUrl,d.zoomOut.DOWN),onPress:n,onRelease:t,onClick:o,onEnter:n,onExit:t,onFocus:c,onBlur:u}))}this.showHomeControl&&p.push(this.homeButton=new m.Button({element:this.homeButton?m.getElement(this.homeButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.Home"),srcRest:B(this.prefixUrl,d.home.REST),srcGroup:B(this.prefixUrl,d.home.GROUP),srcHover:B(this.prefixUrl,d.home.HOVER),srcDown:B(this.prefixUrl,d.home.DOWN),onRelease:r,onFocus:c,onBlur:u}));this.showFullPageControl&&p.push(this.fullPageButton=new m.Button({element:this.fullPageButton?m.getElement(this.fullPageButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.FullPage"),srcRest:B(this.prefixUrl,d.fullpage.REST),srcGroup:B(this.prefixUrl,d.fullpage.GROUP),srcHover:B(this.prefixUrl,d.fullpage.HOVER),srcDown:B(this.prefixUrl,d.fullpage.DOWN),onRelease:s,onFocus:c,onBlur:u}));if(this.showRotationControl){p.push(this.rotateLeftButton=new m.Button({element:this.rotateLeftButton?m.getElement(this.rotateLeftButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.RotateLeft"),srcRest:B(this.prefixUrl,d.rotateleft.REST),srcGroup:B(this.prefixUrl,d.rotateleft.GROUP),srcHover:B(this.prefixUrl,d.rotateleft.HOVER),srcDown:B(this.prefixUrl,d.rotateleft.DOWN),onRelease:a,onFocus:c,onBlur:u}));p.push(this.rotateRightButton=new m.Button({element:this.rotateRightButton?m.getElement(this.rotateRightButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.RotateRight"),srcRest:B(this.prefixUrl,d.rotateright.REST),srcGroup:B(this.prefixUrl,d.rotateright.GROUP),srcHover:B(this.prefixUrl,d.rotateright.HOVER),srcDown:B(this.prefixUrl,d.rotateright.DOWN),onRelease:l,onFocus:c,onBlur:u}))}this.showFlipControl&&p.push(this.flipButton=new m.Button({element:this.flipButton?m.getElement(this.flipButton):null,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold,tooltip:m.getString("Tooltips.Flip"),srcRest:B(this.prefixUrl,d.flip.REST),srcGroup:B(this.prefixUrl,d.flip.GROUP),srcHover:B(this.prefixUrl,d.flip.HOVER),srcDown:B(this.prefixUrl,d.flip.DOWN),onRelease:h,onFocus:c,onBlur:u}));if(g){this.buttonGroup=new m.ButtonGroup({buttons:p,clickTimeThreshold:this.clickTimeThreshold,clickDistThreshold:this.clickDistThreshold});this.navControl=this.buttonGroup.element;this.addHandler("open",m.delegate(this,N));(this.toolbar||this).addControl(this.navControl,{anchor:this.navigationControlAnchor||m.ControlAnchor.TOP_LEFT})}else this.customButtons=p}return this},currentPage:function(){return this._sequenceIndex},goToPage:function(e){if(this.tileSources&&0<=e&&e=this.tileSources.length&&(e=0);this.goToPage(e)},isAnimating:function(){return c[this.hash].animating}});function r(e){e=m.getElement(e);return new m.Point(0===e.clientWidth?1:e.clientWidth,0===e.clientHeight?1:e.clientHeight)}function h(e,t){if(t instanceof m.Overlay)return t;var i=null;if(t.element)i=m.getElement(t.element);else{var n=t.id||"openseadragon-overlay-"+Math.floor(1e7*Math.random());(i=m.getElement(t.id))||((i=document.createElement("a")).href="#/overlay/"+n);i.id=n;m.addClass(i,t.className||"openseadragon-overlay")}var o=t.location;var r=t.width;var s=t.height;if(!o){n=t.x;var a=t.y;if(void 0!==t.px){e=e.viewport.imageToViewportRectangle(new m.Rect(t.px,t.py,r||0,s||0));n=e.x;a=e.y;r=void 0!==r?e.width:void 0;s=void 0!==s?e.height:void 0}o=new m.Point(n,a)}a=t.placement;a&&"string"===m.type(a)&&(a=m.Placement[t.placement.toUpperCase()]);return new m.Overlay({element:i,location:o,placement:a,onDraw:t.onDraw,checkResize:t.checkResize,width:r,height:s,rotationMode:t.rotationMode})}function s(e,t){var i;for(i=e.length-1;0<=i;i--)if(e[i].element===t)return i;return-1}function a(e,t){return m.requestAnimationFrame(function(){t(e)})}function l(e){m.requestAnimationFrame(function(){!function(e){var t,i,n;if(e.controlsShouldFade){t=m.now();t=t-e.controlsFadeBeginTime;i=1-t/e.controlsFadeLength;i=Math.min(1,i);i=Math.max(0,i);for(n=e.controls.length-1;0<=n;n--)e.controls[n].autoFade&&e.controls[n].setOpacity(i);0=t.flickMinSpeed){var n=0;this.panHorizontal&&(n=t.flickMomentum*e.speed*Math.cos(e.direction));i=0;this.panVertical&&(i=t.flickMomentum*e.speed*Math.sin(e.direction));e=this.viewport.pixelFromPoint(this.viewport.getCenter(!0));i=this.viewport.pointFromPixel(new m.Point(e.x-n,e.y-i));this.viewport.panTo(i,!1)}this.viewport.applyConstraints()}t.dblClickDragToZoom&&!0===c[this.hash].draggingToZoom&&(c[this.hash].draggingToZoom=!1)}function S(e){this.raiseEvent("canvas-enter",{tracker:e.eventSource,pointerType:e.pointerType,position:e.position,buttons:e.buttons,pointers:e.pointers,insideElementPressed:e.insideElementPressed,buttonDownAny:e.buttonDownAny,originalEvent:e.originalEvent})}function E(e){this.raiseEvent("canvas-exit",{tracker:e.eventSource,pointerType:e.pointerType,position:e.position,buttons:e.buttons,pointers:e.pointers,insideElementPressed:e.insideElementPressed,buttonDownAny:e.buttonDownAny,originalEvent:e.originalEvent})}function P(e){this.raiseEvent("canvas-press",{tracker:e.eventSource,pointerType:e.pointerType,position:e.position,insideElementPressed:e.insideElementPressed,insideElementReleased:e.insideElementReleased,originalEvent:e.originalEvent});if(this.gestureSettingsByDeviceType(e.pointerType).dblClickDragToZoom){var t=c[this.hash].lastClickTime;e=m.now();if(null!==t){e-tthis.minScrollDeltaTime){this._lastScrollTime=n;t={tracker:e.eventSource,position:e.position,scroll:e.scroll,shift:e.shift,originalEvent:e.originalEvent,preventDefaultAction:!1,preventDefault:!0};this.raiseEvent("canvas-scroll",t);if(!t.preventDefaultAction&&this.viewport){this.viewport.flipped&&(e.position.x=this.viewport.getContainerSize().x-e.position.x);if((i=this.gestureSettingsByDeviceType(e.pointerType)).scrollToZoom){n=Math.pow(this.zoomPerScroll,e.scroll);this.viewport.zoomBy(n,i.zoomToRefPoint?this.viewport.pointFromPixel(e.position,!0):null);this.viewport.applyConstraints()}}e.preventDefault=t.preventDefault}else e.preventDefault=!0}function I(e){c[this.hash].mouseInside=!0;n(this);this.raiseEvent("container-enter",{tracker:e.eventSource,pointerType:e.pointerType,position:e.position,buttons:e.buttons,pointers:e.pointers,insideElementPressed:e.insideElementPressed,buttonDownAny:e.buttonDownAny,originalEvent:e.originalEvent})}function O(e){if(e.pointers<1){c[this.hash].mouseInside=!1;c[this.hash].animating||u(this)}this.raiseEvent("container-exit",{tracker:e.eventSource,pointerType:e.pointerType,position:e.position,buttons:e.buttons,pointers:e.pointers,insideElementPressed:e.insideElementPressed,buttonDownAny:e.buttonDownAny,originalEvent:e.originalEvent})}function k(e){!function(e){if(!e._opening&&c[e.hash]){if(e.autoResize||c[e.hash].forceResize){if(e._autoResizePolling){i=r(e.container);var t=c[e.hash].prevContainerSize;i.equals(t)||(c[e.hash].needsResize=!0)}c[e.hash].needsResize&&function(e,t){var i=e.viewport;var n=i.getZoom();var o=i.getCenter();i.resize(t,e.preserveImageSizeOnResize);i.panTo(o,!0);var r;if(e.preserveImageSizeOnResize)r=c[e.hash].prevContainerSize.x/t.x;else{var s=new m.Point(0,0);o=new m.Point(c[e.hash].prevContainerSize.x,c[e.hash].prevContainerSize.y).distanceTo(s);s=new m.Point(t.x,t.y).distanceTo(s);r=s/o*c[e.hash].prevContainerSize.x/t.x}i.zoomTo(n*r,null,!0);c[e.hash].prevContainerSize=t;c[e.hash].forceRedraw=!0;c[e.hash].needsResize=!1;c[e.hash].forceResize=!1}(e,i||r(e.container))}t=e.viewport.update();var i=e.world.update()||t;t&&e.raiseEvent("viewport-change");e.referenceStrip&&(i=e.referenceStrip.update(e.viewport)||i);t=c[e.hash].animating;if(!t&&i){e.raiseEvent("animation-start");n(e)}t=t&&!i;t&&(c[e.hash].animating=!1);if(i||t||c[e.hash].forceRedraw||e.world.needsDraw()){!function(e){e.imageLoader.clear();e.drawer.clear();e.world.draw();e.raiseEvent("update-viewport",{})}(e);e._drawOverlays();e.navigator&&e.navigator.update(e.viewport);c[e.hash].forceRedraw=!1;i&&e.raiseEvent("animation")}if(t){e.raiseEvent("animation-finish");c[e.hash].mouseInside||u(e)}c[e.hash].animating=i}}(e);e.isOpen()?e._updateRequestId=a(e,k):e._updateRequestId=!1}function B(e,t){return e?e+t:t}function z(){c[this.hash].lastZoomTime=m.now();c[this.hash].zoomFactor=this.zoomPerSecond;c[this.hash].zooming=!0;i(this)}function H(){c[this.hash].lastZoomTime=m.now();c[this.hash].zoomFactor=1/this.zoomPerSecond;c[this.hash].zooming=!0;i(this)}function L(){c[this.hash].zooming=!1}function i(e){m.requestAnimationFrame(m.delegate(e,t))}function t(){var e,t;if(c[this.hash].zooming&&this.viewport){t=(e=m.now())-c[this.hash].lastZoomTime;t=Math.pow(c[this.hash].zoomFactor,t/1e3);this.viewport.zoomBy(t);this.viewport.applyConstraints();c[this.hash].lastZoomTime=e;i(this)}}function F(){if(this.viewport){c[this.hash].zooming=!1;this.viewport.zoomBy(+this.zoomPerClick);this.viewport.applyConstraints()}}function M(){if(this.viewport){c[this.hash].zooming=!1;this.viewport.zoomBy(1/this.zoomPerClick);this.viewport.applyConstraints()}}function N(){if(this.buttonGroup){this.buttonGroup.emulateEnter();this.buttonGroup.emulateLeave()}}function A(){this.viewport&&this.viewport.goHome()}function U(){this.isFullPage()&&!m.isFullScreen()?this.setFullPage(!1):this.setFullScreen(!this.isFullPage());this.buttonGroup&&this.buttonGroup.emulateLeave();this.fullPageButton.element.focus();this.viewport&&this.viewport.applyConstraints()}function W(){if(this.viewport){var e=this.viewport.getRotation();this.viewport.flipped?e+=this.rotationIncrement:e-=this.rotationIncrement;this.viewport.setRotation(e)}}function V(){if(this.viewport){var e=this.viewport.getRotation();this.viewport.flipped?e-=this.rotationIncrement:e+=this.rotationIncrement;this.viewport.setRotation(e)}}function G(){this.viewport.toggleFlip()}}(OpenSeadragon);!function(r){r.Navigator=function(i){var e,t=i.viewer,n=this;if(i.element||i.id){if(i.element){i.id&&r.console.warn("Given option.id for Navigator was ignored since option.element was provided and is being used instead.");i.element.id?i.id=i.element.id:i.id="navigator-"+r.now();this.element=i.element}else this.element=document.getElementById(i.id);i.controlOptions={anchor:r.ControlAnchor.NONE,attachToViewer:!1,autoFade:!1}}else{i.id="navigator-"+r.now();this.element=r.makeNeutralElement("div");i.controlOptions={anchor:r.ControlAnchor.TOP_RIGHT,attachToViewer:!0,autoFade:i.autoFade};if(i.position)if("BOTTOM_RIGHT"===i.position)i.controlOptions.anchor=r.ControlAnchor.BOTTOM_RIGHT;else if("BOTTOM_LEFT"===i.position)i.controlOptions.anchor=r.ControlAnchor.BOTTOM_LEFT;else if("TOP_RIGHT"===i.position)i.controlOptions.anchor=r.ControlAnchor.TOP_RIGHT;else if("TOP_LEFT"===i.position)i.controlOptions.anchor=r.ControlAnchor.TOP_LEFT;else if("ABSOLUTE"===i.position){i.controlOptions.anchor=r.ControlAnchor.ABSOLUTE;i.controlOptions.top=i.top;i.controlOptions.left=i.left;i.controlOptions.height=i.height;i.controlOptions.width=i.width}}this.element.id=i.id;this.element.className+=" navigator";(i=r.extend(!0,{sizeRatio:r.DEFAULT_SETTINGS.navigatorSizeRatio},i,{element:this.element,tabIndex:-1,showNavigator:!1,mouseNavEnabled:!1,showNavigationControl:!1,showSequenceControl:!1,immediateRender:!0,blendTime:0,animationTime:i.animationTime,autoResize:!1,minZoomImageRatio:1,background:i.background,opacity:i.opacity,borderColor:i.borderColor,displayRegionColor:i.displayRegionColor})).minPixelRatio=this.minPixelRatio=t.minPixelRatio;r.setElementTouchActionNone(this.element);this.borderWidth=2;this.fudge=new r.Point(1,1);this.totalBorderWidths=new r.Point(2*this.borderWidth,2*this.borderWidth).minus(this.fudge);i.controlOptions.anchor!==r.ControlAnchor.NONE&&function(e,t){e.margin="0px";e.border=t+"px solid "+i.borderColor;e.padding="0px";e.background=i.background;e.opacity=i.opacity;e.overflow="hidden"}(this.element.style,this.borderWidth);this.displayRegion=r.makeNeutralElement("div");this.displayRegion.id=this.element.id+"-displayregion";this.displayRegion.className="displayregion";!function(e,t){e.position="relative";e.top="0px";e.left="0px";e.fontSize="0px";e.overflow="hidden";e.border=t+"px solid "+i.displayRegionColor;e.margin="0px";e.padding="0px";e.background="transparent";e.float="left";e.cssFloat="left";e.styleFloat="left";e.zIndex=999999999;e.cursor="default"}(this.displayRegion.style,this.borderWidth);r.setElementPointerEventsNone(this.displayRegion);r.setElementTouchActionNone(this.displayRegion);this.displayRegionContainer=r.makeNeutralElement("div");this.displayRegionContainer.id=this.element.id+"-displayregioncontainer";this.displayRegionContainer.className="displayregioncontainer";this.displayRegionContainer.style.width="100%";this.displayRegionContainer.style.height="100%";r.setElementPointerEventsNone(this.displayRegionContainer);r.setElementTouchActionNone(this.displayRegionContainer);t.addControl(this.element,i.controlOptions);this._resizeWithViewer=i.controlOptions.anchor!==r.ControlAnchor.ABSOLUTE&&i.controlOptions.anchor!==r.ControlAnchor.NONE;if(i.width&&i.height){this.setWidth(i.width);this.setHeight(i.height)}else if(this._resizeWithViewer){e=r.getElementSize(t.element);this.element.style.height=Math.round(e.y*i.sizeRatio)+"px";this.element.style.width=Math.round(e.x*i.sizeRatio)+"px";this.oldViewerSize=e;e=r.getElementSize(this.element);this.elementArea=e.x*e.y}this.oldContainerSize=new r.Point(0,0);r.Viewer.apply(this,[i]);this.displayRegionContainer.appendChild(this.displayRegion);this.element.getElementsByTagName("div")[0].appendChild(this.displayRegionContainer);function o(e){c(n.displayRegionContainer,e);c(n.displayRegion,-e);n.viewport.setRotation(e)}if(i.navigatorRotate){o(i.viewer.viewport?i.viewer.viewport.getRotation():i.viewer.degrees||0);i.viewer.addHandler("rotate",function(e){o(e.degrees)})}this.innerTracker.destroy();this.innerTracker=new r.MouseTracker({userData:"Navigator.innerTracker",element:this.element,dragHandler:r.delegate(this,a),clickHandler:r.delegate(this,s),releaseHandler:r.delegate(this,l),scrollHandler:r.delegate(this,h),preProcessEventHandler:function(e){"wheel"===e.eventType&&(e.preventDefault=!0)}});this.outerTracker.userData="Navigator.outerTracker";r.setElementPointerEventsNone(this.canvas);r.setElementPointerEventsNone(this.container);this.addHandler("reset-size",function(){n.viewport&&n.viewport.goHome(!0)});t.world.addHandler("item-index-change",function(t){window.setTimeout(function(){var e=n.world.getItemAt(t.previousIndex);n.world.setItemIndex(e,t.newIndex)},1)});t.world.addHandler("remove-item",function(e){e=e.item;e=n._getMatchingItem(e);e&&n.world.removeItem(e)});this.update(t.viewport)};r.extend(r.Navigator.prototype,r.EventSource.prototype,r.Viewer.prototype,{updateSize:function(){if(this.viewport){var e=new r.Point(0===this.container.clientWidth?1:this.container.clientWidth,0===this.container.clientHeight?1:this.container.clientHeight);if(!e.equals(this.oldContainerSize)){this.viewport.resize(e,!0);this.viewport.goHome(!0);this.oldContainerSize=e;this.drawer.clear();this.world.draw()}}},setWidth:function(e){this.width=e;this.element.style.width="number"==typeof e?e+"px":e;this._resizeWithViewer=!1},setHeight:function(e){this.height=e;this.element.style.height="number"==typeof e?e+"px":e;this._resizeWithViewer=!1},setFlip:function(e){this.viewport.setFlip(e);this.setDisplayTransform(this.viewer.viewport.getFlip()?"scale(-1,1)":"scale(1,1)");return this},setDisplayTransform:function(e){i(this.displayRegion,e);i(this.canvas,e);i(this.element,e)},update:function(e){var t;i=r.getElementSize(this.viewer.element);if(this._resizeWithViewer&&i.x&&i.y&&!i.equals(this.oldViewerSize)){this.oldViewerSize=i;if(this.maintainSizeRatio||!this.elementArea){t=i.x*this.sizeRatio;n=i.y*this.sizeRatio}else{t=Math.sqrt(this.elementArea*(i.x/i.y));n=this.elementArea/t}this.element.style.width=Math.round(t)+"px";this.element.style.height=Math.round(n)+"px";this.elementArea||(this.elementArea=t*n);this.updateSize()}if(e&&this.viewport){i=e.getBoundsNoRotate(!0);t=this.viewport.pixelFromPointNoRotate(i.getTopLeft(),!1);n=this.viewport.pixelFromPointNoRotate(i.getBottomRight(),!1).minus(this.totalBorderWidths);e=this.displayRegion.style;e.display=this.world.getItemCount()?"block":"none";e.top=Math.round(t.y)+"px";e.left=Math.round(t.x)+"px";var i=Math.abs(t.x-n.x);var n=Math.abs(t.y-n.y);e.width=Math.round(Math.max(i,0))+"px";e.height=Math.round(Math.max(n,0))+"px"}},addTiledImage:function(e){var n=this;var o=e.originalTiledImage;delete e.original;e=r.extend({},e,{success:function(e){var t=e.item;t._originalForNavigator=o;n._matchBounds(t,o,!0);n._matchOpacity(t,o);n._matchCompositeOperation(t,o);function i(){n._matchBounds(t,o)}o.addHandler("bounds-change",i);o.addHandler("clip-change",i);o.addHandler("opacity-change",function(){n._matchOpacity(t,o)});o.addHandler("composite-operation-change",function(){n._matchCompositeOperation(t,o)})}});return r.Viewer.prototype.addTiledImage.apply(this,[e])},destroy:function(){return r.Viewer.prototype.destroy.apply(this)},_getMatchingItem:function(e){var t=this.world.getItemCount();var i;for(var n=0;n=1/this.aspectRatio-1e-15&&(n=this.getNumTiles(e).y-1);return new h.Point(i,n)},getTileBounds:function(e,t,i,n){var o=this.dimensions.times(this.getLevelScale(e)),r=this.getTileWidth(e),s=this.getTileHeight(e),a=0===t?0:r*t-this.tileOverlap,e=0===i?0:s*i-this.tileOverlap,t=r+(0===t?1:2)*this.tileOverlap,s=s+(0===i?1:2)*this.tileOverlap,i=1/o.x;t=Math.min(t,o.x-a);s=Math.min(s,o.y-e);return n?new h.Rect(0,0,t,s):new h.Rect(a*i,e*i,t*i,s*i)},getImageInfo:function(n){var t,i,e,o,r,s=this;n&&-1<(r=(o=(e=n.split("/"))[e.length-1]).lastIndexOf("."))&&(e[e.length-1]=o.slice(0,r));var a=null;if(this.splitHashDataForPost){var l=n.indexOf("#");if(-1!==l){a=n.substring(l+1);n=n.substr(0,l)}}t=function(e){"string"==typeof e&&(e=h.parseXml(e));var t=h.TileSource.determineType(s,e,n);if(t){void 0===(i=t.prototype.configure.apply(s,[e,n,a])).ajaxWithCredentials&&(i.ajaxWithCredentials=s.ajaxWithCredentials);i=new t(i);s.ready=!0;s.raiseEvent("ready",{tileSource:i})}else s.raiseEvent("open-failed",{message:"Unable to load TileSource",source:n})};if(n.match(/\.js$/)){l=n.split("/").pop().replace(".js","");h.jsonp({url:n,async:!1,callbackName:l,callback:t})}else h.makeAjaxRequest({url:n,postData:a,withCredentials:this.ajaxWithCredentials,headers:this.ajaxHeaders,success:function(e){e=function(t){var e,i,n=t.responseText,o=t.status;{if(!t)throw new Error(h.getString("Errors.Security"));if(200!==t.status&&0!==t.status){o=t.status;e=404===o?"Not Found":t.statusText;throw new Error(h.getString("Errors.Status",o,e))}}if(n.match(/\s*<.*/))try{i=t.responseXML&&t.responseXML.documentElement?t.responseXML:h.parseXml(n)}catch(e){i=t.responseText}else if(n.match(/\s*[{[].*/))try{i=h.parseJSON(n)}catch(e){i=n}else i=n;return i}(e);t(e)},error:function(e,t){var i;try{i="HTTP "+e.status+" attempting to load TileSource: "+n}catch(e){i=(void 0!==t&&t.toString?t.toString():"Unknown error")+" attempting to load TileSource: "+n}h.console.error(i);s.raiseEvent("open-failed",{message:i,source:n,postData:a})}})},supports:function(e,t){return!1},configure:function(e,t,i){throw new Error("Method not implemented.")},getTileUrl:function(e,t,i){throw new Error("Method not implemented.")},getTilePostData:function(e,t,i){return null},getTileAjaxHeaders:function(e,t,i){return{}},getTileHashKey:function(e,t,i,n,o,r){function s(e){return o?e+"+"+JSON.stringify(o):e}return s("string"!=typeof n?e+"/"+t+"_"+i:n)},tileExists:function(e,t,i){var n=this.getNumTiles(e);return e>=this.minLevel&&e<=this.maxLevel&&0<=t&&0<=i&&tthis.maxLevel)return!1;if(!h||!h.length)return!0;for(l=h.length-1;0<=l;l--)if(!(e<(n=h[l]).minLevel||e>n.maxLevel)){a=this.getLevelScale(e);o=n.x*a;r=n.y*a;s=o+n.width*a;a=r+n.height*a;o=Math.floor(o/this._tileWidth);r=Math.floor(r/this._tileWidth);s=Math.ceil(s/this._tileWidth);a=Math.ceil(a/this._tileWidth);if(o<=t&&t=this.minLevel&&e<=this.maxLevel?this.levels[e].width/this.levels[this.maxLevel].width:t}return h.TileSource.prototype.getLevelScale.call(this,e)},getNumTiles:function(e){if(this.emulateLegacyImagePyramid)return this.getLevelScale(e)?new h.Point(1,1):new h.Point(0,0);return h.TileSource.prototype.getNumTiles.call(this,e)},getTileAtPoint:function(e,t){return this.emulateLegacyImagePyramid?new h.Point(0,0):h.TileSource.prototype.getTileAtPoint.call(this,e,t)},getTileUrl:function(e,t,i){if(this.emulateLegacyImagePyramid){var n=null;return n=0=this.minLevel&&e<=this.maxLevel?this.levels[e].url:n}var o,r,s,a,l,h=Math.pow(.5,this.maxLevel-e),c=Math.round(this.width*h),u=Math.round(this.height*h);o=this.getTileWidth(e);r=this.getTileHeight(e);l=Math.round(o/h);n=Math.round(r/h);e=1===this.version?"native."+this.tileFormat:"default."+this.tileFormat;if(ce.tileSize||parseInt(t.y,10)>e.tileSize;){t.x=Math.floor(t.x/2);t.y=Math.floor(t.y/2);e.imageSizes.push({x:t.x,y:t.y});e.gridSize.push(this._getGridSize(t.x,t.y,e.tileSize))}e.imageSizes.reverse();e.gridSize.reverse();e.minLevel=0;e.maxLevel=e.gridSize.length-1;OpenSeadragon.TileSource.apply(this,[e])};e.extend(e.ZoomifyTileSource.prototype,e.TileSource.prototype,{_getGridSize:function(e,t,i){return{x:Math.ceil(e/i),y:Math.ceil(t/i)}},_calculateAbsoluteTileNumber:function(e,t,i){var n=0;var o={};for(var r=0;r");return n.sort(function(e,t){return e.height-t.height})}(t.levels);if(0=this.minLevel&&e<=this.maxLevel?this.levels[e].width/this.levels[this.maxLevel].width:t},getNumTiles:function(e){return this.getLevelScale(e)?new a.Point(1,1):new a.Point(0,0)},getTileUrl:function(e,t,i){var n=null;return n=0=this.minLevel&&e<=this.maxLevel?this.levels[e].url:n}})}(OpenSeadragon);!function(a){a.ImageTileSource=function(e){e=a.extend({buildPyramid:!0,crossOriginPolicy:!1,ajaxWithCredentials:!1,useCanvas:!0},e);a.TileSource.apply(this,[e])};a.extend(a.ImageTileSource.prototype,a.TileSource.prototype,{supports:function(e,t){return e.type&&"image"===e.type},configure:function(e,t,i){return e},getImageInfo:function(e){var t=this._image=new Image;var i=this;this.crossOriginPolicy&&(t.crossOrigin=this.crossOriginPolicy);this.ajaxWithCredentials&&(t.useCredentials=this.ajaxWithCredentials);a.addEvent(t,"load",function(){i.width=t.naturalWidth;i.height=t.naturalHeight;i.aspectRatio=i.width/i.height;i.dimensions=new a.Point(i.width,i.height);i._tileWidth=i.width;i._tileHeight=i.height;i.tileOverlap=0;i.minLevel=0;i.levels=i._buildLevels();i.maxLevel=i.levels.length-1;i.ready=!0;i.raiseEvent("ready",{tileSource:i})});a.addEvent(t,"error",function(){i.raiseEvent("open-failed",{message:"Error loading image at "+e,source:e})});t.src=e},getLevelScale:function(e){var t=NaN;return t=e>=this.minLevel&&e<=this.maxLevel?this.levels[e].width/this.levels[this.maxLevel].width:t},getNumTiles:function(e){return this.getLevelScale(e)?new a.Point(1,1):new a.Point(0,0)},getTileUrl:function(e,t,i){var n=null;return n=e>=this.minLevel&&e<=this.maxLevel?this.levels[e].url:n},getContext2D:function(e,t,i){var n=null;return n=e>=this.minLevel&&e<=this.maxLevel?this.levels[e].context2D:n},destroy:function(){this._freeupCanvasMemory()},_buildLevels:function(){var e=[{url:this._image.src,width:this._image.naturalWidth,height:this._image.naturalHeight}];if(!this.buildPyramid||!a.supportsCanvas||!this.useCanvas){delete this._image;return e}var t=this._image.naturalWidth;var i=this._image.naturalHeight;var n=document.createElement("canvas");var o=n.getContext("2d");n.width=t;n.height=i;o.drawImage(this._image,0,0,t,i);e[0].context2D=o;delete this._image;if(a.isCanvasTainted(n))return e;for(;2<=t&&2<=i;){t=Math.floor(t/2);i=Math.floor(i/2);var r=document.createElement("canvas");var s=r.getContext("2d");r.width=t;r.height=i;s.drawImage(n,0,0,t,i);e.splice(0,0,{context2D:s,width:t,height:i});n=r;o=s}return e},_freeupCanvasMemory:function(){for(var e=0;e=i.ButtonState.GROUP&&e.currentState===i.ButtonState.REST){!function(e){e.shouldFade=!1;e.imgGroup&&i.setElementOpacity(e.imgGroup,1,!0)}(e);e.currentState=i.ButtonState.GROUP}if(t>=i.ButtonState.HOVER&&e.currentState===i.ButtonState.GROUP){e.imgHover&&(e.imgHover.style.visibility="");e.currentState=i.ButtonState.HOVER}if(t>=i.ButtonState.DOWN&&e.currentState===i.ButtonState.HOVER){e.imgDown&&(e.imgDown.style.visibility="");e.currentState=i.ButtonState.DOWN}}}function r(e,t){if(!e.element.disabled){if(t<=i.ButtonState.HOVER&&e.currentState===i.ButtonState.DOWN){e.imgDown&&(e.imgDown.style.visibility="hidden");e.currentState=i.ButtonState.HOVER}if(t<=i.ButtonState.GROUP&&e.currentState===i.ButtonState.HOVER){e.imgHover&&(e.imgHover.style.visibility="hidden");e.currentState=i.ButtonState.GROUP}if(t<=i.ButtonState.REST&&e.currentState===i.ButtonState.GROUP){!function(e){e.shouldFade=!0;e.fadeBeginTime=i.now()+e.fadeDelay;window.setTimeout(function(){n(e)},e.fadeDelay)}(e);e.currentState=i.ButtonState.REST}}}}(OpenSeadragon);!function(o){o.ButtonGroup=function(e){o.extend(!0,this,{buttons:[],clickTimeThreshold:o.DEFAULT_SETTINGS.clickTimeThreshold,clickDistThreshold:o.DEFAULT_SETTINGS.clickDistThreshold,labelText:""},e);var t,i=this.buttons.concat([]),n=this;this.element=e.element||o.makeNeutralElement("div");if(!e.group){this.element.style.display="inline-block";for(t=0;tu&&(u=m.x);m.yp&&(p=m.y)}return new v.Rect(c,d,u-c,p-d)},_getSegments:function(){var e=this.getTopLeft();var t=this.getTopRight();var i=this.getBottomLeft();var n=this.getBottomRight();return[[e,t],[t,n],[n,i],[i,e]]},rotate:function(e,t){if(0===(e=v.positiveModulo(e,360)))return this.clone();t=t||this.getCenter();var i=this.getTopLeft().rotate(e,t);e=this.getTopRight().rotate(e,t).minus(i);e=e.apply(function(e){return Math.abs(e)<1e-15?0:e});t=Math.atan(e.y/e.x);e.x<0?t+=Math.PI:e.y<0&&(t+=2*Math.PI);return new v.Rect(i.x,i.y,this.width,this.height,t/Math.PI*180)},getBoundingBox:function(){if(0===this.degrees)return this.clone();var e=this.getTopLeft();var t=this.getTopRight();var i=this.getBottomLeft();var n=this.getBottomRight();var o=Math.min(e.x,t.x,i.x,n.x);var r=Math.max(e.x,t.x,i.x,n.x);var s=Math.min(e.y,t.y,i.y,n.y);n=Math.max(e.y,t.y,i.y,n.y);return new v.Rect(o,s,r-o,n-s)},getIntegerBoundingBox:function(){var e=this.getBoundingBox();var t=Math.floor(e.x);var i=Math.floor(e.y);var n=Math.ceil(e.width+e.x-t);e=Math.ceil(e.height+e.y-i);return new v.Rect(t,i,n,e)},containsPoint:function(e,t){t=t||0;var i=this.getTopLeft();var n=this.getTopRight();var o=this.getBottomLeft();var r=n.minus(i);var s=o.minus(i);return(e.x-i.x)*r.x+(e.y-i.y)*r.y>=-t&&(e.x-n.x)*r.x+(e.y-n.y)*r.y<=t&&(e.x-i.x)*s.x+(e.y-i.y)*s.y>=-t&&(e.x-o.x)*s.x+(e.y-o.y)*s.y<=t},toString:function(){return"["+Math.round(100*this.x)/100+", "+Math.round(100*this.y)/100+", "+Math.round(100*this.width)/100+"x"+Math.round(100*this.height)/100+", "+Math.round(100*this.degrees)/100+"deg]"}}}(OpenSeadragon);!function(h){var s={};h.ReferenceStrip=function(e){var t,i,n,o=e.viewer,r=h.getElementSize(o.element);if(!e.id){e.id="referencestrip-"+h.now();this.element=h.makeNeutralElement("div");this.element.id=e.id;this.element.className="referencestrip"}e=h.extend(!0,{sizeRatio:h.DEFAULT_SETTINGS.referenceStripSizeRatio,position:h.DEFAULT_SETTINGS.referenceStripPosition,scroll:h.DEFAULT_SETTINGS.referenceStripScroll,clickTimeThreshold:h.DEFAULT_SETTINGS.clickTimeThreshold},e,{element:this.element});h.extend(this,e);s[this.id]={animating:!1};this.minPixelRatio=this.viewer.minPixelRatio;this.element.tabIndex=0;(i=this.element.style).marginTop="0px";i.marginRight="0px";i.marginBottom="0px";i.marginLeft="0px";i.left="0px";i.bottom="0px";i.border="0px";i.background="#000";i.position="relative";h.setElementTouchActionNone(this.element);h.setElementOpacity(this.element,.8);this.viewer=o;this.tracker=new h.MouseTracker({userData:"ReferenceStrip.tracker",element:this.element,clickHandler:h.delegate(this,a),dragHandler:h.delegate(this,l),scrollHandler:h.delegate(this,c),enterHandler:h.delegate(this,d),leaveHandler:h.delegate(this,p),keyDownHandler:h.delegate(this,g),keyHandler:h.delegate(this,m),preProcessEventHandler:function(e){"wheel"===e.eventType&&(e.preventDefault=!0)}});if(e.width&&e.height){this.element.style.width=e.width+"px";this.element.style.height=e.height+"px";o.addControl(this.element,{anchor:h.ControlAnchor.BOTTOM_LEFT})}else if("horizontal"===e.scroll){this.element.style.width=r.x*e.sizeRatio*o.tileSources.length+12*o.tileSources.length+"px";this.element.style.height=r.y*e.sizeRatio+"px";o.addControl(this.element,{anchor:h.ControlAnchor.BOTTOM_LEFT})}else{this.element.style.height=r.y*e.sizeRatio*o.tileSources.length+12*o.tileSources.length+"px";this.element.style.width=r.x*e.sizeRatio+"px";o.addControl(this.element,{anchor:h.ControlAnchor.TOP_LEFT})}this.panelWidth=r.x*this.sizeRatio+8;this.panelHeight=r.y*this.sizeRatio+8;this.panels=[];this.miniViewers={};for(n=0;ns+n.x-this.panelWidth){t=Math.min(t,o-n.x);this.element.style.marginLeft=-t+"px";u(this,n.x,-t)}else if(ta+n.y-this.panelHeight){t=Math.min(t,r-n.y);this.element.style.marginTop=-t+"px";u(this,n.y,-t)}else if(t-(n-r.x)){this.element.style.marginLeft=t+2*e.delta.x+"px";u(this,r.x,t+2*e.delta.x)}}else if(-e.delta.x<0&&t<0){this.element.style.marginLeft=t+2*e.delta.x+"px";u(this,r.x,t+2*e.delta.x)}}else if(0<-e.delta.y){if(i>-(o-r.y)){this.element.style.marginTop=i+2*e.delta.y+"px";u(this,r.y,i+2*e.delta.y)}}else if(-e.delta.y<0&&i<0){this.element.style.marginTop=i+2*e.delta.y+"px";u(this,r.y,i+2*e.delta.y)}}}function c(e){if(this.element){var t=Number(this.element.style.marginLeft.replace("px","")),i=Number(this.element.style.marginTop.replace("px","")),n=Number(this.element.style.width.replace("px","")),o=Number(this.element.style.height.replace("px","")),r=h.getElementSize(this.viewer.canvas);if("horizontal"===this.scroll){if(0-(n-r.x)){this.element.style.marginLeft=t-60*e.scroll+"px";u(this,r.x,t-60*e.scroll)}}else if(e.scroll<0&&t<0){this.element.style.marginLeft=t-60*e.scroll+"px";u(this,r.x,t-60*e.scroll)}}else if(e.scroll<0){if(i>r.y-o){this.element.style.marginTop=i+60*e.scroll+"px";u(this,r.y,i+60*e.scroll)}}else if(0=this.target.time?t:e+(t-e)*(n=this.springStiffness,i=(this.current.time-this.start.time)/(this.target.time-this.start.time),(1-Math.exp(n*-i))/(1-Math.exp(-n)));var i;var n=this.current.value;this._exponential?this.current.value=Math.exp(i):this.current.value=i;return n!==this.current.value},isAtTargetValue:function(){return this.current.value===this.target.value}}}(OpenSeadragon);!function(n){n.ImageJob=function(e){n.extend(!0,this,{timeout:n.DEFAULT_SETTINGS.timeout,jobId:null},e);this.data=null;this.userData={};this.errorMsg=null};n.ImageJob.prototype={start:function(){var e=this;var t=this.abort;this.jobId=window.setTimeout(function(){e.finish(null,null,"Image load exceeded timeout ("+e.timeout+" ms)")},this.timeout);this.abort=function(){e.source.downloadTileAbort(e);"function"==typeof t&&t()};this.source.downloadTileStart(this)},finish:function(e,t,i){this.data=e;this.request=t;this.errorMsg=i;this.jobId&&window.clearTimeout(this.jobId);this.callback(this)}};n.ImageLoader=function(e){n.extend(!0,this,{jobLimit:n.DEFAULT_SETTINGS.imageLoaderLimit,timeout:n.DEFAULT_SETTINGS.timeout,jobQueue:[],jobsInProgress:0},e)};n.ImageLoader.prototype={addJob:function(t){if(!t.source){n.console.error("ImageLoader.prototype.addJob() requires [options.source]. TileSource since new API defines how images are fetched. Creating a dummy TileSource.");var e=n.TileSource.prototype;t.source={downloadTileStart:e.downloadTileStart,downloadTileAbort:e.downloadTileAbort}}var i=this,e={src:t.src,tile:t.tile||{},source:t.source,loadWithAjax:t.loadWithAjax,ajaxHeaders:t.loadWithAjax?t.ajaxHeaders:null,crossOriginPolicy:t.crossOriginPolicy,ajaxWithCredentials:t.ajaxWithCredentials,postData:t.postData,callback:function(e){!function(e,t,i){e.jobsInProgress--;if((!e.jobLimit||e.jobsInProgressthis.canvas.width&&(r.width=this.canvas.width-r.x);if(r.y<0){r.height+=r.y;r.y=0}r.y+r.height>this.canvas.height&&(r.height=this.canvas.height-r.y);this.context.drawImage(this.sketchCanvas,r.x,r.y,r.width,r.height,r.x,r.y,r.width,r.height)}else{t=o.scale||1;e=(i=o.translate)instanceof a.Point?i:new a.Point(0,0);n=0;r=0;if(i){o=this.sketchCanvas.width-this.canvas.width;i=this.sketchCanvas.height-this.canvas.height;n=Math.round(o/2);r=Math.round(i/2)}this.context.drawImage(this.sketchCanvas,e.x-n*t,e.y-r*t,(this.canvas.width+2*n)*t,(this.canvas.height+2*r)*t,-n,-r,this.canvas.width+2*n,this.canvas.height+2*r)}this.context.restore()}},drawDebugInfo:function(e,t,i,n){if(this.useCanvas){var o=this.viewer.world.getIndexOfItem(n)%this.debugGridColor.length;var r=this.context;r.save();r.lineWidth=2*a.pixelDensityRatio;r.font="small-caps bold "+13*a.pixelDensityRatio+"px arial";r.strokeStyle=this.debugGridColor[o];r.fillStyle=this.debugGridColor[o];this.viewport.getRotation(!0)%360!=0&&this._offsetForRotation({degrees:this.viewport.getRotation(!0)});n.getRotation(!0)%360!=0&&this._offsetForRotation({degrees:n.getRotation(!0),point:n.viewport.pixelFromPointNoRotate(n._getRotationPoint(!0),!0)});n.viewport.getRotation(!0)%360==0&&n.getRotation(!0)%360==0&&n._drawer.viewer.viewport.getFlip()&&n._drawer._flip();r.strokeRect(e.position.x*a.pixelDensityRatio,e.position.y*a.pixelDensityRatio,e.size.x*a.pixelDensityRatio,e.size.y*a.pixelDensityRatio);var s=(e.position.x+e.size.x/2)*a.pixelDensityRatio;o=(e.position.y+e.size.y/2)*a.pixelDensityRatio;r.translate(s,o);r.rotate(Math.PI/180*-this.viewport.getRotation(!0));r.translate(-s,-o);if(0===e.x&&0===e.y){r.fillText("Zoom: "+this.viewport.getZoom(),e.position.x*a.pixelDensityRatio,(e.position.y-30)*a.pixelDensityRatio);r.fillText("Pan: "+this.viewport.getBounds().toString(),e.position.x*a.pixelDensityRatio,(e.position.y-20)*a.pixelDensityRatio)}r.fillText("Level: "+e.level,(e.position.x+10)*a.pixelDensityRatio,(e.position.y+20)*a.pixelDensityRatio);r.fillText("Column: "+e.x,(e.position.x+10)*a.pixelDensityRatio,(e.position.y+30)*a.pixelDensityRatio);r.fillText("Row: "+e.y,(e.position.x+10)*a.pixelDensityRatio,(e.position.y+40)*a.pixelDensityRatio);r.fillText("Order: "+i+" of "+t,(e.position.x+10)*a.pixelDensityRatio,(e.position.y+50)*a.pixelDensityRatio);r.fillText("Size: "+e.size.toString(),(e.position.x+10)*a.pixelDensityRatio,(e.position.y+60)*a.pixelDensityRatio);r.fillText("Position: "+e.position.toString(),(e.position.x+10)*a.pixelDensityRatio,(e.position.y+70)*a.pixelDensityRatio);this.viewport.getRotation(!0)%360!=0&&this._restoreRotationChanges();n.getRotation(!0)%360!=0&&this._restoreRotationChanges();n.viewport.getRotation(!0)%360==0&&n.getRotation(!0)%360==0&&n._drawer.viewer.viewport.getFlip()&&n._drawer._flip();r.restore()}},debugRect:function(e){if(this.useCanvas){var t=this.context;t.save();t.lineWidth=2*a.pixelDensityRatio;t.strokeStyle=this.debugGridColor[0];t.fillStyle=this.debugGridColor[0];t.strokeRect(e.x*a.pixelDensityRatio,e.y*a.pixelDensityRatio,e.width*a.pixelDensityRatio,e.height*a.pixelDensityRatio);t.restore()}},setImageSmoothingEnabled:function(e){if(this.useCanvas){this._imageSmoothingEnabled=e;this._updateImageSmoothingEnabled(this.context);this.viewer.forceRedraw()}},_updateImageSmoothingEnabled:function(e){e.msImageSmoothingEnabled=this._imageSmoothingEnabled;e.imageSmoothingEnabled=this._imageSmoothingEnabled},getCanvasSize:function(e){e=this._getContext(e).canvas;return new a.Point(e.width,e.height)},getCanvasCenter:function(){return new a.Point(this.canvas.width/2,this.canvas.height/2)},_offsetForRotation:function(e){var t=e.point?e.point.times(a.pixelDensityRatio):this.getCanvasCenter();var i=this._getContext(e.useSketch);i.save();i.translate(t.x,t.y);if(this.viewer.viewport.flipped){i.rotate(Math.PI/180*-e.degrees);i.scale(-1,1)}else i.rotate(Math.PI/180*e.degrees);i.translate(-t.x,-t.y)},_flip:function(e){var t=(e=e||{}).point?e.point.times(a.pixelDensityRatio):this.getCanvasCenter();e=this._getContext(e.useSketch);e.translate(t.x,0);e.scale(-1,1);e.translate(-t.x,0)},_restoreRotationChanges:function(e){this._getContext(e).restore()},_calculateCanvasSize:function(){var e=a.pixelDensityRatio;var t=this.viewport.getContainerSize();return{x:Math.round(t.x*e),y:Math.round(t.y*e)}},_calculateSketchCanvasSize:function(){var e=this._calculateCanvasSize();if(0===this.viewport.getRotation())return e;e=Math.ceil(Math.sqrt(e.x*e.x+e.y*e.y));return{x:e,y:e}}}}(OpenSeadragon);!function(h){h.Viewport=function(e){var t=arguments;if((e=t.length&&t[0]instanceof h.Point?{containerSize:t[0],contentSize:t[1],config:t[2]}:e).config){h.extend(!0,e,e.config);delete e.config}this._margins=h.extend({left:0,top:0,right:0,bottom:0},e.margins||{});delete e.margins;e.initialDegrees=e.degrees;delete e.degrees;h.extend(!0,this,{containerSize:null,contentSize:null,zoomPoint:null,rotationPivot:null,viewer:null,springStiffness:h.DEFAULT_SETTINGS.springStiffness,animationTime:h.DEFAULT_SETTINGS.animationTime,minZoomImageRatio:h.DEFAULT_SETTINGS.minZoomImageRatio,maxZoomPixelRatio:h.DEFAULT_SETTINGS.maxZoomPixelRatio,visibilityRatio:h.DEFAULT_SETTINGS.visibilityRatio,wrapHorizontal:h.DEFAULT_SETTINGS.wrapHorizontal,wrapVertical:h.DEFAULT_SETTINGS.wrapVertical,defaultZoomLevel:h.DEFAULT_SETTINGS.defaultZoomLevel,minZoomLevel:h.DEFAULT_SETTINGS.minZoomLevel,maxZoomLevel:h.DEFAULT_SETTINGS.maxZoomLevel,initialDegrees:h.DEFAULT_SETTINGS.degrees,flipped:h.DEFAULT_SETTINGS.flipped,homeFillsViewer:h.DEFAULT_SETTINGS.homeFillsViewer,silenceMultiImageWarnings:h.DEFAULT_SETTINGS.silenceMultiImageWarnings},e);this._updateContainerInnerSize();this.centerSpringX=new h.Spring({initial:0,springStiffness:this.springStiffness,animationTime:this.animationTime});this.centerSpringY=new h.Spring({initial:0,springStiffness:this.springStiffness,animationTime:this.animationTime});this.zoomSpring=new h.Spring({exponential:!0,initial:1,springStiffness:this.springStiffness,animationTime:this.animationTime});this.degreesSpring=new h.Spring({initial:e.initialDegrees,springStiffness:this.springStiffness,animationTime:this.animationTime});this._oldCenterX=this.centerSpringX.current.value;this._oldCenterY=this.centerSpringY.current.value;this._oldZoom=this.zoomSpring.current.value;this._oldDegrees=this.degreesSpring.current.value;this._setContentBounds(new h.Rect(0,0,1,1),1);this.goHome(!0);this.update()};h.Viewport.prototype={get degrees(){h.console.warn("Accessing [Viewport.degrees] is deprecated. Use viewport.getRotation instead.");return this.getRotation()},set degrees(e){h.console.warn("Setting [Viewport.degrees] is deprecated. Use viewport.rotateTo, viewport.rotateBy, or viewport.setRotation instead.");this.rotateTo(e)},resetContentSize:function(e){h.console.assert(e,"[Viewport.resetContentSize] contentSize is required");h.console.assert(e instanceof h.Point,"[Viewport.resetContentSize] contentSize must be an OpenSeadragon.Point");h.console.assert(0i.width?this.visibilityRatio*i.width:this.visibilityRatio*t.width;r=i.x-r+a;s=s-t.x-a;if(a>i.width){t.x+=(r+s)/2;n=!0}else if(s<0){t.x+=s;n=!0}else if(0i.height?this.visibilityRatio*i.height:this.visibilityRatio*t.height;l=i.y-l+r;s=s-t.y-r;if(r>i.height){t.y+=(l+s)/2;o=!0}else if(s<0){t.y+=s;o=!0}else if(0=o?s.height=s.width/o:s.width=s.height*o;s.x=r.x-s.width/2;s.y=r.y-s.height/2;var a=1/s.width;if(i){this.panTo(r,!0);this.zoomTo(a,null,!0);n&&this.applyConstraints(!0);return this}var l=this.getCenter(!0);t=this.getZoom(!0);this.panTo(l,!0);this.zoomTo(t,null,!0);e=this.getBounds();o=this.getZoom();if(0===o||Math.abs(a/o-1)<1e-8){this.zoomTo(a,null,!0);this.panTo(r,i);n&&this.applyConstraints(!1);return this}if(n){this.panTo(r,!1);this.zoomTo(a,null,!1);r=this.getConstrainedBounds();this.panTo(l,!0);this.zoomTo(t,null,!0);this.fitBounds(r)}else{o=s.rotate(-this.getRotation()).getTopLeft().times(a).minus(e.getTopLeft().times(o)).divide(a-o);this.zoomTo(a,o,i)}return this},fitBounds:function(e,t){return this._fitBounds(e,{immediately:t,constraints:!1})},fitBoundsWithConstraints:function(e,t){return this._fitBounds(e,{immediately:t,constraints:!0})},fitVertically:function(e){var t=new h.Rect(this._contentBounds.x+this._contentBounds.width/2,this._contentBounds.y,0,this._contentBounds.height);return this.fitBounds(t,e)},fitHorizontally:function(e){var t=new h.Rect(this._contentBounds.x,this._contentBounds.y+this._contentBounds.height/2,this._contentBounds.width,0);return this.fitBounds(t,e)},getConstrainedBounds:function(e){e=this.getBounds(e);return this._applyBoundaryConstraints(e)},panBy:function(e,t){var i=new h.Point(this.centerSpringX.target.value,this.centerSpringY.target.value);return this.panTo(i.plus(e),t)},panTo:function(e,t){if(t){this.centerSpringX.resetTo(e.x);this.centerSpringY.resetTo(e.y)}else{this.centerSpringX.springTo(e.x);this.centerSpringY.springTo(e.y)}this.viewer&&this.viewer.raiseEvent("pan",{center:e,immediately:t});return this},zoomBy:function(e,t,i){return this.zoomTo(this.zoomSpring.target.value*e,t,i)},zoomTo:function(e,t,i){var n=this;this.zoomPoint=t instanceof h.Point&&!isNaN(t.x)&&!isNaN(t.y)?t:null;i?this._adjustCenterSpringsForZoomPoint(function(){n.zoomSpring.resetTo(e)}):this.zoomSpring.springTo(e);this.viewer&&this.viewer.raiseEvent("zoom",{zoom:e,refPoint:t,immediately:i});return this},setRotation:function(e,t){return this.rotateTo(e,null,t)},getRotation:function(e){return(e?this.degreesSpring.current:this.degreesSpring.target).value},setRotationWithPivot:function(e,t,i){return this.rotateTo(e,t,i)},rotateTo:function(e,t,i){if(!this.viewer||!this.viewer.drawer.canRotate())return this;if(this.degreesSpring.target.value===e&&this.degreesSpring.isAtTargetValue())return this;this.rotationPivot=t instanceof h.Point&&!isNaN(t.x)&&!isNaN(t.y)?t:null;if(i)if(this.rotationPivot){if(!(e-this._oldDegrees)){this.rotationPivot=null;return this}this._rotateAboutPivot(e)}else this.degreesSpring.resetTo(e);else{var n=h.positiveModulo(this.degreesSpring.current.value,360);var o=h.positiveModulo(e,360);t=o-n;180o){r=this._clip.x/this._clip.height*e.height;s=this._clip.y/this._clip.height*e.height}else{r=this._clip.x/this._clip.width*e.width;s=this._clip.y/this._clip.width*e.width}}if(e.getAspectRatio()>o){var l=e.height/t;t=0;n.isHorizontallyCentered?t=(e.width-e.height*o)/2:n.isRight&&(t=e.width-e.height*o);this.setPosition(new y.Point(e.x-r+t,e.y-s),i);this.setHeight(l,i)}else{l=e.width/a;a=0;n.isVerticallyCentered?a=(e.height-e.width/o)/2:n.isBottom&&(a=e.height-e.width/o);this.setPosition(new y.Point(e.x-r,e.y-s+a),i);this.setWidth(l,i)}},getClip:function(){return this._clip?this._clip.clone():null},setClip:function(e){y.console.assert(!e||e instanceof y.Rect,"[TiledImage.setClip] newClip must be an OpenSeadragon.Rect or null");e instanceof y.Rect?this._clip=e.clone():this._clip=null;this._needsDraw=!0;this.raiseEvent("clip-change")},getFlip:function(){return!!this.flipped},setFlip:function(e){this.flipped=!!e;this._needsDraw=!0;this._raiseBoundsChange()},getOpacity:function(){return this.opacity},setOpacity:function(e){if(e!==this.opacity){this.opacity=e;this._needsDraw=!0;this.raiseEvent("opacity-change",{opacity:this.opacity})}},getPreload:function(){return this._preload},setPreload:function(e){this._preload=!!e;this._needsDraw=!0},getRotation:function(e){return(e?this._degreesSpring.current:this._degreesSpring.target).value},setRotation:function(e,t){if(this._degreesSpring.target.value!==e||!this._degreesSpring.isAtTargetValue()){t?this._degreesSpring.resetTo(e):this._degreesSpring.springTo(e);this._needsDraw=!0;this._raiseBoundsChange()}},_getRotationPoint:function(e){return this.getBoundsNoRotate(e).getCenter()},getCompositeOperation:function(){return this.compositeOperation},setCompositeOperation:function(e){if(e!==this.compositeOperation){this.compositeOperation=e;this._needsDraw=!0;this.raiseEvent("composite-operation-change",{compositeOperation:this.compositeOperation})}},_setScale:function(e,t){var i=this._scaleSpring.target.value===e;if(t){if(i&&this._scaleSpring.current.value===e)return;this._scaleSpring.resetTo(e);this._updateForScale();this._needsDraw=!0}else{if(i)return;this._scaleSpring.springTo(e);this._updateForScale();this._needsDraw=!0}i||this._raiseBoundsChange()},_updateForScale:function(){this._worldWidthTarget=this._scaleSpring.target.value;this._worldHeightTarget=this.normHeight*this._scaleSpring.target.value;this._worldWidthCurrent=this._scaleSpring.current.value;this._worldHeightCurrent=this.normHeight*this._scaleSpring.current.value},_raiseBoundsChange:function(){this.raiseEvent("bounds-change")},_isBottomItem:function(){return this.viewer.world.getItemAt(0)===this},_getLevelsInterval:function(){var e=Math.max(this.source.minLevel,Math.floor(Math.log(this.minZoomImageRatio)/Math.log(2)));var t=this.viewport.deltaPixelsFromPointsNoRotate(this.source.getPixelRatio(0),!0).x*this._scaleSpring.current.value;t=Math.min(Math.abs(this.source.maxLevel),Math.abs(Math.floor(Math.log(t/this.minPixelRatio)/Math.log(2))));t=Math.max(t,this.source.minLevel||0);return{lowestLevel:Math.min(e,t),highestLevel:t}},_updateViewport:function(){this._needsDraw=!1;this._tilesLoading=0;this.loadingCoverage={};for(;0=this.minPixelRatio)r=l=!0;else if(!r)continue;var c=e.deltaPixelsFromPointsNoRotate(this.source.getPixelRatio(a),!1).x*this._scaleSpring.current.value;var u=e.deltaPixelsFromPointsNoRotate(this.source.getPixelRatio(Math.max(this.source.getClosestLevel(),0)),!1).x*this._scaleSpring.current.value;u=this.immediateRender?1:u;h=Math.min(1,(h-.5)/.5);c=u/Math.abs(u-c);o=this._updateLevel(r,l,a,h,c,t,s,o);if(this._providesCoverage(this.coverage,a))break}this._drawTiles(this.lastDrawn);if(o&&!o.context2D){this._loadTile(o,s);this._needsDraw=!0;this._setFullyLoaded(!1)}else this._setFullyLoaded(0===this._tilesLoading)},_getCornerTiles:function(e,t,i){var n;var o;if(this.wrapHorizontal){n=y.positiveModulo(t.x,1);o=y.positiveModulo(i.x,1)}else{n=Math.max(0,t.x);o=Math.min(1,i.x)}var r=1/this.source.aspectRatio;if(this.wrapVertical){s=y.positiveModulo(t.y,r);a=y.positiveModulo(i.y,r)}else{s=Math.max(0,t.y);a=Math.min(r,i.y)}var s=this.source.getTileAtPoint(e,new y.Point(n,s));var a=this.source.getTileAtPoint(e,new y.Point(o,a));e=this.source.getNumTiles(e);if(this.wrapHorizontal){s.x+=e.x*Math.floor(t.x);a.x+=e.x*Math.floor(i.x)}if(this.wrapVertical){s.y+=e.y*Math.floor(t.y/r);a.y+=e.y*Math.floor(i.y/r)}return{topLeft:s,bottomRight:a}},_updateLevel:function(e,t,i,n,o,r,s,a){var l=r.getBoundingBox().getTopLeft();var h=r.getBoundingBox().getBottomRight();this.viewer&&this.viewer.raiseEvent("update-level",{tiledImage:this,havedrawn:e,level:i,opacity:n,visibility:o,drawArea:r,topleft:l,bottomright:h,currenttime:s,best:a});this._resetCoverage(this.coverage,i);this._resetCoverage(this.loadingCoverage,i);h=this._getCornerTiles(i,l,h);var c=h.topLeft;var u=h.bottomRight;var d=this.source.getNumTiles(i);var p=this.viewport.pixelFromPoint(this.viewport.getCenter());if(this.getFlip()){u.x+=1;this.wrapHorizontal||(u.x=Math.min(u.x,d.x-1))}for(var g=c.x;g<=u.x;g++)for(var m=c.y;m<=u.y;m++){if(this.getFlip()){var v=(d.x+g%d.x)%d.x;v=g+d.x-v-v-1}else v=g;null!==r.intersection(this.getTileBounds(i,v,m))&&(a=this._updateTile(t,e,v,m,i,n,o,p,d,s,a))}return a},_updateTile:function(e,t,i,n,o,r,s,a,l,h,c){var u=this._getTile(i,n,o,h,l,this._worldWidthCurrent,this._worldHeightCurrent),l=t;this.viewer&&this.viewer.raiseEvent("update-tile",{tiledImage:this,tile:u});this._setCoverage(this.coverage,o,i,n,!1);t=u.loaded||u.loading||this._isCovered(this.loadingCoverage,o,i,n);this._setCoverage(this.loadingCoverage,o,i,n,t);if(!u.exists)return c;e&&!l&&(this._isCovered(this.coverage,o,i,n)?this._setCoverage(this.coverage,o,i,n,!0):l=!0);if(!l)return c;this._positionTile(u,this.source.tileOverlap,this.viewport,a,s);if(!u.loaded)if(u.context2D)this._setTileLoaded(u);else{s=this._tileCache.getImageRecord(u.cacheKey);s&&this._setTileLoaded(u,s.getData())}u.loaded?this._blendTile(u,i,n,o,r,h)&&(this._needsDraw=!0):u.loading?this._tilesLoading++:t||(c=this._compareTiles(c,u));return c},_getTile:function(e,t,i,n,o,r,s){var a,l,h,c,u,d,p,g,m,v=this.tilesMatrix,f=this.source;v[i]||(v[i]={});v[i][e]||(v[i][e]={});if(!v[i][e][t]||!v[i][e][t].flipped!=!this.flipped){a=(o.x+e%o.x)%o.x;l=(o.y+t%o.y)%o.y;h=this.getTileBounds(i,e,t);c=f.getTileBounds(i,a,l,!0);u=f.tileExists(i,a,l);d=f.getTileUrl(i,a,l);m=f.getTilePostData(i,a,l);if(this.loadTilesWithAjax){p=f.getTileAjaxHeaders(i,a,l);y.isPlainObject(this.ajaxHeaders)&&(p=y.extend({},this.ajaxHeaders,p))}else p=null;g=f.getContext2D?f.getContext2D(i,a,l):void 0;m=new y.Tile(i,e,t,h,u,d,g,this.loadTilesWithAjax,p,c,m,f.getTileHashKey(i,a,l,d,p,m));this.getFlip()?0==a&&(m.isRightMost=!0):a==o.x-1&&(m.isRightMost=!0);l==o.y-1&&(m.isBottomMost=!0);m.flipped=this.flipped;v[i][e][t]=m}(m=v[i][e][t]).lastTouchTime=n;return m},_loadTile:function(n,o){var r=this;n.loading=!0;this._imageLoader.addJob({src:n.getUrl(),tile:n,source:this.source,postData:n.postData,loadWithAjax:n.loadWithAjax,ajaxHeaders:n.ajaxHeaders,crossOriginPolicy:this.crossOriginPolicy,ajaxWithCredentials:this.ajaxWithCredentials,callback:function(e,t,i){r._onTileLoad(n,o,e,t,i)},abort:function(){n.loading=!1}})},_onTileLoad:function(t,e,i,n,o){if(i)if(ee.visibility||t.visibility===e.visibility&&t.squaredDistancethis.smoothTileEdgesMinZoom&&!this.iOSDevice&&this.getRotation(!0)%360==0&&y.supportsCanvas&&this.viewer.useCanvas){i=!0;n=t.getScaleForEdgeSmoothing();o=t.getTranslationForEdgeSmoothing(n,this._drawer.getCanvasSize(!1),this._drawer.getCanvasSize(!0))}var a;if(i){if(!n){a=this.viewport.viewportToViewerElementRectangle(this.getClippedBounds(!0)).getIntegerBoundingBox();this._drawer.viewer.viewport.getFlip()&&(this.viewport.getRotation(!0)%360==0&&this.getRotation(!0)%360==0||(a.x=this._drawer.viewer.container.clientWidth-(a.x+a.width)));a=a.times(y.pixelDensityRatio)}this._drawer._clear(!0,a)}if(!n){this.viewport.getRotation(!0)%360!=0&&this._drawer._offsetForRotation({degrees:this.viewport.getRotation(!0),useSketch:i});this.getRotation(!0)%360!=0&&this._drawer._offsetForRotation({degrees:this.getRotation(!0),point:this.viewport.pixelFromPointNoRotate(this._getRotationPoint(!0),!0),useSketch:i});this.viewport.getRotation(!0)%360==0&&this.getRotation(!0)%360==0&&this._drawer.viewer.viewport.getFlip()&&this._drawer._flip()}r=!1;if(this._clip){this._drawer.saveContext(i);s=this.imageToViewportRectangle(this._clip,!0);s=s.rotate(-this.getRotation(!0),this._getRotationPoint(!0));s=this._drawer.viewportToDrawerRectangle(s);n&&(s=s.times(n));o&&(s=s.translate(o));this._drawer.setClip(s,i);r=!0}if(this._croppingPolygons){var l=this;this._drawer.saveContext(i);try{var h=this._croppingPolygons.map(function(e){return e.map(function(e){e=l.imageToViewportCoordinates(e.x,e.y,!0).rotate(-l.getRotation(!0),l._getRotationPoint(!0));e=l._drawer.viewportCoordToDrawerCoord(e);return e=n?e.times(n):e})});this._drawer.clipWithPolygons(h,i)}catch(e){y.console.error(e)}r=!0}if(this.placeholderFillStyle&&!1===this._hasOpaqueTile){h=this._drawer.viewportToDrawerRectangle(this.getBounds(!0));n&&(h=h.times(n));o&&(h=h.translate(o));var c=null;c="function"==typeof this.placeholderFillStyle?this.placeholderFillStyle(this,this._drawer.context):this.placeholderFillStyle;this._drawer.drawRectangle(h,c,i)}c=function(e){if("number"==typeof e)return m(e);if(!e||!y.Browser)return p;var t=e[y.Browser.vendor];g(t)&&(t=e["*"]);return m(t)}(this.subPixelRoundingForTransparency);var u=!1;c===y.SUBPIXEL_ROUNDING_OCCURRENCES.ALWAYS?u=!0:c===y.SUBPIXEL_ROUNDING_OCCURRENCES.ONLY_AT_REST&&(u=!(this.viewer&&this.viewer.isAnimating()));for(var d=e.length-1;0<=d;d--){t=e[d];this._drawer.drawTile(t,this._drawingHandler,i,n,o,u,this.source);t.beingDrawn=!0;this.viewer&&this.viewer.raiseEvent("tile-drawn",{tiledImage:this,tile:t})}r&&this._drawer.restoreContext(i);if(!n){this.getRotation(!0)%360!=0&&this._drawer._restoreRotationChanges(i);this.viewport.getRotation(!0)%360!=0&&this._drawer._restoreRotationChanges(i)}if(i){if(n){this.viewport.getRotation(!0)%360!=0&&this._drawer._offsetForRotation({degrees:this.viewport.getRotation(!0),useSketch:!1});this.getRotation(!0)%360!=0&&this._drawer._offsetForRotation({degrees:this.getRotation(!0),point:this.viewport.pixelFromPointNoRotate(this._getRotationPoint(!0),!0),useSketch:!1})}this._drawer.blendSketch({opacity:this.opacity,scale:n,translate:o,compositeOperation:this.compositeOperation,bounds:a});if(n){this.getRotation(!0)%360!=0&&this._drawer._restoreRotationChanges(!1);this.viewport.getRotation(!0)%360!=0&&this._drawer._restoreRotationChanges(!1)}}n||this.viewport.getRotation(!0)%360==0&&this.getRotation(!0)%360==0&&this._drawer.viewer.viewport.getFlip()&&this._drawer._flip();this._drawDebugInfo(e)}},_drawDebugInfo:function(e){if(this.debugMode)for(var t=e.length-1;0<=t;t--){var i=e[t];try{this._drawer.drawDebugInfo(i,e.length,t,this)}catch(e){y.console.error(e)}}},_providesCoverage:function(e,t,i,n){var o,r,s,a;if(!e[t])return!1;if(void 0!==i&&void 0!==n)return void 0===e[t][i]||void 0===e[t][i][n]||!0===e[t][i][n];for(s in o=e[t])if(Object.prototype.hasOwnProperty.call(o,s))for(a in r=o[s])if(Object.prototype.hasOwnProperty.call(r,a)&&!r[a])return!1;return!0},_isCovered:function(e,t,i,n){return void 0===i||void 0===n?this._providesCoverage(e,t+1):this._providesCoverage(e,t+1,2*i,2*n)&&this._providesCoverage(e,t+1,2*i,2*n+1)&&this._providesCoverage(e,t+1,2*i+1,2*n)&&this._providesCoverage(e,t+1,2*i+1,2*n+1)},_setCoverage:function(e,t,i,n,o){if(e[t]){e[t][i]||(e[t][i]={});e[t][i][n]=o}else y.console.warn("Setting coverage for a tile before its level's coverage has been reset: %s",t)},_resetCoverage:function(e,t){e[t]={}}});var p=y.SUBPIXEL_ROUNDING_OCCURRENCES.NEVER;function g(e){return e!==y.SUBPIXEL_ROUNDING_OCCURRENCES.ALWAYS&&e!==y.SUBPIXEL_ROUNDING_OCCURRENCES.ONLY_AT_REST&&e!==y.SUBPIXEL_ROUNDING_OCCURRENCES.NEVER}function m(e){return g(e)?p:e}}(OpenSeadragon);!function(g){function m(e){g.console.assert(e,"[TileCache.cacheTile] options is required");g.console.assert(e.tile,"[TileCache.cacheTile] options.tile is required");g.console.assert(e.tiledImage,"[TileCache.cacheTile] options.tiledImage is required");this.tile=e.tile;this.tiledImage=e.tiledImage}function v(e){g.console.assert(e,"[ImageRecord] options is required");g.console.assert(e.data,"[ImageRecord] options.data is required");this._tiles=[];e.create.apply(null,[this,e.data,e.ownerTile]);this._destroyImplementation=e.destroy.bind(null,this);this.getImage=e.getImage.bind(null,this);this.getData=e.getData.bind(null,this);this.getRenderedContext=e.getRenderedContext.bind(null,this)}v.prototype={destroy:function(){this._destroyImplementation();this._tiles=null},addTile:function(e){g.console.assert(e,"[ImageRecord.addTile] tile is required");this._tiles.push(e)},removeTile:function(e){for(var t=0;tthis._maxImageCacheCount){var o=null;var r=-1;var s=null;var a,l,h,c,u,d;for(var p=this._tilesLoaded.length-1;0<=p;p--)if(!((a=(d=this._tilesLoaded[p]).tile).level<=t||a.beingDrawn))if(o){c=a.lastTouchTime;l=o.lastTouchTime;u=a.level;h=o.level;if(c=this._items.length)throw new Error("Index bigger than number of layers.");if(t!==i&&-1!==i){this._items.splice(i,1);this._items.splice(t,0,e);this._needsDraw=!0;this.raiseEvent("item-index-change",{item:e,previousIndex:i,newIndex:t})}},removeItem:function(e){g.console.assert(e,"[World.removeItem] item is required");var t=g.indexOf(this._items,e);if(-1!==t){e.removeHandler("bounds-change",this._delegatedFigureSizes);e.removeHandler("clip-change",this._delegatedFigureSizes);e.destroy();this._items.splice(t,1);this._figureSizes();this._needsDraw=!0;this._raiseRemoveItem(e)}},removeAll:function(){this.viewer._cancelPendingImages();var e;var t;for(t=0;td.height?r:r*(d.width/d.height))*(d.height/d.width);d=new g.Point(l+(r-u)/2,h+(r-d)/2);c.setPosition(d,t);c.setWidth(u,t);"horizontal"===i?l+=s:h+=s}this.setAutoRefigureSizes(!0)},_figureSizes:function(){var e=this._homeBounds?this._homeBounds.clone():null;var t=this._contentSize?this._contentSize.clone():null;var i=this._contentFactor||0;if(this._items.length){var n=this._items[0];var o=n.getBounds();this._contentFactor=n.getContentSize().x/o.width;var r=n.getClippedBounds().getBoundingBox();var s=r.x;var a=r.y;var l=r.x+r.width;var h=r.y+r.height;for(var c=1;c svg:not([class*=icon--]) { display: block; @@ -302,7 +308,7 @@ height: auto; margin: 0 auto; - .m-media--s.o-blocks__block & { + .m-media--s.o-blocks__block:not(.m-media--layered-image-viewer-embed) & { width: auto; max-width: 100%; max-height: 80vh; @@ -321,8 +327,8 @@ } } -.m-media--m:not(.m-media--artwork) .m-media__img:not(.m-media--mirador-embed):not(.m-media--360-embed) img, -.m-media--l:not(.m-media--artwork) .m-media__img:not(.m-media--mirador-embed):not(.m-media--360-embed) img, +.m-media--m:not(.m-media--artwork):not(.m-media--layered-image-viewer-embed) .m-media__img:not(.m-media--mirador-embed):not(.m-media--360-embed) img, +.m-media--l:not(.m-media--artwork):not(.m-media--layered-image-viewer-embed) .m-media__img:not(.m-media--mirador-embed):not(.m-media--360-embed) img, .m-media__img video, .m-media__img embed, .m-media:not(.m-media--soundcloud) .m-media__img iframe, diff --git a/frontend/scss/molecules/_m-paginator.scss b/frontend/scss/molecules/_m-paginator.scss index 6980d7b41..06bdac730 100644 --- a/frontend/scss/molecules/_m-paginator.scss +++ b/frontend/scss/molecules/_m-paginator.scss @@ -120,8 +120,9 @@ m-paginator color: $color__text--disabled; } -.m-paginator__prev-next a span, -.m-paginator__prev-next span span { +.m-paginator__prev-next .f-buttons > a > span, +.m-paginator__prev-next .f-buttons > span +{ display: none; @include breakpoint('medium+') { @@ -135,9 +136,8 @@ m-paginator } } -.m-paginator__prev-next svg:first-child { +.m-paginator__prev-next li:last-child svg { transform: rotate(180deg); - transform-origin: 8px 8px; } diff --git a/frontend/scss/organisms/_o-article__primary-actions.scss b/frontend/scss/organisms/_o-article__primary-actions.scss index 089760f47..0740af724 100644 --- a/frontend/scss/organisms/_o-article__primary-actions.scss +++ b/frontend/scss/organisms/_o-article__primary-actions.scss @@ -180,9 +180,7 @@ // Styles shared by all publication sidebars: .o-article__primary-actions--digital-publication, -.o-article__primary-actions--magazine-issue, -.o-article__primary-actions--journal-article, -.o-article__primary-actions--journal-issue { +.o-article__primary-actions--magazine-issue { padding-top: initial; margin-top: 0; @@ -190,8 +188,7 @@ @include breakpoint('#{$name}') { .m-search-bar, hr, - .hr--no-archive ~ .m-article-actions, // PUB-128 - .m-article-actions--journal__issues { + .hr--no-archive ~ .m-article-actions { // PUB-128 margin-top: #{map-get(( xsmall: 24, small: 24, @@ -295,55 +292,6 @@ } } -// Styles specific to journal issues: -.o-article__primary-actions--journal-issue { - .o-sticky-sidebar__sticker { - padding-top: 30px; - } - - .m-article-actions--publication__logo { - .icon--journal-logo { - height: 92px; - width: 120px; - } - } - - .m-search-bar { - input[type=text] { - height: 42px; - } - - .m-search-bar__submit, - .m-search-bar__clear { - width: 42px; - height: 42px; - } - } -} - - -// Styles specific to journal articles: -.o-article__primary-actions--journal-article { - @extend %o-article__primary-actions--toggleable; - - padding-top: 0; - margin-top: 0; - - .o-sticky-sidebar__sticker { - padding-top: 30px; - } - - .m-article-actions--publication__logo { - a { - color: $color__black--90; - } - - .icon--journal-logo { - height: 92px; - width: 120px; - } - } - @each $name, $point in $breakpoints { @include breakpoint('#{$name}') { .m-article-actions--journal__issues { @@ -357,4 +305,3 @@ } } } -} diff --git a/frontend/scss/organisms/_o-layered-image-viewer.scss b/frontend/scss/organisms/_o-layered-image-viewer.scss new file mode 100644 index 000000000..fb0356020 --- /dev/null +++ b/frontend/scss/organisms/_o-layered-image-viewer.scss @@ -0,0 +1,319 @@ +// ------ Layered image viewer + +// ---- General +.o-layered-image-viewer { + -webkit-user-select: none; + user-select: none; + + * { + box-sizing: border-box; + } + + span.radio { + position: relative; + width: 1.6em; + height: 1.6em; + margin: 0; + } + + .f-body, + .f-secondary { + &::before, + &::after { + display: none; + } + } +} + + + +// -- JS only +.js { + .o-layered-image-viewer__caption, + .o-layered-image-viewer__images, + .o-layered-image-viewer__overlays { + display: none; + } +} + +// ---- Toolbars + +// -- Viewer +.o-layered-image-viewer__viewer-toolbar { + display: flex; + flex-direction: column; + gap: 0.1em; + + .btn { + display: block; + margin: 0; + + &:first-child { + border-radius: 0.2em 0.2em 0 0; + } + + &:last-child { + border-radius: 0 0 0.2em 0.2em; + } + } +} + +// -- Layers +.o-layered-image-viewer__layers-toolbar { + display: flex; + gap: 0.1em; + align-items: flex-end; + + & > *:first-child { + border-top-left-radius: 0.2em; + border-bottom-left-radius: 0.2em; + } + + & > *:last-child { + border-top-right-radius: 0.2em; + border-bottom-right-radius: 0.2em; + } + + & > .btn { + display: block; + margin: 0; + flex: 0 0 auto; + } +} + +// ---- Opacity + +.o-layered-image-viewer__opacity { + display: flex; + align-items: center; + min-height: 4.8em; + padding: 0.4em 1.2em; + background-color: $color__white; + + label { + display: none; + } + + @include breakpoint('small+') { + label { + display: block; + } + } +} + +// -- Range styles +@mixin track() { + appearance: none; + border-radius: 0; + height: 0.2em; + background: linear-gradient(var(--track-fill), var(--track-fill)) 0 / + var(--pos) no-repeat, + $color__black--10; +} + +@mixin thumb() { + position: relative; + top: -0.7em; + appearance: none; + box-sizing: border-box; + width: 1.6em; + height: 1.6em; + border-radius: 50%; + border: none; + box-shadow: 0 0 0 0.1em var(--thumb-border); + background: $color__white; + cursor: grab; + + &:active { + cursor: grabbing; + } +} + +.o-layered-image-viewer__opacity-field { + display: flex; + gap: 1.6em; + align-items: center; + + input { + --track-fill: #{$color__black--42}; + --thumb-border: #{$color__black--20}; + + font-size: 1em; + --pos: calc(#{1.6em} + var(--percent, 0) * (100% - #{1.6em})); + appearance: none; + width: 100%; + + &::-webkit-slider-runnable-track { + @include track; + } + &::-webkit-slider-thumb { + @include thumb; + } + + &::-moz-range-track { + @include track; + } + + &::-moz-range-thumb { + @include thumb; + } + + &:hover { + --thumb-border: #{$color__black--42}; + } + + &:active, + &:focus-visible { + --track-fill: #{$color__black--80}; + --thumb-border: #{$color__black--80}; + } + } + + @include breakpoint('small+') { + margin-left: 1.6em; + } +} + +// ---- Details (Menu button) +.o-layered-image-viewer-details { + position: relative; + background-color: transparent; + + &[open] { + summary { + background: rgba(0, 0, 0, 0.6); + } + } + + summary { + display: flex; + justify-content: center; + width: 48px; + height: 48px; + border: none; + cursor: pointer; + &::-webkit-details-marker { + display: none; + } + + svg { + margin: 0; + } + } +} + +// ---- Menu + +.o-layered-image-viewer-details__section + + .o-layered-image-viewer-details__section { + margin-top: 4em; +} + +.o-layered-image-viewer-details__heading { + margin-bottom: 1.2em; + padding-right: 2.4em; +} + +.o-layered-image-viewer-details__menu { + position: absolute; + bottom: 100%; + right: calc(-100% - 0.1em); + min-width: min(calc(var(--viewer-width) - 48px), 35em); + background: $color__white; + padding: 2.4em; + max-height: calc(var(--viewer-height) - 9.8em); + overflow: auto; + + @include breakpoint('small+') { + // button w/h is 4.8em + right: calc(100% - 4.8em); + } +} + +.o-layered-image-viewer-details__close { + position: absolute; + top: 0.8em; + right: 0.8em; +} + + +.o-layered-image-viewer__details-rows { + display: flex; + flex-direction: column; + gap: 1.2em; +} + +.o-layered-image-viewer__details-row { + gap: 2.4em; + padding-bottom: 1.2em; + border-bottom: 0.1em solid $color__black--5; + + &:first-child { + padding-top: 1.2em; + border-top: 0.1em solid $color__black--5; + } +} + +.o-layered-image-viewer__details-row--radio { + display: grid; + grid-template-columns: 1fr 1.6em 1.6em; + justify-items: center; + align-items: center; + + *:first-child { + justify-self: self-start; + } +} + +.o-layered-image-viewer__details-row--title { + align-items: flex-end; + border: none; + + .f-caption { + color: $color__black--54; + } +} + +.o-layered-image-viewer-details__radio-group { + display: contents; +} + +// ---- Mouunted element +.o-layered-image-viewer__osd { + .m-media__img { + display: flex; + } +} + +.o-layered-image-viewer__osd-mount { + width: 100%; + // a11y: need min-height that doesn't allow buttons to overlap + min-height: 32em; + max-height: 80vh; + aspect-ratio: 1 / var(--viewer-aspect); + + @supports not (aspect-ratio: 1) { + height: 80vh; + } + + // Overlays should be non-interactive + .openseadragon-canvas img { + pointer-events: none; + } + +} + +// Initial modal state +.o-layered-image-viewer__modal { + position: fixed; + width: 100vw; + height: 100vh; + max-width: none; + max-height: none; + padding: 0; + border: 0; + margin: 0; + opacity: 0; + -webkit-user-select: none; + user-select: none; +} diff --git a/frontend/scss/pages/_p-issue-show.scss b/frontend/scss/pages/_p-issue-show.scss index 858bddbbe..88da24dba 100644 --- a/frontend/scss/pages/_p-issue-show.scss +++ b/frontend/scss/pages/_p-issue-show.scss @@ -1,8 +1,7 @@ // This file contains styles for both journal issues and magazine issues .p-magazineissue-show, .p-magazineissue-latest, -.p-digitalpublications-show, -.p-issue-show { +.p-digitalpublications-show { @extend %sticky-sidebar; .o-article__body { @@ -52,8 +51,7 @@ // Top margin is different for digital publications vs. everything else .p-magazineissue-show, -.p-magazineissue-latest, -.p-issue-show { +.p-magazineissue-latest { .o-article__body::before { @each $name in ('large', 'xlarge') { @include breakpoint('#{$name}') { diff --git a/frontend/scss/print.scss b/frontend/scss/print.scss index c6140488c..184083710 100644 --- a/frontend/scss/print.scss +++ b/frontend/scss/print.scss @@ -175,6 +175,14 @@ html.s-print body { } .o-blocks { + & > h2 { + font-size: 2em; + margin-top: 2em; + } + & > h3 { + font-size: 1.5em; + margin-top: 1.5em; + } & > h5, & > p, & > ul, @@ -223,6 +231,11 @@ html.s-print body { } } + .o-article__body, + .o-gallery { + width: 100%; + } + .o-article--editorial .o-blocks > p:not([class*=f-]), .o-article--editorial .o-blocks > ul:not([class*=f-]):not([class*=o-]):not([class*=m-]), .o-article--editorial .o-blocks > ol:not([class*=f-]):not([class*=o-]):not([class*=m-]) { @@ -248,6 +261,10 @@ html.s-print body { display: block; } + .o-gallery--slider__controls { + display: none; + } + .o-accordion__panel { height: auto; } @@ -278,16 +295,27 @@ html.s-print body { } .m-media { + break-inside: avoid; margin: 20px 0 0; - padding: 0; overflow: hidden; + padding: 0; + } + + .m-media.m-media--gallery, + .m-media.m-media--l, + .m-media.m-media--s { + & .m-media__img { + width: 50%; + } + & figcaption { + max-width: 50%; + } } .m-media .m-media__img { - position: relative; - width: 25%; float: left; overflow: hidden; + position: relative; } .m-media .m-media__img.m-media__img--video { @@ -297,9 +325,11 @@ html.s-print body { .m-media .m-media__img img { display: block; - width: 100%; height: auto; margin: 0; + max-height: 50vw; + max-width: 50vw; + width: auto; } .m-media .m-media__img video, @@ -315,10 +345,9 @@ html.s-print body { } .m-media figcaption { - width: 75%; float: left; - padding-right: 50px; padding-left: 28px; + padding-right: 50px; } .o-article__meta .m-link-list, @@ -331,7 +360,7 @@ html.s-print body { .m-article-header__img { height: 100%; margin: 0 auto 0 0; - width: 66%; + width: 100%; } .m-article-header__img img { diff --git a/frontend/scss/setup/_icons.scss b/frontend/scss/setup/_icons.scss index c654391d7..1b33ab104 100755 --- a/frontend/scss/setup/_icons.scss +++ b/frontend/scss/setup/_icons.scss @@ -100,6 +100,9 @@ More variants maybe added later, so anything thats not a 16px square SVG needs a + + + @@ -196,6 +199,9 @@ More variants maybe added later, so anything thats not a 16px square SVG needs a + + + @@ -419,6 +425,11 @@ The cloud front server caches icons, if you add a new icon, or edit an icon, you height: 184.4px; } +.icon--layers--24 { + width: 24px; + height: 24px; +} + .icon--location { width: 16px; height: 16px; @@ -579,6 +590,11 @@ The cloud front server caches icons, if you add a new icon, or edit an icon, you height: 44px; } +.icon--reset--24 { + width: 24px; + height: 24px; +} + .icon--return { width: 16px; height: 16px; diff --git a/frontend/scss/state/_s-layered-image-viewer-active.scss b/frontend/scss/state/_s-layered-image-viewer-active.scss new file mode 100644 index 000000000..989c350f9 --- /dev/null +++ b/frontend/scss/state/_s-layered-image-viewer-active.scss @@ -0,0 +1,29 @@ +/*** + +Layered image viewer active +============================ + +When fullscreen / using modal on layered image viewer + + +***/ + +.s-layered-image-viewer-modal-active { + &, + body { + overflow: hidden; + } + + .o-layered-image-viewer__osd-mount { + background: $color__black--80; + height: 100%; + } + + .o-layered-image-viewer__modal { + top: 0; + left: 0; + z-index: 9999; + animation: reveal 0.3s normal forwards; + opacity: 1; + } +} diff --git a/public/index.php b/public/index.php index 1df295f41..7b8708d73 100644 --- a/public/index.php +++ b/public/index.php @@ -16,8 +16,8 @@ | */ -if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) { - require __DIR__.'/../storage/framework/maintenance.php'; +if (file_exists(__DIR__ . '/../storage/framework/maintenance.php')) { + require __DIR__ . '/../storage/framework/maintenance.php'; } /* @@ -29,7 +29,7 @@ | into the script here so we don't need to manually load our classes. | */ -require __DIR__.'/../vendor/autoload.php'; +require __DIR__ . '/../vendor/autoload.php'; /* |-------------------------------------------------------------------------- @@ -42,7 +42,7 @@ | */ -$app = require_once __DIR__.'/../bootstrap/app.php'; +$app = require_once __DIR__ . '/../bootstrap/app.php'; $kernel = $app->make(Kernel::class); diff --git a/resources/views/admin/articles/form.blade.php b/resources/views/admin/articles/form.blade.php index 39ab73912..739a7089a 100644 --- a/resources/views/admin/articles/form.blade.php +++ b/resources/views/admin/articles/form.blade.php @@ -125,7 +125,7 @@ '3d_model', '3d_tour', '3d_embed', '360_embed', '360_modal', 'gallery_new', 'image_slider', 'mirador_embed', 'mirador_modal', 'vtour_embed', - 'feature_2x', 'feature_4x' + 'feature_2x', 'feature_4x', 'layered_image_viewer' ]) ]) diff --git a/resources/views/admin/blocks/gallery_new.blade.php b/resources/views/admin/blocks/gallery_new.blade.php index d323c8159..1b575095e 100644 --- a/resources/views/admin/blocks/gallery_new.blade.php +++ b/resources/views/admin/blocks/gallery_new.blade.php @@ -4,19 +4,24 @@ {{-- WEB-1251: Inline contents partial for shared gallery block --}} @include('admin.partials.gallery-shared') -@formField('input', [ +@formField('wysiwyg', [ 'name' => 'title', 'label' => 'Title', - 'maxlength' => 60 + 'maxlength' => 60, + 'toolbarOptions' => [ + 'italic', 'link', + ], ]) -@formField('input', [ - 'type' => 'textarea', +@formField('wysiwyg', [ 'name' => 'description', 'label' => 'Description', 'rows' => 4, 'maxlength' => 500, 'note' => 'Will be hidden if title is empty', + 'toolbarOptions' => [ + 'italic', 'link', + ], ]) @formField('checkbox', [ diff --git a/resources/views/admin/blocks/layered_image_viewer.blade.php b/resources/views/admin/blocks/layered_image_viewer.blade.php new file mode 100644 index 000000000..90d5d381e --- /dev/null +++ b/resources/views/admin/blocks/layered_image_viewer.blade.php @@ -0,0 +1,45 @@ +@twillBlockTitle('Layered Image Viewer') +@twillBlockIcon('image') + +@formField('wysiwyg', [ + 'name' => 'caption_title', + 'label' => 'Caption title', + 'toolbarOptions' => [ + 'italic', 'link', + ], +]) + +@formField('wysiwyg', [ + 'name' => 'caption', + 'label' => 'Caption', + 'maxlength' => 300, + 'note' => 'Max 300 characters', + 'toolbarOptions' => [ + 'italic', 'link', + ], +]) + +@formField('select', [ + 'name' => 'size', + 'label' => 'Size', + 'placeholder' => 'Select size', + 'default' => 'm', + 'options' => [ + [ + 'value' => 's', + 'label' => 'Small' + ], + [ + 'value' => 'm', + 'label' => 'Medium' + ], + [ + 'value' => 'l', + 'label' => 'Large' + ] + ] +]) + +@formField('repeater', ['type' => 'layered_image_viewer_img']) + +@formField('repeater', ['type' => 'layered_image_viewer_overlay']) diff --git a/resources/views/admin/digitalPublications/form.blade.php b/resources/views/admin/digitalPublications/form.blade.php index d715c7d4d..1fe07e878 100644 --- a/resources/views/admin/digitalPublications/form.blade.php +++ b/resources/views/admin/digitalPublications/form.blade.php @@ -16,10 +16,9 @@ 'note' => 'Minimum image width 3000px' ]) - @formField('input', [ + @formField('color', [ 'name' => 'bgcolor', 'label' => 'Hero background color', - 'note' => 'Use a color hex code like #b50938' ]) @formField('wysiwyg', [ @@ -37,6 +36,7 @@ 'name' => 'listing_description', 'label' => 'Listing description', 'note' => 'Max 255 characters', + 'maxlength' => 255, 'toolbarOptions' => [ 'italic' ], diff --git a/resources/views/admin/digitalPublications/sections/form.blade.php b/resources/views/admin/digitalPublications/sections/form.blade.php index 755223d30..8508bf31b 100644 --- a/resources/views/admin/digitalPublications/sections/form.blade.php +++ b/resources/views/admin/digitalPublications/sections/form.blade.php @@ -101,7 +101,7 @@ '3d_model', '3d_tour', '3d_embed', '360_embed', '360_modal', 'gallery_new', 'table', 'image_slider', 'mirador_embed', 'mirador_modal', - 'links-bar' + 'links-bar', 'layered_image_viewer' ]) ]) @stop diff --git a/resources/views/admin/events/form.blade.php b/resources/views/admin/events/form.blade.php index 7e29cb4af..3b8391c66 100644 --- a/resources/views/admin/events/form.blade.php +++ b/resources/views/admin/events/form.blade.php @@ -110,7 +110,7 @@ @formField('input', [ 'name' => 'buy_tickets_link', 'label' => 'Button link preview', - 'disabled' => 'true', + 'readonly' => 'true', 'note' => 'Save and refresh the page to see the link preview', ]) @@ -346,7 +346,7 @@ 'label' => 'Program URLs', 'type' => 'textarea', 'rows' => $item->programs->count(), - 'disabled' => 'true', + 'readonly' => 'true', ]) diff --git a/resources/views/admin/exhibitions/form.blade.php b/resources/views/admin/exhibitions/form.blade.php index 18dc1d848..7e51ec5ec 100644 --- a/resources/views/admin/exhibitions/form.blade.php +++ b/resources/views/admin/exhibitions/form.blade.php @@ -119,7 +119,7 @@ 'hr', 'split_block', 'audio_player', 'tour_stop', 'button', 'mobile_app', '3d_model', '360_embed', '360_modal', 'gallery_new', 'mirador_embed', 'mirador_modal', - 'feature_2x', 'feature_4x', 'vtour_embed', + 'feature_2x', 'feature_4x', 'vtour_embed', 'layered_image_viewer' ]) ]) @stop diff --git a/resources/views/admin/highlights/form.blade.php b/resources/views/admin/highlights/form.blade.php index 1825a9baf..789747f25 100644 --- a/resources/views/admin/highlights/form.blade.php +++ b/resources/views/admin/highlights/form.blade.php @@ -61,7 +61,7 @@ 'artwork', 'hr', 'audio_player', 'tour_stop', 'button', '3d_model', 'gallery_new', 'vtour_embed', 'event', 'feature_2x', 'feature_4x', 'list', 'split_block', - 'grid' + 'grid', 'layered_image_viewer' ]) ]) @stop diff --git a/resources/views/admin/homeFeatures/form.blade.php b/resources/views/admin/homeFeatures/form.blade.php index 0b808ef92..872f8d806 100644 --- a/resources/views/admin/homeFeatures/form.blade.php +++ b/resources/views/admin/homeFeatures/form.blade.php @@ -2,11 +2,21 @@ @section('contentFields') @formField('medias', [ - 'label' => 'Hero', + 'with_multiple' => false, + 'no_crop' => false, + 'label' => 'Hero image', 'name' => 'hero', 'note' => 'Minimum image width 3000px' ]) + @formField('medias', [ + 'with_multiple' => false, + 'no_crop' => false, + 'label' => 'Mobile Hero Image', + 'name' => 'mobile_hero', + 'note' => 'Minimum image width 3000px' + ]) + @formField('files', [ 'name' => 'video', 'label' => 'Video file', diff --git a/resources/views/admin/issues/articles/form.blade.php b/resources/views/admin/issues/articles/form.blade.php deleted file mode 100644 index 22829ea58..000000000 --- a/resources/views/admin/issues/articles/form.blade.php +++ /dev/null @@ -1,127 +0,0 @@ -@extends('twill::layouts.form') - -@section('contentFields') - @formField('input', [ - 'name' => 'title_display', - 'label' => 'Title formatting (optional)', - 'note' => 'Use tag to add italics. e.g. Nighthawks' - ]) - - @formField('input', [ - 'name' => 'short_title_display', - 'label' => 'Short title', - 'note' => 'Use tag to add italics. e.g. Nighthawks' - ]) - - @formField('date_picker', [ - 'name' => 'date', - 'label' => 'Display date', - 'optional' => false, - 'withTime' => false, - 'note' => 'Required', - ]) - - @formField('medias', [ - 'with_multiple' => false, - 'no_crop' => false, - 'label' => 'Hero image', - 'name' => 'hero', - 'note' => 'Minimum image width 3000px' - ]) - - @formField('medias', [ - 'with_multiple' => false, - 'no_crop' => false, - 'label' => 'Mobile hero image', - 'name' => 'mobile_hero', - 'note' => 'Minimum image width 3000px' - ]) - - @formField('input', [ - 'name' => 'type_display', - 'label' => 'Article label', - 'note' => 'Used for article cards on the issue page. Defaults to "Article" if empty.', - ]) - - @formField('wysiwyg', [ - 'name' => 'list_description', - 'label' => 'List description', - 'maxlength' => 255, - 'note' => 'Max 255 characters. Will be used on the issue landing, search, and social media.', - 'toolbarOptions' => [ - 'italic' - ], - ]) - - @formField('wysiwyg', [ - 'name' => 'description', - 'label' => 'Description', - 'note' => 'Appears below title on the article detail page.', - 'toolbarOptions' => [ - 'italic' - ], - ]) - - @formField('input', [ - 'name' => 'abstract', - 'label' => 'Abstract', - 'type' => 'textarea', - 'note' => 'Appears in italics below the description on article detail.', - ]) - - @formField('input', [ - 'name' => 'author_display', - 'label' => 'Author display', - ]) - - @formField('browser', [ - 'routePrefix' => 'collection', - 'moduleName' => 'authors', - 'name' => 'authors', - 'label' => 'Authors', - 'max' => 10 - ]) - - @formField('wysiwyg', [ - 'name' => 'cite_as', - 'label' => 'How to Cite', - 'toolbarOptions' => [ - 'italic' - ], - ]) - - @formField('input', [ - 'name' => 'review_status', - 'label' => 'Review status', - ]) - - @formField('medias', [ - 'with_multiple' => false, - 'no_crop' => false, - 'label' => 'License image', - 'name' => 'license', - ]) - - @formField('input', [ - 'name' => 'license_text', - 'label' => 'License text', - ]) - - @formField('block_editor', [ - 'blocks' => BlockHelpers::getBlocksForEditor([ - 'paragraph', 'image', 'video', 'media_embed', 'quote', - 'list', 'artwork', 'hr', 'citation', 'split_block', - 'membership_banner', 'digital_label', 'audio_player', 'tour_stop', 'button', 'mobile_app', - '3d_model', '3d_tour', '3d_embed', '360_embed', '360_modal', - 'gallery_new', 'table', - 'image_slider', 'mirador_embed', 'mirador_modal', - ]) - ]) - -@stop - -@section('fieldsets') - - @include('admin.partials.meta') - -@stop diff --git a/resources/views/admin/issues/create.blade.php b/resources/views/admin/issues/create.blade.php deleted file mode 100644 index 7367ade9b..000000000 --- a/resources/views/admin/issues/create.blade.php +++ /dev/null @@ -1,9 +0,0 @@ -@include('admin.partials.create') - -@formField('input', [ - 'name' => 'issue_number', - 'label' => 'Issue number', - 'required' => true, - 'type' => 'number', - 'note' => 'Required', -]) diff --git a/resources/views/admin/issues/form.blade.php b/resources/views/admin/issues/form.blade.php deleted file mode 100644 index 0642758e2..000000000 --- a/resources/views/admin/issues/form.blade.php +++ /dev/null @@ -1,96 +0,0 @@ -@extends('twill::layouts.form') - -@section('contentFields') -
{{ $item->articles->count() }} Articles - @formField('input', [ - 'name' => 'title_display', - 'label' => 'Title formatting (optional)', - 'note' => 'Use tag to add italics. e.g. Nighthawks' - ]) - - @formField('input', [ - 'name' => 'issue_number', - 'label' => 'Issue number', - 'type' => 'number', - 'maxlength' => 3, - 'optional' => false, - 'note' => 'Required', - ]) - - @formField('date_picker', [ - 'name' => 'date', - 'label' => 'Display date', - 'optional' => false, - 'withTime' => false, - 'note' => 'Required', - ]) - - @formField('wysiwyg', [ - 'name' => 'header_text', - 'label' => 'Header text', - 'toolbarOptions' => [ - 'italic' - ], - ]) - - @formField('wysiwyg', [ - 'name' => 'list_description', - 'label' => 'List description', - 'maxlength' => 255, - 'note' => 'Max 255 characters. Will be used when the issue appears in listings and for social media.', - 'toolbarOptions' => [ - 'italic' - ], - ]) - - @include('admin.partials.hero') - -
- - @formField('wysiwyg', [ - 'name' => 'welcome_note_display', - 'label' => 'Welcome note text', - 'toolbarOptions' => [ - 'italic' - ], - ]) - - @formField('browser', [ - 'name' => 'welcome_note_article', - 'label' => 'Welcome note article', - 'endpoint' => route('admin.collection.issues.articles.subbrowser',[ - 'issue' => $item->id, - ]), - 'max' => 1, - ]) - -
- - @formField('medias', [ - 'with_multiple' => false, - 'no_crop' => false, - 'label' => 'License image', - 'name' => 'license', - ]) - - @formField('input', [ - 'name' => 'license_text', - 'label' => 'License text', - ]) - -
- - @formField('wysiwyg', [ - 'name' => 'cite_as', - 'label' => 'How to Cite', - 'toolbarOptions' => [ - 'italic' - ], - ]) -@stop - -@section('fieldsets') - - @include('admin.partials.meta') - -@stop diff --git a/resources/views/admin/pages/form_articles_and_publications.blade.php b/resources/views/admin/pages/form_articles_and_publications.blade.php index cc2d9a7f1..57daab07b 100644 --- a/resources/views/admin/pages/form_articles_and_publications.blade.php +++ b/resources/views/admin/pages/form_articles_and_publications.blade.php @@ -17,15 +17,6 @@ 'label' => 'Featured items', ]) - @formField('browser', [ - 'max' => 4, - 'endpoint' => route('admin.collection.issues.articles.subbrowser',[ - 'issue' => $item->present()->getFeaturedJournalIssue()->id ?? 0, - ]), - 'name' => 'featuredJournalArticles', - 'label' => 'Featured journal articles', - ]) - @formField('browser', [ 'routePrefix' => 'collection.interactive_features', 'max' => 4, diff --git a/resources/views/admin/repeaters/layered_image_viewer_img.blade.php b/resources/views/admin/repeaters/layered_image_viewer_img.blade.php new file mode 100644 index 000000000..9b1660fd4 --- /dev/null +++ b/resources/views/admin/repeaters/layered_image_viewer_img.blade.php @@ -0,0 +1,19 @@ +@twillRepeaterTitle('Image') +@twillRepeaterTrigger('Add image') +@twillRepeaterComponent('a17-block-layered_image_viewer_img') +@twillRepeaterMax('10') + + +@formField('medias', [ + 'name' => 'image', + 'label' => 'Image', + 'max' => 1 +]) + +@formField('input', [ + 'name' => 'label', + 'label' => 'Label', + 'note' => 'Displayed at bottom of image', + 'maxlength' => 82, +]) + diff --git a/resources/views/admin/repeaters/layered_image_viewer_overlay.blade.php b/resources/views/admin/repeaters/layered_image_viewer_overlay.blade.php new file mode 100644 index 000000000..da2fcdfa9 --- /dev/null +++ b/resources/views/admin/repeaters/layered_image_viewer_overlay.blade.php @@ -0,0 +1,23 @@ +@twillRepeaterTitle('Overlay') +@twillRepeaterTrigger('Add overlay') +@twillRepeaterComponent('a17-block-layered_image_viewer_overlay') +@twillRepeaterMax('10') + + +@formField('medias', [ + 'name' => 'image', + 'label' => 'Overlay', + 'max' => 1 +]) + +@formField('input', [ + 'name' => 'label', + 'label' => 'Label', + 'note' => 'Displayed at bottom of overlay', + 'maxlength' => 82, +]) + +@formField('checkbox', [ + 'name' => 'starting_view', + 'label' => 'Show this overlay in starting view', +]) diff --git a/resources/views/admin/videos/form.blade.php b/resources/views/admin/videos/form.blade.php index 86c2268d9..8d9595dff 100644 --- a/resources/views/admin/videos/form.blade.php +++ b/resources/views/admin/videos/form.blade.php @@ -2,6 +2,7 @@ 'additionalFieldsets' => [ ['fieldset' => 'content', 'label' => 'Content'], ['fieldset' => 'related_to', 'label' => 'Related'], + ['fieldset' => 'metadata', 'label' => 'Metadata'], ] ]) @@ -47,6 +48,7 @@ 'rows' => 3, 'type' => 'textarea', ]) + @formField('block_editor', [ 'blocks' => BlockHelpers::getBlocksForEditor([ @@ -73,6 +75,28 @@ + + @formField('input', [ + 'name' => 'meta_title', + 'label' => 'Metadata Title' + ]) + + @formField('input', [ + 'name' => 'meta_description', + 'label' => 'Metadata Description', + 'type' => 'textarea' + ]) + + @formField('input', [ + 'name' => 'search_tags', + 'label' => 'Internal Search Tags', + 'type' => 'textarea' + ]) + +

Comma-separatated list of words or phrases. Don't worry about grammar or similar word variations. This field is intended to assist our internal search engine in finding your content. These tags will not be shown to website users and will have no effect on external search engines, e.g. Google.

+ +
+ @include('admin.partials.related') @endsection diff --git a/resources/views/components/molecules/_m-article-actions----journal-article.blade.php b/resources/views/components/molecules/_m-article-actions----journal-article.blade.php deleted file mode 100644 index a8a44ceea..000000000 --- a/resources/views/components/molecules/_m-article-actions----journal-article.blade.php +++ /dev/null @@ -1,67 +0,0 @@ -
- - - - - - @if (!empty($item->issue)) - @component('components.molecules._m-article-actions----journal__issues') - @slot('issues', [$item->issue]) - @endcomponent - @endif - - @if (!empty($item->present()->articlesForSidebar())) - @component('components.organisms._o-accordion') - @slot('variation', 'o-accordion--publication-sidebar') - @slot('titleFont', 'f-tag-2') - @slot('items', $item->present()->articlesForSidebar()) - @endcomponent - @endif - -

Article Actions

-
    -
  • - @component('components.atoms._btn') - @slot('variation', 'btn--icon btn--senary') - @slot('font', '') - @slot('icon', 'icon--share--24') - @slot('behavior','sharePage') - @slot('ariaLabel','Share page') - @endcomponent -
  • - @if (!empty($item->present()->pdfDownloadPath())) -
  • - @component('components.atoms._btn') - @slot('variation', 'btn--icon') - @slot('font', '') - @slot('tag', 'a') - @slot('href', $item->present()->pdfDownloadPath()) - @slot('icon', 'icon--download--24') - @slot('ariaLabel','Download PDF') - @endcomponent -
  • - @endif - @if ($item->cite_as) -
  • - @component('components.atoms._btn') - @slot('variation', 'btn--icon btn--septenary') - @slot('font', '') - @slot('tag', 'a') - @slot('href', '#h-how-to-cite') - @slot('icon', 'icon--citation--24') - @slot('ariaLabel','Show how to cite') - @endcomponent -
  • - @endif -
-
- -
diff --git a/resources/views/components/molecules/_m-article-actions----journal-issue.blade.php b/resources/views/components/molecules/_m-article-actions----journal-issue.blade.php deleted file mode 100644 index 6b956db75..000000000 --- a/resources/views/components/molecules/_m-article-actions----journal-issue.blade.php +++ /dev/null @@ -1,60 +0,0 @@ -
- - - -

The Art Institute Review is dedicated to innovative object-centered scholarship and is published twice a year. Learn more.

- - @if (isset($issues) && $issues->count() > 1) - @component('components.molecules._m-search-bar') - @slot('placeholder','Search articles') - @slot('name', 'journal-search-mobile') - @slot('value', request('q')) - @slot('action', route('collection')) - @slot('gtmAttributes', 'data-gtm-event="click" data-gtm-event-category="journal f-search"') - @endcomponent - -
- - @component('components.molecules._m-article-actions----journal__issues') - @slot('issues', $issues) - @endcomponent - @else -
- @endif - -

Page Actions

-
    -
  • - @component('components.atoms._btn') - @slot('variation', 'btn--icon btn--senary') - @slot('font', '') - @slot('icon', 'icon--share--24') - @slot('behavior','sharePage') - @slot('ariaLabel','Share page') - @endcomponent -
  • - @if (!empty($citeAs)) -
  • - @component('components.atoms._btn') - @slot('variation', 'btn--icon btn--septenary') - @slot('font', '') - @slot('tag', 'a') - @slot('href', '#h-how-to-cite') - @slot('icon', 'icon--citation--24') - @slot('ariaLabel','Show how to cite') - @endcomponent -
  • - @endif -
- -
- -
- -
diff --git a/resources/views/components/molecules/_m-article-actions----journal__issues.blade.php b/resources/views/components/molecules/_m-article-actions----journal__issues.blade.php deleted file mode 100644 index 86bdfaa40..000000000 --- a/resources/views/components/molecules/_m-article-actions----journal__issues.blade.php +++ /dev/null @@ -1,29 +0,0 @@ -{{-- _m-article-actions----magazine-issue also has this, separately, since it's different enough --}} -
    - @foreach($issues as $issue) -
  • - @component('components.atoms._tag') - @slot('href', route('issues.show', [ - 'issueNumber' => $issue->issue_number, - 'slug' => $issue->getSlug(), - ])) - @slot('variation', 'tag--journal tag--senary tag--w-image') - @slot('gtmAttributes', 'data-gtm-event="' . StringHelpers::getUtf8Slug( $issue->title ) . '" data-gtm-event-category="journal-sidebar-issue"') - @if (!empty($issue->imageFront('hero', 'default'))) - @component('components.atoms._img') - @slot('image', $issue->imageFront('hero', 'default')) - @slot('settings', array( - 'fit' => 'crop', - 'ratio' => '1:1', - 'srcset' => array(30,60), - 'sizes' => '60px', - )) - @endcomponent - @endif - Issue {!! $issue->issue_number !!} -
    - {!! $issue->present()->title !!} - @endcomponent -
  • - @endforeach -
diff --git a/resources/views/components/molecules/_m-article-header----journal.blade.php b/resources/views/components/molecules/_m-article-header----journal.blade.php deleted file mode 100644 index 8e3c6e471..000000000 --- a/resources/views/components/molecules/_m-article-header----journal.blade.php +++ /dev/null @@ -1,64 +0,0 @@ -
-
- @if ($img) - @component('components.atoms._img') - @slot('image', $img) - @slot('class', 'img-hero-desktop') - @slot('settings', array( - 'srcset' => array(300,600,1000,1500,3000), - 'sizes' => '100vw', - )) - @endcomponent - @component('components.atoms._img') - @slot('image', !empty($imgMobile) ? $imgMobile : $img) - @slot('class', 'img-hero-mobile') - @slot('settings', array( - 'srcset' => array(300,600,1000,1500,3000), - 'sizes' => '100vw', - )) - @endcomponent - @endif -
-
- - @if (isset($intro)) - @component('components.blocks._text') - @slot('font','f-deck') - @slot('variation', 'm-article-header__intro') - @slot('tag', 'div') - {!! SmartyPants::defaultTransform($intro) !!} - @endcomponent - @endif - @if (isset($issueNumber) || isset($title)) -
- @if (isset($issueNumber)) - @component('components.blocks._text') - @slot('font','f-subheading-2') - @slot('variation', 'm-article-header__issue-number') - @slot('tag', 'span') - Issue {!! SmartyPants::defaultTransform($issueNumber) !!} - @endcomponent - @endif - @if (isset($title)) - @component('components.atoms._title') - @slot('tag','h1') - @slot('font', 'f-subheading-2') - @slot('itemprop','name') - @slot('title', $title) - @slot('title_display', $title_display ?? null) - @endcomponent - @endif -
- @endif - @if (!empty($credit)) - @component('components.molecules._m-info-trigger') - @slot('isInverted', true) - @slot('creditText', $credit) - @endcomponent - @endif -
-
diff --git a/resources/views/components/molecules/_m-layered-image-viewer-layer.blade.php b/resources/views/components/molecules/_m-layered-image-viewer-layer.blade.php new file mode 100644 index 000000000..9682eb41b --- /dev/null +++ b/resources/views/components/molecules/_m-layered-image-viewer-layer.blade.php @@ -0,0 +1,100 @@ +@php + $layerType = isset($layerType) ? $layerType : 'image'; + $size = isset($size) ? $size : 'm'; + $media = $item['media']; + + if ($media) { + $alt = $media['alt']; + $width = $media['width']; + $height = $media['height']; + $crop_x = $media['crop_x']; + $crop_y = $media['crop_y']; + $startingView = $item['starting_view'] ? $item['starting_view'] : false; + + // Set empty $imageSettings, this will be populated based on $size + $imageSettings = []; + + $defaultSrcset = array(200,400,600,1000,1500,3000); + + if (empty($imageSettings) && $size === 's') { + $imageSettings = array( + 'srcset' => $defaultSrcset, + 'sizes' => ImageHelpers::aic_imageSizes(array( + 'xsmall' => '58', + 'small' => '58', + 'medium' => '38', + 'large' => '28', + 'xlarge' => '28', + ))); + } + + if (empty($imageSettings) && $size === 'm') { + $imageSettings = array( + 'srcset' => $defaultSrcset, + 'sizes' => ImageHelpers::aic_imageSizes(array( + 'xsmall' => '58', + 'small' => '58', + 'medium' => '58', + 'large' => '43', + 'xlarge' => '43', + ))); + } + + if (empty($imageSettings) && $size === 'l') { + $imageSettings = array( + 'srcset' => $defaultSrcset, + 'sizes' => ImageHelpers::aic_imageSizes(array( + 'xsmall' => '58', + 'small' => '58', + 'medium' => '58', + 'large' => '58', + 'xlarge' => '58', + ))); + } + + if (isset($imageSettings)) { + + $imageSettings = ImageHelpers::aic_imageSettings(array( + 'settings' => $imageSettings, + 'image' => $media, + )); + + $srcset = $imageSettings['srcset']; + $sizes = $imageSettings['sizes']; + } + } + + global $_allowAdvancedModalFeatures; +@endphp + +@if ($media) +
+
+
+ {{ $alt }} +
+ @if (isset($item['label'])) +
+
+ {!! $item['label'] !!} +
+
+ @endif +
+
+@endif diff --git a/resources/views/components/molecules/_m-listing----article.blade.php b/resources/views/components/molecules/_m-listing----article.blade.php index a0361c664..5f0ffbd2d 100644 --- a/resources/views/components/molecules/_m-listing----article.blade.php +++ b/resources/views/components/molecules/_m-listing----article.blade.php @@ -3,10 +3,23 @@ @if (!isset($hideImage) || (isset($hideImage) && !($hideImage))) -1 and !$item->videoFront) ? ' data-blur-img' : '' }}> @if (isset($image) || $item->imageFront('hero')) - @component('components.atoms._img') - @slot('image', $image ?? $item->imageFront('hero')) - @slot('settings', $imageSettings ?? '') - @endcomponent + @if ($isHero ?? false) + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @slot('class', 'img-hero-desktop') + @endcomponent + @component('components.atoms._img') + @slot('image', $imageMobile ?? $item->imageFront('mobile_hero') ?? $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @slot('class', 'img-hero-mobile') + @endcomponent + @else + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @endcomponent + @endif @component('components.molecules._m-listing-video') @slot('item', $item) @slot('image', $image ?? null) diff --git a/resources/views/components/molecules/_m-listing----custom.blade.php b/resources/views/components/molecules/_m-listing----custom.blade.php index 63bf68899..6dbf7d9a5 100644 --- a/resources/views/components/molecules/_m-listing----custom.blade.php +++ b/resources/views/components/molecules/_m-listing----custom.blade.php @@ -9,10 +9,23 @@ -1 and !$item->videoFront()) ? ' data-blur-img' : '' }}> @if (isset($image) || $item->imageFront('hero')) - @component('components.atoms._img') - @slot('image', $image ?? $item->imageFront('hero')) - @slot('settings', $imageSettings ?? '') - @endcomponent + @if ($isHero ?? false) + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @slot('class', 'img-hero-desktop') + @endcomponent + @component('components.atoms._img') + @slot('image', $imageMobile ?? $item->imageFront('mobile_hero') ?? $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @slot('class', 'img-hero-mobile') + @endcomponent + @else + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @endcomponent + @endif @component('components.molecules._m-listing-video') @slot('item', $item) @slot('image', $image ?? null) diff --git a/resources/views/components/molecules/_m-listing----event.blade.php b/resources/views/components/molecules/_m-listing----event.blade.php index 91c9cc85a..a05ce0ff8 100644 --- a/resources/views/components/molecules/_m-listing----event.blade.php +++ b/resources/views/components/molecules/_m-listing----event.blade.php @@ -10,10 +10,23 @@ @if (!isset($hideImage) or (isset($hideImage) && !($hideImage))) -1 and !$item->videoFront) ? ' data-blur-img' : '' }}> @if (isset($image) || $item->imageFront('hero')) - @component('components.atoms._img') - @slot('image', $image ?? $item->imageFront('hero')) - @slot('settings', $imageSettings ?? '') - @endcomponent + @if ($isHero ?? false) + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @slot('class', 'img-hero-desktop') + @endcomponent + @component('components.atoms._img') + @slot('image', $imageMobile ?? $item->imageFront('mobile_hero') ?? $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @slot('class', 'img-hero-mobile') + @endcomponent + @else + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @endcomponent + @endif @component('components.molecules._m-listing-video') @slot('item', $item) @slot('image', $image ?? null) diff --git a/resources/views/components/molecules/_m-listing----exhibition.blade.php b/resources/views/components/molecules/_m-listing----exhibition.blade.php index 6a17a1881..c43774f2f 100644 --- a/resources/views/components/molecules/_m-listing----exhibition.blade.php +++ b/resources/views/components/molecules/_m-listing----exhibition.blade.php @@ -10,10 +10,23 @@ @if (!isset($hideImage) || (isset($hideImage) && !($hideImage))) -1 and !$item->videoFront) ? ' data-blur-img' : '' }}> @if (isset($image) || $item->imageFront('hero')) - @component('components.atoms._img') - @slot('image', $image ?? $item->imageFront('hero')) - @slot('settings', $imageSettings ?? '') - @endcomponent + @if ($isHero ?? false) + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @slot('class', 'img-hero-desktop') + @endcomponent + @component('components.atoms._img') + @slot('image', $imageMobile ?? $item->imageFront('mobile_hero') ?? $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @slot('class', 'img-hero-mobile') + @endcomponent + @else + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero')) + @slot('settings', $imageSettings ?? '') + @endcomponent + @endif @component('components.molecules._m-listing-video') @slot('item', $item) @slot('image', $image ?? null) diff --git a/resources/views/components/molecules/_m-listing----highlight.blade.php b/resources/views/components/molecules/_m-listing----highlight.blade.php index 587baf25b..a0aaf87dd 100644 --- a/resources/views/components/molecules/_m-listing----highlight.blade.php +++ b/resources/views/components/molecules/_m-listing----highlight.blade.php @@ -2,13 +2,30 @@ @if (!isset($hideImage) || (isset($hideImage) && !($hideImage))) - @if ($item->imageFront('hero') ?? $item->images[0] ?? false) - @component('components.atoms._img') - @slot('image', $item->imageFront('hero') ?? $item->images[0]) - @slot('settings', !isset($imageSettings) ? null : array_merge($imageSettings, [ - 'ratio' => '1:1', // TODO: Verify $imgVariation usage? - ])) - @endcomponent + @if ($image ?? $item->imageFront('hero') ?? $item->images[0] ?? false) + @if ($isHero ?? false) + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero') ?? $item->images[0]) + @slot('class', 'img-hero-desktop') + @slot('settings', !isset($imageSettings) ? null : array_merge($imageSettings, [ + 'ratio' => '1:1', // TODO: Verify $imgVariation usage? + ])) + @endcomponent + @component('components.atoms._img') + @slot('image', $imageMobile ?? $item->imageFront('mobile_hero') ?? $image ?? $item->imageFront('hero') ?? $item->images[0]) + @slot('class', 'img-hero-mobile') + @slot('settings', !isset($imageSettings) ? null : array_merge($imageSettings, [ + 'ratio' => '1:1', // TODO: Verify $imgVariation usage? + ])) + @endcomponent + @else + @component('components.atoms._img') + @slot('image', $image ?? $item->imageFront('hero') ?? $item->images[0]) + @slot('settings', !isset($imageSettings) ? null : array_merge($imageSettings, [ + 'ratio' => '1:1', // TODO: Verify $imgVariation usage? + ])) + @endcomponent + @endif @else @endif diff --git a/resources/views/components/molecules/_m-listing----journal-article-minimal.blade.php b/resources/views/components/molecules/_m-listing----journal-article-minimal.blade.php deleted file mode 100644 index ac60aa947..000000000 --- a/resources/views/components/molecules/_m-listing----journal-article-minimal.blade.php +++ /dev/null @@ -1,28 +0,0 @@ -{{-- PUB-146: Used to show journal article on Writings --}} -<{{ $tag ?? 'li' }} class="m-listing m-listing--w-meta-bottom{{ (isset($variation)) ? ' '.$variation : '' }}"> - - - @if ($item->imageFront('hero')) - @component('components.atoms._img') - @slot('image', $item->imageFront('hero')) - @slot('settings', $imageSettings ?? '') - @endcomponent - @else - - @endif - - - @if ($item->present()->subtype) - {!! $item->present()->subtype !!} -
- @endif - {!! $item->present()->title_display ?? $item->present()->title !!} -
- @if ($item->showAuthors()) - - {{ $item->showAuthors() }} - - @endif -
-
- diff --git a/resources/views/components/molecules/_m-listing----journal-issue.blade.php b/resources/views/components/molecules/_m-listing----journal-issue.blade.php deleted file mode 100644 index bda32fa35..000000000 --- a/resources/views/components/molecules/_m-listing----journal-issue.blade.php +++ /dev/null @@ -1,29 +0,0 @@ -{{-- PUB-146: Used to show journal issue on Writings --}} -<{{ $tag ?? 'li' }} class="m-listing m-listing--article{{ (isset($variation)) ? ' '.$variation : '' }}"> - - - @if (isset($image) || $item->imageFront('hero')) - @component('components.atoms._img') - @slot('image', $image ?? $item->imageFront('hero')) - @slot('settings', $imageSettings ?? '') - @endcomponent - @else - - @endif - - -
- {!! $subtype ?? $item->present()->subtype !!} -
- @component('components.atoms._title') - @slot('font', $titleFont ?? 'f-list-3') - @slot('title', $item->present()->title) - @slot('title_display', $item->present()->title_display) - @endcomponent -
- @if ($item->present()->list_description) -
{!! $item->present()->list_description !!}
- @endif -
-
- diff --git a/resources/views/components/molecules/_m-paginator.blade.php b/resources/views/components/molecules/_m-paginator.blade.php index 9a0d4656b..6a065eaab 100644 --- a/resources/views/components/molecules/_m-paginator.blade.php +++ b/resources/views/components/molecules/_m-paginator.blade.php @@ -29,15 +29,13 @@
  • @if ($paginator->onFirstPage()) - Previous + @else - - - Previous - + Previous + @endif
  • diff --git a/resources/views/components/organisms/_o-color-picker-filter.php b/resources/views/components/organisms/_o-color-picker-filter.blade.php similarity index 100% rename from resources/views/components/organisms/_o-color-picker-filter.php rename to resources/views/components/organisms/_o-color-picker-filter.blade.php diff --git a/resources/views/components/organisms/_o-feature.blade.php b/resources/views/components/organisms/_o-feature.blade.php index e9c82ce96..4aaa2f441 100644 --- a/resources/views/components/organisms/_o-feature.blade.php +++ b/resources/views/components/organisms/_o-feature.blade.php @@ -2,7 +2,9 @@ @component('components.molecules._m-listing----' . strtolower($item->enclosedItem()->type)) @slot('tag', $tag ?? null) @slot('item', $item->enclosedItem()) + @slot('isHero', $isHero) @slot('image', $item->enclosedItem()->featureImage) + @slot('imageMobile', $item->enclosedItem()->featureImageMobile) @slot('variation', $isHero ? 'm-listing--hero' : 'm-listing--feature') @slot('titleFont', $isHero ? 'f-display-1' : 'f-list-4') @slot('imageSettings', array( @@ -15,7 +17,9 @@ @component('components.molecules._m-listing----custom') @slot('tag', $tag ?? null) @slot('item', $item) + @slot('isHero', $isHero) @slot('image', $item->featureImage) + @slot('imageMobile', $item->featureImageMobile) @slot('variation', $isHero ? 'm-listing--hero' : 'm-listing--feature') @slot('titleFont', $isHero ? 'f-display-1' : 'f-list-4') @slot('imageSettings', array( diff --git a/resources/views/components/organisms/_o-layered-image-viewer.blade.php b/resources/views/components/organisms/_o-layered-image-viewer.blade.php new file mode 100644 index 000000000..c992de4f2 --- /dev/null +++ b/resources/views/components/organisms/_o-layered-image-viewer.blade.php @@ -0,0 +1,38 @@ +
    + @if (isset($images) && !empty($images)) +
    + @foreach ($images as $image) + @component('components.molecules._m-layered-image-viewer-layer') + @slot('item', $image) + @slot('size', $size) + @slot('layerType', 'image') + @endcomponent + @endforeach +
    + @endif + + @if (isset($overlays) && !empty($overlays)) +
    + @foreach ($overlays as $overlay) + @component('components.molecules._m-layered-image-viewer-layer') + @slot('item', $overlay) + @slot('size', $size) + @slot('layerType', 'overlay') + @endcomponent + @endforeach +
    + @endif + + @if (isset($captionTitle)) +
    +
    + {!! $captionTitle !!} +
    + @if (isset($captionText)) +
    + {!! $captionText !!} +
    + @endif +
    + @endif +
    diff --git a/resources/views/partials/_header.blade.php b/resources/views/partials/_header.blade.php index c9a0daff5..07ab050b9 100644 --- a/resources/views/partials/_header.blade.php +++ b/resources/views/partials/_header.blade.php @@ -74,16 +74,4 @@ include base_path('frontend/icons/logo--outline--92.svg') @endphp - @if (isset($item) && is_object($item) && (get_class($item) == 'App\Models\Issue' || get_class($item) == 'App\Models\IssueArticle')) - -
    - Issue {{ $item->present()->issueNumber }}
    - {{ $item->present()->issueTitle }} -
    - @endif diff --git a/resources/views/site/articleDetail.blade.php b/resources/views/site/articleDetail.blade.php index e26625a13..ee24fc1fa 100644 --- a/resources/views/site/articleDetail.blade.php +++ b/resources/views/site/articleDetail.blade.php @@ -392,6 +392,7 @@ @endsection @section('extra_scripts') + diff --git a/resources/views/site/articles_publications/index.blade.php b/resources/views/site/articles_publications/index.blade.php index 7b9bdfaa3..b3db149f8 100644 --- a/resources/views/site/articles_publications/index.blade.php +++ b/resources/views/site/articles_publications/index.blade.php @@ -26,22 +26,6 @@ @slot('features', $features ?? null) @endcomponent - @if (!empty($journalFeatureHero) && $journalFeatures->count() > 0) - @component('site.articles_publications._articleFeature') - @slot('featureHero', $journalFeatureHero ?? null) - @slot('features', $journalFeatures ?? null) - @slot('title', 'Art Institute Review') - @slot('showTopBorder', true) - @slot('resourceName', 'journal articles') - @slot('gtmEventPrefix', 'journal') - @slot('browseAllLink', [ - 'label' => 'Browse the latest issue', - 'href' => route('issues.latest'), - 'gtmAttributes' => 'data-gtm-event="browse-all-articles" data-gtm-event-category="nav-link"', - ]) - @endcomponent - @endif - @if(sizeof($experiences['items']) > 0) @component('site.articles_publications._interactiveFeature') @slot('experiences', $experiences['items'] ?? null) diff --git a/resources/views/site/blocks/layered_image_viewer.blade.php b/resources/views/site/blocks/layered_image_viewer.blade.php new file mode 100644 index 000000000..d9471a0b3 --- /dev/null +++ b/resources/views/site/blocks/layered_image_viewer.blade.php @@ -0,0 +1,57 @@ +@php + $captionTitle = $block->present()->input('caption_title'); + $captionText = $block->present()->input('caption'); + $size = $block->present()->input('size'); + $images = []; + $overlays = []; + $cropRegion = null; + + $firstImage = $block->childs->filter(function ($item) { + return $item->type == 'layered_image_viewer_img'; + })->first(); + + // Pull the crop from the first image to pass to the organism + if ($firstImage) { + $cropRegion = array_intersect_key( + $firstImage->imageAsArray('image', 'desktop'), + array_flip(['crop_x', 'crop_y', 'width', 'height']) + ); + $cropRegion['x'] = $cropRegion['crop_x']; + $cropRegion['y'] = $cropRegion['crop_y']; + unset($cropRegion['crop_x']); + unset($cropRegion['crop_y']); + $cropRegion = htmlspecialchars(json_encode($cropRegion), ENT_QUOTES, 'UTF-8'); + } + + foreach ($block->childs as $child) { + $mediaItem = [ + 'media' => $child->imageAsArray('image', 'desktop'), + 'label' => $child->input('label'), + 'starting_view' => $child->checkbox('starting_view') ? $child->checkbox('starting_view') : false, + ]; + + // Append full source for viewer + $mediaItem['media']['full_src'] = strtok($mediaItem['media']['src'], '?'); + + if ($child['type'] == 'layered_image_viewer_img') { + $images[] = $mediaItem; + } + + if ($child['type'] == 'layered_image_viewer_overlay') { + $overlays[] = $mediaItem; + } + + } +@endphp + +@if (count($images) > 0 || count($overlays) > 0) + @component('components.organisms._o-layered-image-viewer') + @slot('variation', 'o-blocks__block') + @slot('captionTitle', $captionTitle) + @slot('captionText', $captionText) + @slot('size', $size) + @slot('images', $images) + @slot('overlays', $overlays) + @slot('cropRegion', $cropRegion) + @endcomponent +@endif diff --git a/resources/views/site/digitalPublicationSectionDetail.blade.php b/resources/views/site/digitalPublicationSectionDetail.blade.php index cd8f78cb3..6d07c0178 100644 --- a/resources/views/site/digitalPublicationSectionDetail.blade.php +++ b/resources/views/site/digitalPublicationSectionDetail.blade.php @@ -86,6 +86,7 @@ @endsection @section('extra_scripts') + diff --git a/resources/views/site/exhibitionDetail.blade.php b/resources/views/site/exhibitionDetail.blade.php index 2a64293b0..c4971a4a9 100644 --- a/resources/views/site/exhibitionDetail.blade.php +++ b/resources/views/site/exhibitionDetail.blade.php @@ -346,6 +346,7 @@ @endsection @section('extra_scripts') + diff --git a/resources/views/site/highlightDetail.blade.php b/resources/views/site/highlightDetail.blade.php index 7536bb602..1ca2edace 100644 --- a/resources/views/site/highlightDetail.blade.php +++ b/resources/views/site/highlightDetail.blade.php @@ -140,6 +140,7 @@ @endsection @section('extra_scripts') + diff --git a/resources/views/site/issueArticleDetail.blade.php b/resources/views/site/issueArticleDetail.blade.php deleted file mode 100644 index 21d0ff1b5..000000000 --- a/resources/views/site/issueArticleDetail.blade.php +++ /dev/null @@ -1,118 +0,0 @@ -@extends('layouts.app') - -@section('content') - -
    - @component('components.molecules._m-sidebar-toggle') - @slot('title', 'Art Institue Review') - @endcomponent - -
    - @component('components.molecules._m-article-actions----journal-article') - @slot('item', $item) - @endcomponent -
    - - @component('components.molecules._m-article-header----journal-article') - @slot('title', $item->present()->title) - @slot('title_display', $item->present()->title_display) - @slot('img', $item->imageFront('hero')) - @slot('imgMobile', $item->imageFront('mobile_hero')) - @endcomponent - -
    - {{-- Intentionally left blank for layout --}} -
    - - @if ($item->description) -
    - @component('components.blocks._text') - @slot('font', 'f-deck') - @slot('tag', 'div') - {!! $item->present()->description !!} - @endcomponent -
    - @endif - -
    - @if ($item->showAuthorsWithLinks()) - @component('components.blocks._text') - @slot('font', 'f-tag-2') - @slot('tag', 'div') - {!! $item->showAuthorsWithLinks() !!} - @endcomponent -
    - @endif - - @if ($item->abstract) - @component('components.blocks._text') - @slot('font', 'f-body-editorial-emphasis') - @slot('variation', 'o-article--journal_abstract') - @slot('tag', 'div') - {!! $item->present()->abstract !!} - @endcomponent -
    - @endif - - @php - global $_collectedReferences; - $_collectedReferences = []; - - global $_paragraphCount; - $_paragraphCount = 0; - @endphp - - {!! $item->renderBlocks(false, [], [ - 'pageTitle' => $item->meta_title ?: $item->title, - ]) !!} - - @component('partials._bibliography') - @slot('notes', $_collectedReferences ?? null) - @slot('references', $item->present()->references()) - @slot('citeAs', $item->present()->citeAs()) - @endcomponent -
    -
    - -@if (isset($featuredArticles) && $featuredArticles) - @component('components.molecules._m-title-bar') - Further Reading - @endcomponent - @component('components.organisms._o-grid-listing') - @slot('variation', 'o-grid-listing--single-row o-grid-listing--scroll@xsmall o-grid-listing--scroll@small o-grid-listing--hide-extra@medium o-grid-listing--gridlines-cols o-grid-listing--gridlines-rows') - @slot('cols_medium','3') - @slot('cols_large','4') - @slot('cols_xlarge','4') - @slot('behavior','dragScroll') - @foreach ($featuredArticles as $item) - @component('components.molecules._m-listing----' . strtolower($item->type)) - @slot('item', $item) - @slot('imageSettings', array( - 'fit' => 'crop', - 'ratio' => '16:9', - 'srcset' => array(200,400,600), - 'sizes' => ImageHelpers::aic_imageSizes(array( - 'xsmall' => '216px', - 'small' => '216px', - 'medium' => '18', - 'large' => '13', - 'xlarge' => '13', - )), - )) - @endcomponent - @endforeach - @endcomponent -@endif - -
    - -@include('components.organisms._o-publication-footer----journal') - -@endsection - -@section('extra_scripts') - - - - -@endsection diff --git a/resources/views/site/issueDetail.blade.php b/resources/views/site/issueDetail.blade.php deleted file mode 100644 index a6e6e8d5d..000000000 --- a/resources/views/site/issueDetail.blade.php +++ /dev/null @@ -1,91 +0,0 @@ -@extends('layouts.app') - -@section('content') - -
    - @component('components.molecules._m-article-header----journal') - @slot('title', $item->present()->title ?? null) - @slot('title_display', $item->present()->title_display ?? null) - @slot('img', $item->imageFront('hero') ?? null) - @slot('imgMobile', $item->imageFront('mobile_hero') ?? null) - @slot('credit', $item->hero_caption ?? null) - @slot('intro', $item->header_text ?? null) - @slot('issueNumber', $item->issue_number ?? null) - @endcomponent - -
    - @component('components.molecules._m-article-actions----journal-issue') - @slot('issues', $issues) - @slot('citeAs', $item->cite_as ?? null) - @endcomponent -
    - -
    - @if ($item->welcome_note_display && $welcomeNote) -
    - @component('components.organisms._o-editors-note----publication') - @slot('description', $item->welcome_note_display) - @slot('articleLink', $welcomeNote->url) - @endcomponent -
    - @endif - - @if ($item->present()->articlesForLanding()) - @component('components.organisms._o-grid-listing') - @slot('variation', 'o-grid-listing--journal') - @slot('cols_xsmall','1') - @slot('cols_small','2') - @slot('cols_medium','2') - @slot('cols_large','2') - @slot('cols_xlarge','2') - @foreach ($item->present()->articlesForLanding() as $article) - @component('components.molecules._m-listing----publication') - @slot('variation', 'm-listing--journal') - @slot('href', $article->url) - @slot('image', $article->imageFront('hero')) - @slot('type', $article->present()->getArticleType()) - @slot('title', $article->present()->title) - @slot('title_display', $article->present()->title_display) - @slot('list_description', $article->present()->list_description) - @slot('author_display', $article->showAuthors()) - @slot('imageSettings', array( - 'fit' => 'crop', - 'ratio' => '16:9', - 'srcset' => array(200,400,600), - 'sizes' => ImageHelpers::aic_imageSizes(array( - 'xsmall' => '216px', - 'small' => '216px', - 'medium' => '18', - 'large' => '13', - 'xlarge' => '13', - )), - )) - @endcomponent - @endforeach - @endcomponent - @endif - - - @if ($item->cite_as) - @component('components.molecules._m-title-bar', [ - 'variation' => 'm-title-bar--compact m-title-bar--light', - ]) - How to Cite - @endcomponent - - {!! $item->cite_as !!} - @endif - -
    - -
    - -
    - -@include('components.organisms._o-publication-footer----journal') - -@endsection - -@section('extra_scripts') - -@endsection diff --git a/public/robots.txt b/resources/views/site/robots.blade.php similarity index 100% rename from public/robots.txt rename to resources/views/site/robots.blade.php diff --git a/resources/views/site/search/index.blade.php b/resources/views/site/search/index.blade.php index d2ba6fd5f..4f5346476 100644 --- a/resources/views/site/search/index.blade.php +++ b/resources/views/site/search/index.blade.php @@ -31,7 +31,7 @@ @endcomponent @endif -@if (empty($featuredResults) && empty($artists) && empty($researchGuides) && empty($pressReleases) && empty($pages) && empty($press) && empty($publications) && empty($artworks) && empty($exhibitions) && empty($events) && empty($articles) && empty($interactiveFeatures) && empty($highlights) && empty($issueArticles)) +@if (empty($featuredResults) && empty($artists) && empty($educatorResources) && empty($pressReleases) && empty($pages) && empty($press) && empty($publications) && empty($artworks) && empty($exhibitions) && empty($events) && empty($articles) && empty($interactiveFeatures) && empty($highlights)) @component('components.molecules._m-no-results') @endcomponent @endif @@ -703,11 +703,10 @@ @endif @endif -{{-- WEB-448: This includes both Research Guides and Educator Resources. --}} -@if (isset($researchGuides) && $researchGuides->getMetadata('pagination')->total > 0) +@if (isset($educatorResources) && $educatorResources->getMetadata('pagination')->total > 0) @component('components.molecules._m-title-bar') @unless($allResultsView) - @slot('links', array(array('label' => 'See all '. $researchGuides->getMetadata('pagination')->total. ' '. Str::plural('resource', $researchGuides->getMetadata('pagination')->total), 'href' => route('search.research-guides', ['q' => request('q')])))) + @slot('links', array(array('label' => 'See all '. $educatorResources->getMetadata('pagination')->total. ' '. Str::plural('resource', $educatorResources->getMetadata('pagination')->total), 'href' => route('search.educator-resources', ['q' => request('q')])))) @endunless Resources @@ -721,7 +720,7 @@ @slot('cols_medium','3') @slot('cols_large','4') @slot('cols_xlarge','4') - @foreach ($researchGuides as $item) + @foreach ($educatorResources as $item) @component('components.molecules._m-listing----generic') @slot('item', $item) @slot('hideImage', true) @@ -740,7 +739,7 @@ @slot('cols_large','4') @slot('cols_xlarge','4') - @foreach ($researchGuides as $item) + @foreach ($educatorResources as $item) @component('components.molecules._m-listing----generic') @slot('item', $item) @slot('hideImage', true) diff --git a/routes/admin.php b/routes/admin.php index 1abcd19eb..1ac1cf6c8 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -9,7 +9,6 @@ use App\Http\Controllers\Admin\ExhibitionController; use App\Http\Controllers\Admin\FeeController; use App\Http\Controllers\Admin\GalleryController; -use App\Http\Controllers\Admin\IssueArticleController; use App\Http\Controllers\Admin\PageController; Route::module('pages'); @@ -70,18 +69,11 @@ Route::module('authors'); - Route::module('issues'); - Route::module('issues.articles'); - - // PUB-127: Browser for nested modules must be implemented manually - Route::get('issuesFoo/{issue}/articles/browser', [IssueArticleController::class, 'browser'])->name('collection.issues.articles.subbrowser'); - Route::module('categoryTerms'); Route::get('categoryTerms/augment/{datahub_id}', [CategoryTermController::class, 'augment'])->name('collection.categoryTerms.augment'); Route::group(['prefix' => 'research_resources'], function () { Route::get('landing', [PageController::class, 'research'])->name('collection.research_resources.landing'); - Route::module('researchGuides'); Route::module('educatorResources'); }); diff --git a/routes/api.php b/routes/api.php index ae1cbf61a..e27dc6748 100644 --- a/routes/api.php +++ b/routes/api.php @@ -19,12 +19,9 @@ use App\Http\Controllers\API\HighlightsController; use App\Http\Controllers\API\HoursController; use App\Http\Controllers\API\InteractiveFeaturesController; -use App\Http\Controllers\API\IssuesController; -use App\Http\Controllers\API\IssueArticlesController; use App\Http\Controllers\API\LocationsController; use App\Http\Controllers\API\PressReleasesController; use App\Http\Controllers\API\PrintedPublicationsController; -use App\Http\Controllers\API\ResearchGuidesController; use App\Http\Controllers\API\SponsorsController; use App\Http\Controllers\API\StaticPagesController; use App\Http\Controllers\API\TagsController; @@ -144,12 +141,6 @@ Route::get('pressreleases', [PressReleasesController::class, 'index']); Route::get('pressreleases/{id}', [PressReleasesController::class, 'show']); - /** - * Research guides ------------------------------------------------------ - */ - Route::get('researchguides', [ResearchGuidesController::class, 'index']); - Route::get('researchguides/{id}', [ResearchGuidesController::class, 'show']); - /** * Educator resources ------------------------------------------------------ */ @@ -190,13 +181,4 @@ Route::options('seamless-images/{id}', [SeamlessImagesController::class, 'byFile']); Route::get('seamless-images/{id}', [SeamlessImagesController::class, 'byFile']); - - /** - * Journal issues and articles -------------------------------------------------------------------- - */ - Route::get('issues', [IssuesController::class, 'index']); - Route::get('issues/{id}', [IssuesController::class, 'show']); - - Route::get('issue-articles', [IssueArticlesController::class, 'index']); - Route::get('issue-articles/{id}', [IssueArticlesController::class, 'show']); }); diff --git a/routes/web.php b/routes/web.php index 1c9fb16b3..23616fb3b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -20,8 +20,6 @@ use App\Http\Controllers\HighlightsController; use App\Http\Controllers\HomeController; use App\Http\Controllers\InteractiveFeatureExperiencesController; -use App\Http\Controllers\IssueController; -use App\Http\Controllers\IssueArticleController; use App\Http\Controllers\MagazineIssueController; use App\Http\Controllers\MiradorController; use App\Http\Controllers\PressReleasesController; @@ -29,7 +27,7 @@ use App\Http\Controllers\PrintedPublicationsController; use App\Http\Controllers\RedirectController; use App\Http\Controllers\ResearchController; -use App\Http\Controllers\ResearchGuidesController; +use App\Http\Controllers\RobotsController; use App\Http\Controllers\SearchController; use App\Http\Controllers\SubscribeController; use App\Http\Controllers\VideoController; @@ -37,7 +35,6 @@ use App\Http\Controllers\VisitController; use App\Http\Controllers\Forms\EducatorAdmissionController; use App\Http\Controllers\Forms\EmailSubscriptionsController; -use App\Http\Controllers\Forms\EventPlanningContactController; use App\Http\Controllers\Forms\FilmingAndPhotoShootProposalController; Route::get('p/{hash}', [PreviewController::class, 'show'])->name('previewLink'); @@ -47,6 +44,7 @@ Route::get('/target', [HomeController::class, 'target'])->name('target'); Route::get('/', [HomeController::class, 'index'])->name('home'); +Route::get('/robots.txt', [RobotsController::class, 'index'])->name('robots-txt'); // Collection routes Route::get('/collection', [CollectionController::class, 'index'])->name('collection'); @@ -73,10 +71,6 @@ // Collection Research Route::get('/collection/research_resources', [ResearchController::class, 'index'])->name('collection.research_resources'); -// Collection Resources - Research Guides -Route::get('/collection/resources/research-guides', [ResearchGuidesController::class, 'index'])->name('collection.resources.research-guides'); -Route::get('/collection/resources/research-guides/{id}', [ResearchGuidesController::class, 'show'])->name('collection.resources.research-guides.show'); - // Collection Resources Educator Resources Route::get('/learn-with-us/educators/tools-for-my-classroom/resource-finder', [EducatorResourcesController::class, 'index'])->name('collection.resources.educator-resources'); Route::get('/collection/resources/educator-resources/{id}', [EducatorResourcesController::class, 'show'])->name('collection.resources.educator-resources.show'); @@ -97,7 +91,7 @@ Route::get('/search/publications', [SearchController::class, 'publications'])->name('search.publications'); Route::get('/search/artworks', [SearchController::class, 'artworks'])->name('search.artworks'); Route::get('/search/press-releases', [SearchController::class, 'pressReleases'])->name('search.press-releases'); -Route::get('/search/research-guides', [SearchController::class, 'researchGuides'])->name('search.research-guides'); +Route::get('/search/educator-resources', [SearchController::class, 'educatorResources'])->name('search.educator-resources'); Route::get('/search/exhibitions', [SearchController::class, 'exhibitions'])->name('search.exhibitions'); Route::get('/search/interactive-features', [SearchController::class, 'interactiveFeatures'])->name('search.interactive-features'); Route::get('/search/highlights', [SearchController::class, 'highlights'])->name('search.highlights'); @@ -115,16 +109,6 @@ Route::get('/articles', [ArticleController::class, 'index'])->name('articles'); Route::get('/articles/{id}/{slug?}', [ArticleController::class, 'show'])->name('articles.show'); -// Journal routes -Route::get('/artinstitutereview', [IssueController::class, 'latest'])->name('issues.latest'); -Route::get('/artinstitutereview/issues/{issueNumber}/{slug?}', [IssueController::class, 'show'])->name('issues.show'); -Route::get('/artinstitutereview/articles/{id}/{slug?}', [IssueArticleController::class, 'show'])->name('issue-articles.show'); - -// PUB-148: Redirect legacy journal URLs via cannonical functionality -Route::get('/journal', [IssueController::class, 'latest'])->name('alt-issues.latest'); -Route::get('/journal/issues/{issueNumber}/{slug?}', [IssueController::class, 'show'])->name('alt-issues.show'); -Route::get('/journal/articles/{id}/{slug?}', [IssueArticleController::class, 'show'])->name('alt-issue-articles.show'); - // Magazine issue routes Route::get('/magazine/issues/{id}/{slug?}', [MagazineIssueController::class, 'show'])->name('magazine-issues.show'); Route::get('/magazine', [MagazineIssueController::class, 'latest'])->name('magazine-issues.latest'); @@ -188,8 +172,8 @@ Route::get('/press/archive', [PressReleasesController::class, 'archive'])->name('about.press.archive'); Route::get('/press/press-releases/{id}/{slug?}', [PressReleasesController::class, 'show'])->name('about.press.show'); -Route::middleware(['httpauth'])->get('/press/exhibition-press-room', [ExhibitionPressRoomController::class, 'index'])->name('about.exhibitionPressRooms'); -Route::middleware(['httpauth'])->get('/press/exhibition-press-room/{id}/{slug?}', [ExhibitionPressRoomController::class, 'show'])->name('about.exhibitionPressRooms.show'); +Route::get('/press/exhibition-press-room', [ExhibitionPressRoomController::class, 'index'])->name('about.exhibitionPressRooms'); +Route::get('/press/exhibition-press-room/{id}/{slug?}', [ExhibitionPressRoomController::class, 'show'])->name('about.exhibitionPressRooms.show'); // Educator admission request Route::get('/educators/visit-on-my-own/educator-admission-request', [EducatorAdmissionController::class, 'index'])->name('forms.educator-admission-request'); @@ -216,15 +200,10 @@ // Digital labels Route::get('/interactive-features', [InteractiveFeatureExperiencesController::class, 'index'])->name('interactiveFeatures'); Route::get('/interactive-features/{slug}', [InteractiveFeatureExperiencesController::class, 'show'])->name('interactiveFeatures.show'); -Route::get('/interactive-features/kiosk/{slug}', [InteractiveFeatureExperiencesController::class, 'show'])->name('interactiveFeatures.showKiosk'); +Route::get('/interactive-features/kiosk/{slug}', [InteractiveFeatureExperiencesController::class, 'show'])->name('interactiveFeatures.show-kiosk'); // Feed routes Route::feeds(); -// Generic Page w/ httpauth -Route::middleware(['httpauth'])->get('/press/art-institute-images', function () { - return App::make(App\Http\Controllers\GenericPagesController::class)->show('/press/art-institute-images'); -})->name('about.press.art-institute-images'); - // Generic Page Route::get('{any}', [GenericPagesController::class, 'show'])->where('any', '.*')->name('genericPages.show'); diff --git a/tests/Feature/ArtworkTest.php b/tests/Feature/ArtworkTest.php new file mode 100644 index 000000000..3c9aee6a6 --- /dev/null +++ b/tests/Feature/ArtworkTest.php @@ -0,0 +1,72 @@ +count(6)->published()->visible()->notUnlisted()->create(); + } + + public function test_artwork_show_redirects_to_canonical_url_when_missing_slug() + { + $artwork = Artwork::factory()->make(); + $this->addMockApiResponses($this->mockApiModelReponse($artwork)); + + $response = $this->get(route('artworks.show', ['id' => $artwork->id])); + $response->assertRedirect(route('artworks.show', ['id' => $artwork->id, 'slug' => $artwork->titleSlug])); + } + + public function test_artwork_show_displays_edition() + { + $artwork = Artwork::factory()->make(); + $this->addMockApiResponses([ + $this->mockApiModelReponse($artwork), + $this->mockApiSearchResponse(), // Multisearch for related artworks + $this->mockApiSearchResponse(), // Search for multimedia resources + $this->mockApiSearchResponse(), // Search for educational resources + ]); + + $response = $this->get(route('artworks.show', ['id' => $artwork->id, 'slug' => $artwork->titleSlug])); + $response->assertStatus(200); + $response->assertSee('Title'); + $response->assertSee($artwork->title); + $response->assertSee('Edition'); + $response->assertSee($artwork->edition); + } + + public function test_artwork_show_retrieves_related_media() + { + $this->markTestSkipped("We're hiding related content entirely using the SHOW_DEFAULT_RELATED_ITEMS feature flag"); + $artwork = Artwork::factory()->make(); + $this->addMockApiResponses([ + $this->mockApiModelReponse($artwork), + $this->mockApiSearchResponse(), // Multisearch for related artworks + $this->mockApiSearchResponse(), // Search for multimedia resources + $this->mockApiSearchResponse(), // Search for educational resources + ]); + + $response = $this->get(route('artworks.show', ['id' => $artwork->id, 'slug' => $artwork->titleSlug])); + $response->assertSee('Discover More'); + $this->assertApiRequestReceived('GET', "/api/v1/artworks/{$artwork->id}"); + $this->assertApiRequestReceived('POST', '/api/v1/msearch'); + $this->assertApiRequestReceived('POST', '/api/v1/search'); + $this->assertApiRequestReceived('POST', '/api/v1/search'); + $this->assertApiRequestCount(4, 'artworks.show requires four requests to the API'); + } +} diff --git a/tests/Feature/EventTest.php b/tests/Feature/EventTest.php index 24fe56714..b00b33aab 100644 --- a/tests/Feature/EventTest.php +++ b/tests/Feature/EventTest.php @@ -3,7 +3,6 @@ namespace Tests\Feature; use Aic\Hub\Foundation\Testing\FeatureTestCase as BaseTestCase; - use App\Models\Event; use App\Models\EventMeta; use App\Models\EventProgram; @@ -14,7 +13,7 @@ class EventTest extends BaseTestCase public function test_event_page_displays_events() { - $response = $this->get('/events'); + $response = $this->get(route('events')); $response->assertSee(Event::get()->pluck('title_display')->all()); } @@ -27,7 +26,7 @@ public function test_event_page_loads_events_by_program() $event->save(); }); - $response = $this->get("/events?program=$eventProgram->id"); + $response = $this->get(route('events', ['program' => $eventProgram->id])); $response->assertStatus(200); @@ -61,6 +60,6 @@ public function test_next_occurrence() 'date_end' => now()->addDay(), ]); $event->eventMetas()->save($futureEvent); - $this->assertNotNull($event->nextOccurrence, "The next occurrence must end in the future"); + $this->assertNotNull($event->nextOccurrence, "The next occurrence must end in the future"); } } diff --git a/tests/Feature/GeneratePdfsTest.php b/tests/Feature/GeneratePdfsTest.php index 949e3b599..bda4cb8d5 100644 --- a/tests/Feature/GeneratePdfsTest.php +++ b/tests/Feature/GeneratePdfsTest.php @@ -44,13 +44,6 @@ public function test_generate_one_command_successful() ->expectsOutput("Generated PDF for DigitalPublicationSection with ID {$this->sections->first()->id}"); } - public function test_errors_when_prince_binary_not_present() - { - $noPrinceCommand = '/dev/null'; - Config::set('aic.prince_command', $noPrinceCommand); - $this->artisan('pdfs:generate')->assertFailed()->expectsOutput("Prince could not be found at $noPrinceCommand"); - } - public function test_pdf_download_path_updated() { $this->assertNull($this->sections->first()->pdf_download_path); @@ -59,7 +52,7 @@ public function test_pdf_download_path_updated() 'id' => $this->sections->first()->id, ]); $this->sections->first()->refresh(); - $downloadPath = GeneratePdfs::pdfDownloadPath(GeneratePdfs::pdfFileName($this->sections->first())); + $downloadPath = GeneratePdfs::downloadPath(GeneratePdfs::fileName($this->sections->first())); $this->assertEquals($downloadPath, $this->sections->first()->pdf_download_path); } @@ -71,7 +64,10 @@ public function test_pdf_uploaded() 'model' => DigitalPublicationSection::class, 'id' => $this->sections->first()->id, ]); - $downloadPath = GeneratePdfs::pdfDownloadPath(GeneratePdfs::pdfFileName($this->sections->first())); + $fileName = GeneratePdfs::fileName($this->sections->first()); + $localPath = GeneratePdfs::localPath($fileName); + Storage::disk('local')->assertMissing($localPath); + $downloadPath = GeneratePdfs::downloadPath($fileName); Storage::disk('pdf_s3')->assertExists($downloadPath); } } diff --git a/tests/Feature/HomePageTest.php b/tests/Feature/HomePageTest.php index 38498ab6c..e166891fd 100644 --- a/tests/Feature/HomePageTest.php +++ b/tests/Feature/HomePageTest.php @@ -15,14 +15,14 @@ class HomePageTest extends BaseTestCase public function test_home_page_loads() { - $response = $this->get('/'); + $response = $this->get(route('home')); $response->assertStatus(200); } public function test_visit_page_links_appear_on_home_page() { $appUrl = config('APP_URL'); - $response = $this->get('/'); + $response = $this->get(route('home')); $response->assertSee('Hours and admission fees'); $response->assertSee("href=\"{$appUrl}/visit#hours\"", false); $response->assertSee('Directions and parking'); @@ -31,7 +31,7 @@ public function test_visit_page_links_appear_on_home_page() public function test_events_section_appears_on_home_page() { - $response = $this->get('/'); + $response = $this->get(route('home')); $response->assertSee('Events'); $response->assertSee('See upcoming events'); } @@ -47,18 +47,18 @@ public function test_events_appear_on_home_page() $this->assertDatabaseCount('events', 5); $events = Event::get(); - $response = $this->get('/'); + $response = $this->get(route('home')); $response->assertSee($events->take(4)->pluck('title_display')->all(), 'Home page displays first four events'); $response->assertDontSee($events->last()->title_display, 'Home page displays only the first four events'); } public function test_events_times_appear_on_home_page() { - $response = $this->get('/'); + $response = $this->get(route('home')); $forcedFormattedDates = Event::whereNotNull('forced_date')->get()->pluck('forced_date')->all(); $response->assertSee($forcedFormattedDates, 'Home page displays forced formatted dates as they are'); - $dynamicallyFormattedDates = Event::whereNull('forced_date')->get()->map(function($event) { + $dynamicallyFormattedDates = Event::whereNull('forced_date')->get()->map(function ($event) { return $event->nextOccurrence->date->format('l, F j'); // [weekday], [month] [day of month] })->all(); $response->assertSee($dynamicallyFormattedDates, 'Home page displays dynamically formatted dates'); diff --git a/tests/Feature/PrinceTest.php b/tests/Feature/PrinceTest.php new file mode 100644 index 000000000..4eaac38b4 --- /dev/null +++ b/tests/Feature/PrinceTest.php @@ -0,0 +1,45 @@ +sections = DigitalPublicationSection::factory() + ->count(2) + ->published() + ->for(DigitalPublication::factory()->published()) + ->create(); + } + + public function test_errors_when_prince_binary_not_present() + { + Http::fake(); + $noPrinceCommand = '/dev/null'; + Config::set('aic.prince_command', $noPrinceCommand); + $this->artisan('pdfs:generate')->assertFailed()->expectsOutput("Prince could not be found at $noPrinceCommand"); + } + + public function test_errors_when_prince_cannot_generate_pdf() + { + Http::fake(['*' => Http::response('')]); + $id = $this->sections->first()->id; + $this->artisan('pdfs:generate-one', [ + 'model' => DigitalPublicationSection::class, + 'id' => $id, + ]) + ->assertFailed() + ->expectsOutput("Prince was unable to generate a PDF for DigitalPublicationSection with ID {$id}"); + } +} diff --git a/tests/Feature/RobotsTxtTest.php b/tests/Feature/RobotsTxtTest.php new file mode 100644 index 000000000..8aa9fde1a --- /dev/null +++ b/tests/Feature/RobotsTxtTest.php @@ -0,0 +1,40 @@ +get(route('robots-txt')); + $response->assertStatus(200); + } + + public function test_blocks_all_traffic_when_not_production() + { + Config::set('app.env', 'testing'); + $response = $this->get(route('robots-txt')); + $this->assertEquals("User-agent: *\nDisallow: /", $response->getContent()); + } + + public function test_blocks_all_traffic_when_production_but_different_domain() + { + Config::set('app.env', 'production'); + Config::set('app.debug', false); + Config::set('app.url', 'www.example.com'); + $response = $this->get(route('robots-txt')); + $this->assertEquals("User-agent: *\nDisallow: /", $response->getContent()); + } + + public function test_allow_traffic_when_production_request_to_same_host() + { + Config::set('app.env', 'production'); + Config::set('app.debug', false); + Config::set('app.url', 'localhost'); + $response = $this->get(route('robots-txt')); + $this->assertNotEquals("User-agent: *\nDisallow: /", $response->getContent()); + } +} diff --git a/tests/Feature/VisitPageTest.php b/tests/Feature/VisitPageTest.php index 0bc94a658..580373e5a 100644 --- a/tests/Feature/VisitPageTest.php +++ b/tests/Feature/VisitPageTest.php @@ -18,7 +18,7 @@ public function setUp(): void public function test_visiting_hours_are_displayed() { - $response = $this->get('/visit'); + $response = $this->get(route('visit')); $response->assertSee( 'The Art Institute reopens on July 30, and we’re so happy to welcome you back to our galleries. Please see below for new hours—including member-only hours—and updated safety policies.', false @@ -29,7 +29,7 @@ public function test_visiting_hours_are_displayed() public function test_admission_description_is_displayed() { - $response = $this->get('/visit'); + $response = $this->get(route('visit')); $response->assertSee( 'The Art Institute of Chicago provides free access to children under 14, Chicago teens under 18, Link and WIC cardholders, and Illinois educators every day, and to Illinois residents on certain days throughout the year.' ); @@ -37,7 +37,7 @@ public function test_admission_description_is_displayed() public function test_accessibility_link_is_displayed() { - $response = $this->get('/visit'); + $response = $this->get(route('visit')); $response->assertSee( 'The Art Institute of Chicago welcomes all visitors and is committed to making its services accessible to everyone. We offer a range of resources for both adults and children with disabilities.' ); @@ -47,7 +47,7 @@ public function test_accessibility_link_is_displayed() public function test_family_pages_titles_are_displayed_in_order() { - $response = $this->get('/visit'); + $response = $this->get(route('visit')); $response->assertSeeInOrder([ 'Art Institute Mobile App', 'What to See in an Hour', @@ -57,7 +57,7 @@ public function test_family_pages_titles_are_displayed_in_order() public function test_mobile_app_family_page_link_is_displayed() { - $response = $this->get('/visit'); + $response = $this->get(route('visit')); $response->assertSee( 'The Art Institute’s free app offers the stories behind the art through conversations with artists, experts, and community members. Download it via the App Store or Google Play.', false @@ -68,7 +68,7 @@ public function test_mobile_app_family_page_link_is_displayed() public function test_highlights_family_page_link_is_displayed() { - $response = $this->get('/visit'); + $response = $this->get(route('visit')); $response->assertSee('Short on time? Check out this must-see guide to the collection.'); $response->assertSee('More custom tours'); $response->assertSee("href=\"{$this->appUrl}/highlights\"", false); @@ -76,7 +76,7 @@ public function test_highlights_family_page_link_is_displayed() public function test_visit_virtually_family_page_link_is_displayed() { - $response = $this->get('/visit'); + $response = $this->get(route('visit')); $response->assertSee('Even from afar, there’s a host of ways to connect to our collection of art from around the world—whether you’re seeking inspiration, community, or a little adventure.', false); $response->assertSee('Learn more'); $response->assertSee("href=\"{$this->appUrl}/visit-us-virtually\"", false); @@ -84,7 +84,7 @@ public function test_visit_virtually_family_page_link_is_displayed() public function test_what_to_expect_items_are_displayed_in_order() { - $response = $this->get('/visit'); + $response = $this->get(route('visit')); $response->assertSeeInOrder([ 'Face coverings will be required for your entire museum visit.', 'Maintain a physical distance of six-feet from staff and visitors.', @@ -97,5 +97,4 @@ public function test_what_to_expect_items_are_displayed_in_order() 'Special exhibitions may use timed queueing systems. Check in at exhibition entrances to reserve your spot in line.', ]); } -// } diff --git a/tests/MockApi.php b/tests/MockApi.php new file mode 100644 index 000000000..a5d1febc8 --- /dev/null +++ b/tests/MockApi.php @@ -0,0 +1,128 @@ +transactions = array(); + $this->mockApi = new MockHandler(); + $handler = HandlerStack::create($this->mockApi); + $handler->push(Middleware::history($this->transactions)); + $this->instance('ApiClient', new GuzzleApiConsumer(['handler' => $handler])); + } + + /** + * Generate a mock API response based on the given model. + */ + public function mockApiModelReponse(ApiModel $model, int $statusCode = 200, array $headers = []): Response + { + return new Response($statusCode, $headers, json_encode(['data' => $model->toArray()])); + } + + /** + * Generate a mock API search response. + * + * TODO: Allow for passing in models to return as the search results. + */ + public function mockApiSearchResponse(int $statusCode = 200, array $headers = []): Response + { + return new Response($statusCode, $headers, $this->searchBody); + } + + /** + * Add mocked API responses to the queue. + * + * When the mock API receives a request, it will respond with the next + * response from the queue until the queue is empty. + */ + public function addMockApiResponses(array|Response $responses): void + { + if ($responses instanceof Response) { + $responses = [$responses]; + } + $this->mockApi->append(...$responses); + } + + /** + * Assert the mock API received the expected number of requests. + */ + public function assertApiRequestCount(int $expected, ?string $message = null): void + { + $this->assertCount( + $expected, + $this->transactions, + $message ?: 'The API did not receive the expected number of requests', + ); + } + + /** + * Assert the mock API received a request with the expected method and uri. + */ + public function assertApiRequestReceived(string $method, string $uri, ?string $message = null): void + { + $transactionsContainRequest = collect($this->transactions) + ->pluck('request') + ->contains(function ($request, $_) use ($method, $uri) { + return strtoupper($method) == $request->getMethod() && $uri == $request->getUri()->getPath(); + }); + $message = $message ?: "The API did not receive the request {$method} {$uri}"; + $this->assertTrue($transactionsContainRequest, $message); + } +} diff --git a/tests/Unit/IssueArticleTest.php b/tests/Unit/IssueArticleTest.php deleted file mode 100644 index 3ecbffc4c..000000000 --- a/tests/Unit/IssueArticleTest.php +++ /dev/null @@ -1,36 +0,0 @@ -make([ - 'published' => false, - 'title' => 'Unpublished test', - ]); - - $issueArticle = IssueArticle::factory()->make([ - 'publish_start_date' => Carbon::yesterday(), - 'title' => 'Published test', - 'issue_id' => $issue->id, - ]); - - $this->assertFalse($issueArticle->published); - - $issue->delete(); - $issueArticle->delete(); - } -}