]> _ Git - fluidbook-toolbox.git/commitdiff
wip #5718 @1
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 15 Feb 2023 18:36:06 +0000 (19:36 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 15 Feb 2023 18:36:06 +0000 (19:36 +0100)
app/Http/Controllers/Admin/Operations/Files/DownloadOperation.php [new file with mode: 0644]
app/Models/File.php
composer.json
composer.lock
public/images/ios/512.png [new file with mode: 0644]
public/images/ios/57.png [new file with mode: 0644]
resources/views/vendor/backpack/crud/buttons/files/download.blade.php [new file with mode: 0644]
resources/views/vendor/backpack/crud/buttons/files/install.blade.php [new file with mode: 0644]

diff --git a/app/Http/Controllers/Admin/Operations/Files/DownloadOperation.php b/app/Http/Controllers/Admin/Operations/Files/DownloadOperation.php
new file mode 100644 (file)
index 0000000..8c60980
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+
+namespace App\Http\Controllers\Admin\Operations\Files;
+
+use App\Http\Middleware\CheckIfAdmin;
+use App\Models\File;
+use CFPropertyList\CFPropertyList;
+use CFPropertyList\IOException;
+use Cubist\Backpack\Http\Controllers\Base\XSendFileController;
+use Cubist\Util\Files\Files;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\Route;
+use ZipArchive;
+
+trait DownloadOperation
+{
+    protected function setupDownloadRoutes($segment, $routeName, $controller)
+    {
+        Route::match(['get'], $segment . '/{hash}/install', $controller . '@manifestIpa')->withoutMiddleware([CheckIfAdmin::class]);
+        Route::match(['get'], $segment . '/{hash}/{file}', $controller . '@download')->withoutMiddleware([CheckIfAdmin::class]);
+
+    }
+
+    protected function setupDownloadDefaults()
+    {
+        $this->crud->addButtonFromView('line', 'install', 'files.install', 'end');
+        $this->crud->addButtonFromView('line', 'download', 'files.download', 'end');
+    }
+
+    protected function download($hash, $name)
+    {
+        $file = File::where('hash', $hash)->where('name', $name)->first();
+        if ($file === null) {
+            abort(404);
+        }
+        return XSendFileController::sendfile($file->path);
+    }
+
+    /**
+     * @throws IOException
+     */
+    protected function manifestIpa($hash)
+    {
+        $file = File::where('hash', $hash)->first();
+        if ($file === null) {
+            abort(404);
+        }
+
+        $xml = Cache::rememberForever('ipamanifest_' . $hash, function () use ($file) {
+            $ipa = $file->path;
+
+            $zip = new ZipArchive();
+            $zip->open($ipa);
+            for ($i = 0; $i < $zip->numFiles; $i++) {
+                $filename = $zip->getNameIndex($i);
+                if (preg_match('|Payload/(.+).app/Info.plist|', $filename, $matches)) {
+                    $idx = $i;
+                    break;
+                }
+            }
+            if (!$idx) {
+                return;
+            }
+
+            $tmp = Files::tempnam();
+            file_put_contents($tmp, $zip->getFromIndex($idx));
+
+            $plist = new CFPropertyList($tmp);
+
+            $infos = $plist->toArray();
+            $bundle = $infos['CFBundleIdentifier'];
+            $appName = $infos['CFBundleDisplayName'];
+            $version = $infos['CFBundleVersion'];
+
+            return '<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>items</key>
+       <array>
+               <dict>
+                       <key>assets</key>
+                       <array>
+                               <dict>
+                                       <key>kind</key>
+                                       <string>software-package</string>
+                                       <key>url</key>
+                                       <string>' . $file->getURL() . '</string>
+                               </dict>
+                               <dict>
+                                       <key>kind</key>
+                                       <string>display-image</string>
+                                       <key>url</key>
+                                       <string>https://toolbox.fluidbook.com/images/ios/57.png</string>
+                               </dict>
+                               <dict>
+                                       <key>kind</key>
+                                       <string>full-size-image</string>
+                                       <key>url</key>
+                                       <string>https://toolbox.fluidbook.com/images/ios/57.png</string>
+                               </dict>
+                       </array>
+                       <key>metadata</key>
+                       <dict>
+                               <key>bundle-identifier</key>
+                               <string>' . $bundle . '</string>
+                               <key>bundle-version</key>
+                               <string>' . $version . '</string>
+                               <key>kind</key>
+                               <string>software</string>
+                               <key>title</key>
+                               <string>' . $appName . '</string>
+                       </dict>
+               </dict>
+       </array>
+</dict>
+</plist>';
+        });
+
+
+        return response($xml, 200, ['Content-type' => 'application/xml']);
+
+
+    }
+
+}
+
index 6e8b8934a3bce1cf3a1fbc95be60e0a234cd878c..1df51800f7564dba91431f4a13f394f7370aa6d4 100644 (file)
@@ -2,7 +2,9 @@
 
 namespace App\Models;
 
+use App\Http\Controllers\Admin\Operations\Files\DownloadOperation;
 use App\Models\Base\ToolboxModel;
+use Cubist\Backpack\CubistBackpackServiceProvider;
 use Cubist\Backpack\Magic\Fields\Date;
 use Cubist\Backpack\Magic\Fields\Hidden;
 use Cubist\Backpack\Magic\Fields\Integer;
@@ -24,24 +26,33 @@ class File extends ToolboxModel
 
     protected static $_permissionBase = 'files';
 
+    protected $_enableEdition = false;
+    protected $_enableClone = false;
+
+    protected $primaryKey = 'hash';
+    public $incrementing = false;
+    protected $keyType = 'string';
+
+
+    protected $_operations = [DownloadOperation::class];
+
     public function setFields()
     {
         parent::setFields();
 
+        //$this->addField('hash', Text::class, __('Hash'), ['column' => false, 'database_index' => true]);
         $this->addField('name', Text::class, __('Nom du fichier'), ['column' => true]);
         $this->addField('path', Hidden::class, __('Chemin'));
         $this->addField('ext', Text::class, __('Type'), ['column' => true]);
         $this->addField('updated_at', Date::class, __('Date'), ['column' => true]);
-        $this->addField('size', Integer::class, __('Taille'), ['column' => true]);
+        $this->addField('size', Integer::class, __('Taille'), ['column' => true, 'column_type' => 'filesize', 'column_view_namespace' => CubistBackpackServiceProvider::NAMESPACE . '::columns']);
         $this->addField('from', \App\Fields\User::class, __('Envoyé par'), ['column' => true]);
         $this->addField('to', \App\Fields\User::class, __('Destiné à'), ['column' => true]);
-        $this->addField('hash', Hidden::class, __('Hash'));
         $this->addField('mtime', Hidden::class, '');
-
         $this->addOwnerField(['column' => false]);
     }
 
-    protected function getData()
+    protected function _getData()
     {
         /** @var User $user */
         $users = User::withoutGlobalScopes()->get();
@@ -49,10 +60,7 @@ class File extends ToolboxModel
         foreach ($users as $user) {
             $this->_listFilesOfUser($user->id, $files);
         }
-        usort($files, function ($a, $b) {
-            return $a['mtime'] - $b['mtime'];
-        });
-        return array_values($files);
+        return $files;
     }
 
     protected function _listFilesOfUser($id, &$files)
@@ -61,11 +69,11 @@ class File extends ToolboxModel
             return $this->___listFilesOfUser($id);
         });
 
