Integracja z zapleczem cakephp w celu dołączania obrazków
Zakładamy że lokalizacja zdjęć będzie zależała od 3 parametrów: brand_id, course_id, lesson_id. Struktura katalogu jest następująca:
/var/www/<projekt>/webroot/files/brand/<brand_id>/course/<course_id>/lesson/<lesson_id>/
Ta struktura jest tworzona przez akcję 'add’ cakePHP w czasie tworzenia nowych obiektów, aby była dostępna w momencie wgrywania zdjęcia. Po stronie JS przekazujemy te parametry w atrybutach data-*
Plik konfiguracyjny /js/tinymce-config.js
let course_id = $('#model').data('course-id'); let lesson_id = $('#model').data('lesson-id'); let brand_id = $('#model').data('brand-id'); let course_url = ''; let lesson_urs = ''; if(brand_id) { brand_id = brand_id ? parseInt(brand_id) : null; brand_url = '/brand/' + brand_id; if(course_id) { course_id = course_id ? parseInt(course_id) : null; course_url = '/' + course_id; if(lesson_id) { lesson_id = course_id ? parseInt(lesson_id) : null; lesson_url = '/' + lesson_id; } } } let base_path = '/files/brand/' + brand_id + '/course/' + course_id + '/lesson/' + lesson_id; let upload_url = '/panel/lessons/uploadFile' + course_url + lesson_url + '.json'; tinymce.init({ selector :'textarea.editor', images_upload_url: upload_url, images_upload_base_path: base_path, images_upload_credentials: true, ...... pozostałe opcje ... }
Akcja wgrania pliku dla (course_id=2, lesson_id=1). brand_id – po stronie serwera (zalogowany user).
/panel/lessons/uploadFile/2/31.json
public function uploadFile($course_id=null, $lesson_id=null) { $response = ['message' => 'Nie weszło w pętlę AJAX']; if( $this->request->is('json') ) { if( is_uploaded_file( $this->getRequest()->getData('file') ['tmp_name']) ) { $filename = $this->getRequest()->getData('file')['name']; $tmp_name = $this->getRequest()->getData('file')['tmp_name']; // Sprawdzenie nazwy if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $filename)) { header("HTTP/1.1 400 Invalid file name."); return; } // Sprawdzenie rozszerzenia if (!in_array(strtolower(pathinfo($filename, PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) { header("HTTP/1.1 400 Invalid extension."); return; } if( $course_id && $lesson_id && $filename ) { // Sprawdza czy jest taka lekcja i kurs i należą do marki $lesson = $this->Lessons->get($lesson_id, [ 'conditions' => [ 'brand_id' => $this->Auth->user('brand_id'), 'course_id' => $course_id ] ]); if( $lesson ) { $this->loadComponent('CourseDir'); $path = $this->CourseDir->composePath($lesson->brand_id, $lesson->course_id, $lesson->id); $subdir = $course_id .DS. $lesson_id .DS. $filename; if( move_uploaded_file( $tmp_name, $path .DS. $filename ) ) { $response = ['location' => $filename]; } else { $response = ['message' => 'Nie udało się wgrać pliku']; } } else { $response = ['message' => 'Błędny id lekcji']; } } // Nie przekazano lekcji i kursu - zapisz do worka ../courses/slidesall/ // Czy chcemy wrzucać takie niedopasowane do lekcji pliki ????? else { $path = 'slidesall'.DS. $filename; if( move_uploaded_file( $tmp_name, $path ) ) { $response = ['location' => $filename]; } else { $response = ['message' => 'Nie udało się wgrać pliku']; } } } else { // Info do edytora że upload pliku nie powiódł się header("HTTP/1.1 500 Server Error"); } } $this->set('response', $response); $this->set('_serialize', 'response'); }
Komponent obsługujący tworzenie ścieżek: /Controller/Component/CourseDirComponent.php
class CourseDirComponent extends Component { protected $_defaultConfig = []; public function composePath($brand_id = null, $course_id=null, $lesson_id=null) { if($brand_id) { //'BRAND_DIR' => WWW_ROOT.'files/brand/' $path = Folder::addPathElement(BRAND_DIR, [$brand_id]); if($course_id) { $path = Folder::addPathElement($path, ['course', $course_id]); if($lesson_id) { $path = Folder::addPathElement($path, ['lesson', $lesson_id]); } } return $path; } return false; } public function create($brand_id = null, $course_id=null, $lesson_id=null) { $path = $this->composePath($brand_id, $course_id, $lesson_id); if($path) { $dir = new Folder($path); if(!$dir->inPath(BRAND_DIR)) { $dir->create($path); } return $path; } return false; } public function remove($brand_id = null, $course_id=null, $lesson_id=null) { $path = $this->composePath($brand_id, $course_id, $lesson_id); if($path) { $dir = new Folder($path); if($dir->inPath(BRAND_DIR)) { $dir->delete($path); return 'Katalog '. $path .' usunięty'; } return 'Nie usunięto katalogu '. $path; } return false; } }
Użycie komponentu w akcji ADD – dodającej kurs (/courses/add)
public function add() { if ($this->Courses->save($course)) { $this->loadComponent('CourseDir'); $info = $this->CourseDir->create( $course->brand_id, $course->id ); $this->Flash->success(__('Kurs dodany. '. $info)); return $this->redirect(['action' => 'index']); } ..... } }