diff --git a/admin/event-edit.php b/admin/event-edit.php index 86f3259..466c3bf 100644 --- a/admin/event-edit.php +++ b/admin/event-edit.php @@ -1,666 +1,703 @@ <?php # Linux Day Torino website # Copyright (C) 2016, 2017, 2018, 2019, 2020 Valerio Bozzolan, Linux Day Torino # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. /* * Event edit * * From this page you can create/edit an User and assign some skills/interests etc. */ // load configurations and framework require 'load.php'; // inherit the Conference or specify one $conference_uid = $_GET['conference_uid'] ?? $_POST['conference_uid'] ?? CURRENT_CONFERENCE_UID; // check if the Conference exists $conference = ( new QueryConference() ) ->whereConferenceUID( $conference_uid ) ->queryRow(); // no Conference no party if( !$conference ) { error( "missing conference with UID $conferene_uid" ); die_with_404(); } // retrieve the Event (if existing) $event = null; if( isset( $_GET['id'] ) ) { // no Event no party $event = ( new QueryEvent() ) ->whereConference( $conference ) ->joinConference() ->joinChapter( 'LEFT' ) ->whereEventID( $_GET['id'] ) ->queryRow(); // no Event no party if( !$event ) { die_with_404(); } // no editable no party if( !$event->isEventEditable() ) { missing_privileges(); } } else { // check if there are permissions to add event if( !has_permission( 'add-event' ) ) { missing_privileges(); } } $warning = null; // check if the user submitted a form // check which one if( $_POST ) { // the user is submitting the save form if( is_action( 'save-event' ) ) { $conference_ID = $conference->getConferenceID(); $data = []; $data[] = new DBCol( Event::TITLE, $_POST['title'], 's' ); $data[] = new DBCol( Event::UID, $_POST['uid'], 's' ); $data[] = new DBCol( Event::LANGUAGE, $_POST['language'], 's' ); $data[] = new DBCol( Event::SUBTITLE, $_POST['subtitle'], 's' ); $data[] = new DBCol( Event::START, $_POST['start'], 's' ); $data[] = new DBCol( Event::END, $_POST['end'], 's' ); $data[] = new DBCol( Event::EXTERNAL_URL,$_POST['url'], 's' ); $data[] = new DBCol( Event::ABORTED, $_POST['aborted'], 'd' ); $data[] = new DBCol( Event::IMAGE, $_POST['image'], 'snull' ); $data[] = new DBCol( Chapter::ID, $_POST['chapter'], 'd' ); $data[] = new DBCol( Room::ID, $_POST['room'], 'd' ); $data[] = new DBCol( Track::ID, $_POST['track'], 'd' ); $data[] = new DBCol( Conference::ID, $conference_ID, 'd' ); // for each language save the fields foreach( all_languages() as $lang ) { foreach( Event::fields_i18n() as $i18n_column => $label ) { // generic column name in this language $field = $i18n_column . '_' . $lang->getISO(); // sent column value $value = $_POST[ $field ] ?? null; // prepare to be saved $data[] = new DBCol( $field, $value, 'snull' ); } } // convert empty strings to NULL, if possible foreach( $data as $row ) { $row->promoteNULL(); } if( $event ) { // update the existing Event ( new QueryEvent() ) ->whereEvent( $event ) ->update( $data ); } else { // insert a new Event Event::factory() ->insertRow( $data ); } $id = $event ? $event->getEventID() : last_inserted_ID(); // get the updated Event $event = FullEvent::factory() ->whereInt( Event::ID, $id ) ->queryRow(); // POST-redirect-GET http_redirect( $event->getEventEditURL(), 303 ); } /** * Change the Image */ if( $event && is_action( 'change-image' ) ) { // prepare the image uploader $image = new FileUploader( 'image', [ 'category' => 'image', 'override-filename' => "event-" . $event->getEventUID(), ] ); // prepare the image pathnames $img_url = $event->getConferenceUID() . _ . 'images'; $img_path = ABSPATH . __ . $event->getConferenceUID() . __ . 'images'; // really upload that shitty image somewhere if( $image->fileChoosed() ) { $ok = $image->uploadTo( $img_path, $status, $filename, $ext ); if( $ok ) { // now update ( new QueryEvent() ) ->whereEvent( $event ) ->update( [ 'event_img' => $img_url . "/$filename.$ext", ] ); // POST-redirect-GET http_redirect( $event->getFullEventEditURL(), 303 ); } else { $warning = $image->getErrorMessage(); } } } /* * Add the user */ if( $event && is_action( 'add-user' ) && isset( $_POST['user'] ) ) { // Add user $user = User::factoryFromUID( $_POST['user'] ) ->select( User::ID ) ->queryRow(); if( $user ) { ( new QueryEventUser() ) ->whereEvent( $event ) ->whereUser( $user ) ->delete(); ( new QueryEventUser() )->insertRow( [ new DBCol( Event::ID, $event->getEventID(), 'd' ), new DBCol( User ::ID, $user->getUserID(), 'd' ), new DBCol( EventUser::ORDER, 0, 'd' ), ] ); } } /** * Update an user order */ if( $event && is_action( 'update-user' ) && isset( $_POST['user'] ) ) { $user = User::factoryFromUID( $_POST['user'] ) ->select( User::ID ) ->queryRow(); if( $user ) { if ( !empty( $_POST['delete'] ) ) { // delete user ( new QueryEventUser() ) ->whereEvent( $event ) ->whereUser( $user ) ->delete(); } elseif( isset( $_POST['order'] ) ) { // change order ( new QueryEventUser() ) ->whereEvent( $event ) ->whereUser( $user ) ->update( [ new DBCol( EventUser::ORDER, $_POST['order'], 'd' ) ] ); } } } // post -> redirect -> get (no: it hide errors) // http_redirect( $_SERVER[ 'REQUEST_URI' ], 303 ); } +// Event's Sharable(s) +$sharables = []; + if( $event ) { + + // query all the Sharable(s) related to this Event + $sharables = + ( new QuerySharable() ) + ->whereEvent( $event ) + ->queryGenerator(); + Header::spawn( null, [ 'title' => sprintf( __("Modifica %s: %s"), $event->getChapterName(), $event->getEventTitle() ), ] ); } else { Header::spawn( null, [ 'title' => sprintf( __( "Aggiungi %s" ), __( "Evento" ) ), ] ); } ?> <?php if( $warning ): ?> <div class="card-panel yellow"><?= esc_html( $warning ) ?></div> <?php endif ?> <p><?= HTML::a( $conference->getConferenceURL(), esc_html( $conference->getConferenceTitle() ) . icon( 'home', 'left' ) ) ?></p> <?php if( $event && $event->hasEventPermalink() ): ?> <p><?= HTML::a( // href $event->getEventURL(), // text __( "Vedi" ) . icon( 'account_box', 'left' ) ) ?></p> <?php endif ?> <form method="post"> <?php form_action( 'save-event' ) ?> <div class="row"> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="event-title"><?= __( "Titolo" ) ?></label> <input type="text" name="title" id="event-title" required<?php if( $event ) { echo value( $event->get( Event::TITLE ) ); } ?> /> </div> </div> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="event-uid"><?= __( "Codice" ) ?></label> <input type="text" name="uid" id="event-uid" required<?php if( $event ) { echo value( $event->get( Event::UID ) ); } ?> /> </div> </div> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="event-subtitle"><?= __( "Sottotitolo" ) ?></label> <input type="text" name="subtitle" id="event-subtitle"<?php if( $event ) { echo value( $event->get( Event::SUBTITLE ) ); } ?> /> </div> </div> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="event-url"><?= __( "URL" ) ?></label> <input type="text" name="url" id="event-url"<?php if( $event ) { echo value( $event->get( Event::EXTERNAL_URL ) ); } ?> /> </div> </div> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="event-language"><?= __( "Lingua" ) ?></label> <input type="text" name="language" id="event-language" maxlenght="2"<?php if( $event ) { echo value( $event->get( Event::LANGUAGE ) ); } ?> /> </div> </div> </div> <div class="row"> <!-- chapters --> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="chapter"><?= __( "Capitolo" ) ?></label> <select name="chapter"> <?php // get every chapter $chapters = Chapter::factory() ->orderBy( Chapter::NAME ) ->queryGenerator(); // generate select options foreach( $chapters as $chapter ) { $option = ( new HTML( 'option' ) ) ->setText( esc_html( $chapter->getChapterName() ) ) ->setAttr( 'value', $chapter->getChapterID() ); // eventually select this chapter $selected = false; if( $event && $event->has( Chapter::ID ) ) { $selected = $event->getChapterID() === $chapter->getChapterID(); } elseif( isset( $_GET['chapter'] ) ) { $selected = $_GET['chapter'] === $chapter->getChapterUID(); } if( $selected ) { $option->setAttr( 'selected', 'selected' ); } echo $option->render(); } ?> </select> </div> </div> <!-- /chapters --> <!-- tracks --> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="track"><?= __( "Traccia" ) ?></label> <select name="track"> <?php // select all the available tracks for this Location $tracks = Track::factory() ->orderBy( Track::NAME ) ->queryGenerator(); // generate a select option for each track foreach( $tracks as $track ) { $option = ( new HTML( 'option' ) ) ->setText( esc_html( $track->getTrackName() ) ) ->setAttr( 'value', $track->getTrackID() ); // eventually auto-select this track $selected = false; if( $event && $event->has( Track::ID ) ) { $selected = $event->getTrackID() === $track->getTrackID(); } elseif( isset( $_GET['track'] ) ) { $selected = $_GET['track'] === $track->getTrackUID(); } if( $selected ) { $option->setAttr( 'selected', 'selected' ); } echo $option->render(); } ?> </select> </div> </div> <!-- /tracks --> <!-- rooms --> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="room"><?= __( "Stanza" ) ?></label> <select name="room"> <?php // select all the available rooms for this Location $rooms = Room::factory() ->whereInt( Location::ID, $conference->getLocationID() ) ->orderBy( Room::NAME ) ->queryGenerator(); // generate a select option for each room foreach( $rooms as $room ) { $option = ( new HTML( 'option' ) ) ->setText( esc_html( $room->getRoomName() ) ) ->setAttr( 'value', $room->getRoomID() ); // eventually auto-select this room $selected = false; if( $event && $event->has( Room::ID ) ) { $selected = $event->getRoomID() === $room->getRoomID(); } elseif( isset( $_GET['room'] ) ) { $selected = $_GET['room'] === $room->getRoomUID(); } if( $selected ) { $option->setAttr( 'selected', 'selected' ); } echo $option->render(); } ?> </select> </div> </div> <!-- /rooms --> </div> <div class="row"> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="event-start"><?= __( "Inizio" ) ?></label> <input type="text" name="start" required placeholder="Y-m-d H:i:s"<?php if( $event ) { echo value( $event->getEventStart()->format( 'Y-m-d H:i:s' ) ); } elseif( isset( $_GET['start'] ) ) { echo value( $_GET['start'] ); } ?> /> </div> </div> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="event-end"><?= __( "Fine" ) ?></label> <input type="text" name="end" required placeholder="Y-m-d H:i:s"<?php if( $event ) { echo value( $event->getEventEnd()->format( 'Y-m-d H:i:s' ) ); } elseif( isset( $_GET['end'] ) ) { echo value( $_GET['end'] ); } ?> /> </div> </div> <div class="col s12 m4 l3"> <div class="card-panel"> <label for="event-aborted"><?= __( "Annullato" ) ?></label> <select name="aborted"> <option value="0"<?= selected( !$event || !$event->isEventAborted() ) ?>><?= __( "No" ) ?></option> <option value="1"<?= selected( $event && $event->isEventAborted() ) ?>><?= __( "Sì" ) ?></option> </select> </div> </div> <div class="col s12"> <p><button type="submit" class="btn waves-effect"><?= __( "Salva" ) ?></button></p> </div> </div> <?php foreach( Event::fields_i18n() as $i18n_column => $label ): ?> <h3><?= $label ?></h3> <div class="row"> <?php foreach( all_languages() as $lang ): ?> <?php $iso = $lang->getISO() ?> <?php $field = $i18n_column . '_' . $iso ?> <div class="col s12 m6"> <div class="card-panel"> <label for="event-abstract"><?= $label ?> (<?= $lang->getHuman() ?>)</label> <textarea name="<?= esc_attr( $field ) ?>" class="materialize-textarea"><?php if( $event ) { echo esc_html( $event->get( $field ) ); } ?></textarea> </div> </div> <?php endforeach ?> </div> <?php endforeach ?> <!-- Image --> <div class="row"> <div class="col s12 m6"> <div class="card-panel"> <label for="event-image"><?= __( "Immagine" ) ?></label> <input type="text" name="image"<?php if( $event ) { echo value( $event->get( Event::IMAGE ) ); } ?>/ > <?php if( $event && $event->hasEventImage() ): ?> <img src="<?= esc_attr( $event->getEventImage() ) ?>" class="responsive-img" alt="<?= esc_attr( $event->getEventTitle() ) ?>" /> <?php endif ?> </div> </div> </div> <!-- /Image --> <div class="row"> <div class="col s12"> <button type="submit" class="btn waves-effect"><?= __( "Salva" ) ?></button> </div> </div> </form> <!-- image --> <?php if( $event ): ?> <form method="post" enctype="multipart/form-data"> <?php form_action( 'change-image' ) ?> <div class="row"> <div class="col s12"> <div class="card-panel"> <h3><?= __( "Nuova Immagine" ) ?></h3> <div class="file-field input-field"> <div class="btn"> <span><?= __( "Sfoglia" ) ?></span> <input name="image" type="file" /> </div> <div class="file-path-wrapper"> <input class="file-path validate" type="text" /> </div> </div> <button type="submit" class="btn waves-effect"><?= __( "Carica" ) ?></button> </div> </div> </div> </form> <?php endif ?> <!-- /image --> <?php if( $event ): ?> <div class="row"> <div class="col s12 m6"> <div class="card-panel"> <h3><?php printf( __( "Associa %s" ), __( "Utente" ) ) ?></h3> <form action="" method="post"> <?php form_action( 'add-user' ) ?> <select name="user" class="browser-default"> <?php $users = User::factory() ->select( [ User::UID, User::NAME, User::SURNAME, ] ) ->orderBy( User::NAME ) ->queryGenerator(); ?> <?php foreach( $users as $user ): ?> <option value="<?= $user->getUserUID() ?>"> <?= esc_html( $user->getUserFullname() ) ?> </option> <?php endforeach ?> </select> <p><button type="submit" class="btn"><?= __("Aggiungi") ?></button></p> </form> <p><?= HTML::a( User::editURL(), sprintf( __( "Aggiungi %s" ), sprintf( __( "Nuovo %s" ), __( "Utente" ) ) ) ) ?></p> </div> </div> </div> <?php endif ?> <?php if( $event ): ?> <?php $users = $event->factoryUserByEvent() ->select( [ User::UID, EventUser::ORDER, ] ) ->defaultClass( EventUser::class ) ->orderBy( EventUser::ORDER ) ->queryGenerator(); ?> <?php if( $users->valid() ): ?> <h3><?php printf( __( "Modifica %s" ), __( "Ordinamento" ) ) ?></h3> <div class="row"> <?php foreach( $users as $i => $user ): ?> <div class="col s12 m6"> <div class="card-panel"> <div class="row"> <form action="" method="post"> <?php form_action( 'update-user' ) ?> <div class="col s12 m6"> <input type="text" name="user"<?= value( $user->getUserUID() ) ?> /> </div> <div class="col s12 m6"> <input type="number" name="order"<?= value( $user->getEventUserOrder() ) ?>" /> </div> <div class="col s12 m6"> <input type="checkbox" name="delete" value="yes" id="asd-<?= $i ?>" /> <label for="asd-<?= $i ?>"><?= __("Elimina") ?></label> </div> <div class="col s12 m6"> <p><button type="submit" class="btn"><?= __("Salva") ?></button></p> <p><small><?= HTML::a( $user->getUserEditURL(), sprintf( __( "Modifica %s" ), __( "Utente" ) ) ) ?></small></p> </div> </form> </div> </div> </div> <?php endforeach ?> </div> <?php endif ?> <?php endif ?> + <!-- start Sharables --> + <?php if( $event && $sharables ): ?> + + <h3><?= __( "Materiali condivisi" ) ?></h3> + + <ul class="collection"> + + <?php foreach( $sharables as $sharable ): ?> + <li class="collection-item"><?= HTML::a( + $sharable->getSharableEditURL(), + esc_html( $sharable->getSharableTitle() ) + ) ?></li> + <?php endforeach ?> + + <!-- start add Sharable --> + <li><?= HTML::a( + Sharable::editURL( [ + 'event_ID' => $event->getEventID(), + ] ), + __( "Aggiungi" ) + ) ?></li> + <!-- end add Sharable --> + + </ul> + + <?php endif ?> + <!-- end Sharables --> <?php Footer::spawn(); diff --git a/admin/sharable.php b/admin/sharable.php new file mode 100644 index 0000000..2d5ff01 --- /dev/null +++ b/admin/sharable.php @@ -0,0 +1,144 @@ +<?php +# Suckless Conference +# Copyright (C) 2020 Valerio Bozzolan +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +/* + * Event edit + * + * From this page you can create/edit an User and assign some skills/interests etc. + */ + +// load configurations and framework +require 'load.php'; + +// editable Sharable fields +$EDITABLE_FIELDS = [ + Sharable::TITLE, + Sharable::TYPE, + Sharable::PATH, + Sharable::MIME, + Sharable::LICENSE, + Sharable::PARENT, +]; + +$sharable = null; +$sharable_ID = $_GET['id'] ?? 0; +$sharable_ID = (int) $sharable_ID; + +$event_ID = null; + +if( $sharable_ID ) { + + $sharable = ( new QuerySharable() ) + ->whereSharableID( $sharable_ID ) + ->queryRow(); + + // no Sharable no party + if( !$sharable ) { + error( "missing sharable with ID $sharable_ID" ); + die_with_404(); + } +} + +// check if it exists +if( $sharable ) { + + $event_ID = $sharable->getEventID(); + +} else { + + $event_ID = $_GET['event_ID'] ?? 0; + $event_ID = (int) $event_ID; + + // no Event no party + if( !$event_ID ) { + throw new Exception( "missing Event" ); + } +} + +// check if the user submitted the form +if( is_action( 'save-sharable' ) ) { + + // data to be saved + $data = []; + + // read and sanitize POST data + foreach( $EDITABLE_FIELDS as $field ) { + + $v = luser_input( $_POST[ $field ] ?? '', 128 ); + if( !$v ) { + $v = null; + } + + $data[] = new DBCol( $field, $v, 'snull' ); + } + + // check if already existing + if( $sharable ) { + + // update existing + ( new QuerySharable() ) + ->whereSharable( $sharable ) + ->update( $data ); + } else { + + // insert a new one + ( new QuerySharable() ) + ->insertRow( $data ); + + $sharable_ID = last_inserted_ID(); + } + + // POST -> redirect -> POST + http_redirect( Sharable::editURL( [ + 'id' => $sharable_ID, + ] ) ); +} + +// print website header +Header::spawn( null, [ + 'title' => __( "Materiale condiviso" ), +] ); + +?> + + <form method="post"> + + <?php form_action( 'save-sharable' ) ?> + + <?php foreach( $EDITABLE_FIELDS as $field ): ?> + + <p> + <?= esc_html( $field ) ?><br /> + + <input type="text" name="<?= esc_attr( $field ) ?>"<?= value( + $sharable + ? $sharable->get( $field ) + : ( $_POST[ $field ] ?? null ) + ) ?>" /> + </p> + + <?php endforeach ?> + + <button type="submit"><?= __( "Salva" ) ?></button> + + </form> + +<?php + +// print website footer +Footer::spawn(); + diff --git a/includes/class-QuerySharable.php b/includes/class-QuerySharable.php index 16ebb62..b608c75 100644 --- a/includes/class-QuerySharable.php +++ b/includes/class-QuerySharable.php @@ -1,140 +1,147 @@ <?php # Suckless conference # Copyright (C) 2020 Valerio Bozzolan # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. // require dependent traits class_exists( QueryEvent::class, true ); /** * Methods related to a QuerySharable class */ trait QuerySharableTrait { /** * Where the Sharable is... * * @param object $event Sharable * @return self */ public function whereSharable( $event ) { return $this->whereSharableID( $event->getSharableID() ); } /** * Where the Sharable ID is... * * @param int $id Sharable ID * @return self */ public function whereSharableID( $id ) { return $this->whereInt( $this->SHARABLE_ID, $id ); } /** * Where the Sharable has a parent * * @param boolean $has Set to false to have not a parent * @return self */ public function whereSharableHasParent( $has = true ) { // it has the parent if it's not NULL $verb = $has ? 'IS NOT' : 'IS'; return $this->compare( Sharable::PARENT, $verb, 'NULL' ); } /** * Where the Sharable has not a parent * * @param boolean $has Set to false to have not a parent * @return self */ public function whereSharableIsRoot() { return $this->whereSharableHasParent( false ); } /** * Where the Sharable has a parent and it's this one * * @param Sharable $sharable * @return self */ public function whereSharableParent( $sharable ) { return $this->whereSharableParentID( $sharable->getSharableID() ); } /** * Where the Sharable has a parent and it's this one * * @param int $id Sharable ID * @return self */ public function whereSharableParentID( $id ) { return $this->whereInt( Sharable::PARENT, $id ); } /** * Select a field called 'has_sharable_children' * * @return self */ public function selectSharableHasChildren( $alias = 'sharable_has_children' ) { // check if it exists another Sharable with this row as its parent $temp_subquery_alias = 'sharable_children'; $subquery = ( new QuerySharable( null, $temp_subquery_alias ) ) ->equals( $temp_subquery_alias . DOT . Sharable::PARENT, Sharable::ID_ ) ->getQuery(); return $this->select( "EXISTS( $subquery ) $alias"); } } /** * Utility used to Query a Sharable. */ class QuerySharable extends Query { use QuerySharableTrait; use QueryEventTrait; + /** + * Univoque Sharable ID column name + * + * @var + */ + protected $SHARABLE_ID = 'sharable.sharable_ID'; + /** * Univoque Event ID column name * * @var */ protected $EVENT_ID = 'sharable.event_ID'; /** * Constructor * * @param DB $db Database or NULL for the default one * @param string $alias Table alias */ public function __construct( $db = null, $alias = true ) { // initialize Query parent::__construct(); // select default table $this->fromAlias( Sharable::T, $alias ); // select default result class name $this->defaultClass( Sharable::class ); } } diff --git a/includes/class-Sharable.php b/includes/class-Sharable.php index 662f43d..bec42d2 100644 --- a/includes/class-Sharable.php +++ b/includes/class-Sharable.php @@ -1,285 +1,313 @@ <?php # Linux Day 2016 - Construct a database sharable # Copyright (C) 2016, 2017, 2018, 2019, 2020 Valerio Bozzolan, Linux Day Torino website contributors # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +// load dependent traits +class_exists( Event::class, true ); + trait SharableTrait { /** * Get the sharable ID * * @return int */ public function getSharableID() { return $this->nonnull( Sharable::ID ); } /** * Check if this Sharable has a parent * * See https://gitpull.it/T557 * * @return boolean */ public function hasSharableParent() { return $this->has( Sharable::PARENT ); } /** * Get the ID of the parent Sharable (if any) * * See https://gitpull.it/T557 * * @return mixed */ public function getSharableParentID() { return $this->get( Sharable::PARENT ); } /** * Get the localized sharable title * * @param $args array Title arguments like 'prop' * @return string */ public function getSharableTitle( $args = [] ) { $sharable_title = $this->get( Sharable::TITLE ); if( ! isset( $sharable_title ) ) { return $this->getDefaultSharableTitle( $args ); } return __( $sharable_title ); } /** * Retrieve something usable as a title * * @param $args array Title arguments like 'prop' * @return string */ public function getDefaultSharableTitle( $args = [] ) { $sharable_type = $this->get( Sharable::TYPE ); if( $sharable_type === 'youtube' ) { if( isset( $args['prop'] ) && $args['prop'] ) { return sprintf( __("il %s"), __("video esterno") ); } else { return __("video esterno"); } } $sharable_path = $this->get( Sharable::PATH ); // Get filename from "/asd/asd/asd/(filename)" $i = 0; while( strpos( $sharable_path, _, $i ) !== false ) { $i++; } return substr( $sharable_path, $i ); } /** * Is it an image? * * @return bool */ public function isSharableImage() { return $this->isSharableType( 'image' ); } /** * Is it a video? * * @return bool */ public function isSharableVideo() { return $this->isSharableType( 'video' ); } /** * Is it a document? * * @return bool */ public function isSharableDocument() { return $this->isSharableType( 'document' ); } /** * Is it an iframe (like a YouTube video?) * * @return bool */ public function isSharableIframe() { return $this->isSharableType( 'youtube' ); } /** * Is it of a certain type? * * @param $type string * @return bool */ private function isSharableType( $type ) { return $this->get( Sharable::TYPE ) === $type; } /** * It can be downloaded? * * @return bool */ public function isSharableDownloadable() { return ! $this->isSharableIframe(); } /** * @TODO: $base = ROOT is wrong and should be $absolute = false */ function getSharablePath( $base = ROOT ) { $type = $this->get( Sharable::TYPE ); $path = $this->get( Sharable::PATH ); if( 'youtube' === $type ) { return "https://www.youtube.com/watch?v={$path}"; } return site_page( $path, $base ); } /** * Get the MIME type * * @return string|null */ public function getSharableMIME() { return $this->get( Sharable::MIME ); } /** * Get the license * * @return License */ public function getSharableLicense() { return license( $this->get( Sharable::LICENSE ) ); } + /** + * Get the Sharable edit URL + * + * @return self + */ + public function getSharableEditURL() { + return Sharable::editURL( [ + 'id' => $this->getSharableID(), + ] ); + } + /** * Normalize a Sharable object */ protected function normalizeSharable() { $this->integers( Sharable::ID, Sharable::PARENT, Event ::ID ); } } /** * A Sharable is an attachment related to a Talk */ class Sharable extends Queried { + use SharableTrait; + use EventTrait; /** * Database table name */ const T = 'sharable'; /** * Sharable ID column */ const ID = 'sharable_ID'; /** * Sharable title column */ const TITLE = 'sharable_title'; /** * Sharable type column */ const TYPE = 'sharable_type'; /** * Sharable path column */ const PATH = 'sharable_path'; /** * Sharable mime type column */ const MIME = 'sharable_mimetype'; /** * Sharable license column */ const LICENSE = 'sharable_license'; /** * Name of the parent sharable_ID column * * See https://gitpull.it/T557 */ const PARENT = 'sharable_parent'; /** * Sharable univoque ID */ const ID_ = self::T . DOT . self::ID; /** * Sharable event ID */ const EVENT_ = self::T . DOT . Event::ID; /** * Constructor */ public function __construct() { $this->normalizeSharable(); + $this->normalizeEvent(); } /** * Factory by an event * * @param $event_ID int Event ID * @return Query */ public static function factoryByEvent( $event_ID ) { return ( new QuerySharable ) ->whereEventID( $event_ID ); } /** * All basic fields * * @return array */ public static function fields() { return [ self::ID_, self::TITLE, self::TYPE, self::PATH, self::MIME, self::LICENSE, self::PARENT, ]; } + + /** + * Create the Sharable edit URL + * + * @param array $args + * @return string + */ + public static function editURL( $args ) { + $url = site_page( ADMIN_BASE_URL . '/sharable.php' ); + return http_build_get_query( $url, $args ); + } }