-        foreach ($uFiles as $path => $uFile) {
-            if (isset($files[$path])) {
+        foreach ($uFiles as $hash => $uFile) {
+            if (isset($files[$hash])) {
                 continue;
             }
-            $files[$path] = $uFile;
+            $files[$hash] = $uFile;
         }
     }
 
@@ -101,8 +109,9 @@ class File extends ToolboxModel
 
             $date = new \DateTime();
             $date->setTimestamp($mtime);
+            $hash = Files::hashFileAttributes($pathname);
 
-            $res[$pathname] = [
+            $res[$hash] = [
                 'path' => $pathname,
                 'name' => $file->getFilename(),
                 'ext' => mb_strtolower($file->getExtension()),
@@ -113,13 +122,18 @@ class File extends ToolboxModel
                 'to' => $to,
                 'owner' => $id,
                 'mtime' => $mtime,
-                'hash' => Files::hashFileAttributes($pathname),
+                'hash' => $hash,
             ];
         }
 
         return $res;
     }
 
+    public function showPrimaryColumn()
+    {
+        return false;
+    }
+
     public static function addOwnerClause(Builder $builder)
     {
 
@@ -134,4 +148,9 @@ class File extends ToolboxModel
         }
         $builder->whereIn(static::$_ownerAttribute, backpack_user()->getManagedUsers());
     }
+
+    public function getURL()
+    {
+        return config('url', 'https://toolbox.fluidbook.com') . '/file/' . $this->hash . '/' . $this->name;
+    }
 }
index 1b1f007971d8b2061af0469a275f08b5a91bb008..7b3c9bf6ee8fb55115a1c618411694ff8b920d0c 100644 (file)
         "mxl/laravel-job": "^1.3",
         "nyholm/psr7": "^1.5",
         "php-ffmpeg/php-ffmpeg": "^0.18.0",
+        "rodneyrehm/plist": "^2.0",
         "rustici-software/scormcloud-api-v2-client-php": "^2.0",
         "symfony/http-client": "^v6.0"
     },
     "require-dev": {
         "facade/ignition": "^2.17",
-        "fzaninotto/faker": "^1.9",
         "mockery/mockery": "^1.5",
         "nunomaduro/collision": "^4.3",
         "phpunit/phpunit": "^8.5",
     "config": {
         "optimize-autoloader": true,
         "preferred-install": "dist",
-        "sort-packages": true
+        "sort-packages": true,
+        "allow-plugins": {
+            "php-http/discovery": true
+        }
     },
     "extra": {
         "laravel": {
index 49ba241da7a7c2050b437202aa9a340d356672d6..237ff04dea9257968722df89972c475ab5bd48b4 100644 (file)
@@ -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": "3841d2420cde41846464f40adf52e325",
+    "content-hash": "9e1d830868759266a700df2a00576cf8",
     "packages": [
         {
             "name": "ahmadshah/lucy",
             "source": {
                 "type": "git",
                 "url": "git://git.cubedesigners.com/cubist_cms-back.git",
-                "reference": "3cbabfd839e1ee1449dfe53050e2f5537d0dd7fd"
+                "reference": "541015ec6f5b6838d5ac59fbfef12aac086311e7"
             },
             "dist": {
                 "type": "tar",
-                "url": "https://composer.cubedesigners.com/dist/cubist/cms-back/cubist-cms-back-dev-master-37b21b.tar",
-                "reference": "3cbabfd839e1ee1449dfe53050e2f5537d0dd7fd",
-                "shasum": "a5d02527b1621e284024d141f3d71634cd90d7fb"
+                "url": "https://composer.cubedesigners.com/dist/cubist/cms-back/cubist-cms-back-dev-master-0f74fc.tar",
+                "reference": "541015ec6f5b6838d5ac59fbfef12aac086311e7",
+                "shasum": "3adce0eeb2370518325f7ca2ab03f99d6d724267"
             },
             "require": {
                 "backpack/backupmanager": "^3.0",
                 }
             ],
             "description": "Cubist Backpack extension",
-            "time": "2023-02-15T09:41:45+00:00"
+            "time": "2023-02-15T15:17:43+00:00"
         },
         {
             "name": "cubist/cms-front",
             ],
             "time": "2022-02-11T10:27:51+00:00"
         },
+        {
+            "name": "rodneyrehm/plist",
+            "version": "v2.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/TECLIB/CFPropertyList.git",
+                "reference": "eb1f97cc44427359be9f09e617d68eef57707617"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/TECLIB/CFPropertyList/zipball/eb1f97cc44427359be9f09e617d68eef57707617",
+                "reference": "eb1f97cc44427359be9f09e617d68eef57707617",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-libxml": "*",
+                "php": "^7.4 || ^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.0",
+                "squizlabs/php_codesniffer": "^3.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "CFPropertyList\\": "src/CFPropertyList/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Christian Kruse",
+                    "email": "cjk@wwwtech.de",
+                    "role": "developer"
+                },
+                {
+                    "name": "Rodney Rehm",
+                    "email": "mail+github@rodneyrehm.de",
+                    "role": "developer"
+                },
+                {
+                    "name": "Thierry Bugier",
+                    "email": "tbugier@teclib.com",
+                    "role": "developer"
+                }
+            ],
+            "description": "Library for reading and writing Apple's CFPropertyList (plist) files in XML as well as binary format.",
+            "homepage": "https://github.com/TECLIB/CFPropertyList",
+            "keywords": [
+                "CFPropertyList",
+                "Core Foundation",
+                "apple",
+                "binary",
+                "plist",
+                "xml"
+            ],
+            "support": {
+                "docs": "http://teclib.github.io/CFPropertyList/howtos/",
+                "email": "contact@teclib.com",
+                "issues": "https://github.com/TECLIB/CFPropertyList/issues",
+                "rss": "https://teclib.github.io/CFPropertyList/feed.xml",
+                "source": "https://github.com/TECLIB/CFPropertyList"
+            },
+            "time": "2021-12-01T18:24:28+00:00"
+        },
         {
             "name": "rustici-software/scormcloud-api-v2-client-php",
             "version": "2.1.0",
             ],
             "time": "2022-11-02T16:23:29+00:00"
         },
-        {
-            "name": "fzaninotto/faker",
-            "version": "v1.9.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/fzaninotto/Faker.git",
-                "reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/848d8125239d7dbf8ab25cb7f054f1a630e68c2e",
-                "reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^5.3.3 || ^7.0"
-            },
-            "require-dev": {
-                "ext-intl": "*",
-                "phpunit/phpunit": "^4.8.35 || ^5.7",
-                "squizlabs/php_codesniffer": "^2.9.2"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.9-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Faker\\": "src/Faker/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "François Zaninotto"
-                }
-            ],
-            "description": "Faker is a PHP library that generates fake data for you.",
-            "keywords": [
-                "data",
-                "faker",
-                "fixtures"
-            ],
-            "support": {
-                "issues": "https://github.com/fzaninotto/Faker/issues",
-                "source": "https://github.com/fzaninotto/Faker/tree/v1.9.2"
-            },
-            "abandoned": true,
-            "time": "2020-12-11T09:56:16+00:00"
-        },
         {
             "name": "hamcrest/hamcrest-php",
             "version": "v2.0.1",
diff --git a/public/images/ios/512.png b/public/images/ios/512.png
new file mode 100644 (file)
index 0000000..197673e
Binary files /dev/null and b/public/images/ios/512.png differ
diff --git a/public/images/ios/57.png b/public/images/ios/57.png
new file mode 100644 (file)
index 0000000..77cbba4
Binary files /dev/null and b/public/images/ios/57.png differ
diff --git a/resources/views/vendor/backpack/crud/buttons/files/download.blade.php b/resources/views/vendor/backpack/crud/buttons/files/download.blade.php
new file mode 100644 (file)
index 0000000..9ae23d7
--- /dev/null
@@ -0,0 +1,2 @@
+<a class="btn btn-sm btn-link" download="{{$entry->name}}" href="{{$entry->getURL()}}"><i
+        class="la la-arrow-circle-down"></i> {{__('Télécharger')}}</a>
diff --git a/resources/views/vendor/backpack/crud/buttons/files/install.blade.php b/resources/views/vendor/backpack/crud/buttons/files/install.blade.php
new file mode 100644 (file)
index 0000000..3533677
--- /dev/null
@@ -0,0 +1,8 @@
+@if($entry->ext==='apk')
+    <a class="btn btn-sm btn-link" download="{{$entry->name}}"
+       href="{{$entry->getURL()}}"><i class="las la-mobile"></i> {{__('Installer')}}</a>
+@elseif($entry->ext==='ipa')
+    <a class="btn btn-sm btn-link"
+       href="itms-services://?action=download-manifest&url={{urlencode($crud->route.'/'.$entry->hash.'/install')}}"><i
+            class="las la-mobile"></i> {{__('Installer')}}</a>
+@endif