diff --git a/admin/event-edit.php b/admin/event-edit.php index 1e1a6c9..043ade3 100644 --- a/admin/event-edit.php +++ b/admin/event-edit.php @@ -1,639 +1,666 @@ . /* * 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 ); } if( $event ) { Header::spawn( null, [ 'title' => sprintf( __("Modifica %s: %s"), $event->getChapterName(), $event->getEventTitle() ), ] ); } else { Header::spawn( null, [ 'title' => sprintf( __( "Aggiungi %s" ), __( "Evento" ) ), ] ); } ?>

getConferenceURL(), esc_html( $conference->getConferenceTitle() ) . icon( 'home', 'left' ) ) ?>

hasEventPermalink() ): ?>

getEventURL(), // text __( "Vedi" ) . icon( 'account_box', 'left' ) ) ?>

get( Event::TITLE ) ); } ?> />
get( Event::UID ) ); } ?> />
get( Event::SUBTITLE ) ); } ?> />
+
+
+ + get( Event::EXTERNAL_URL ) ); + } + ?> /> +
+
+
get( Event::LANGUAGE ) ); } ?> />
getEventStart()->format( 'Y-m-d H:i:s' ) ); } elseif( isset( $_GET['start'] ) ) { echo value( $_GET['start'] ); } ?> />
getEventEnd()->format( 'Y-m-d H:i:s' ) ); } elseif( isset( $_GET['end'] ) ) { echo value( $_GET['end'] ); } ?> />
+
+
+ + +
+
+ +
+

+
+
$label ): ?>

getISO() ?>
get( Event::IMAGE ) ); } ?>/ > hasEventImage() ): ?> <?= esc_attr( $event->getEventTitle() ) ?>

factoryUserByEvent() ->select( [ User::UID, EventUser::ORDER, ] ) ->defaultClass( EventUser::class ) ->orderBy( EventUser::ORDER ) ->queryGenerator(); ?> valid() ): ?>

$user ): ?>
getUserUID() ) ?> />
getEventUserOrder() ) ?>" />

getUserEditURL(), sprintf( __( "Modifica %s" ), __( "Utente" ) ) ) ?>

. trait EventTrait { /** * Get event ID * * @return int */ public function getEventID() { return $this->nonnull( Event::ID ); } /** * Get event UID * * @return string */ public function getEventUID() { return $this->get( Event::UID ); } /** * Check if this Event is external or not * * @return boolean */ public function hasEventExternalURL() { return $this->has( Event::EXTERNAL_URL ); } /** * Get the Event external URL (if any) * * @return string|null */ public function getEventExternalURL() { return $this->get( Event::EXTERNAL_URL ); } /** * Get localized event title * * @return string */ public function getEventTitle() { return __( $this->get( Event::TITLE ) ); } /** * Check if the Event has a subtitle * * @return boolean */ public function hasEventSubtitle() { $title = $this->get( Event::SUBTITLE ); return !empty( $title ); } /** * Get localized event subtitle * * @return string */ public function getEventSubtitle() { return __( $this->get( Event::SUBTITLE ) ); } /** * Get an human event start date * * @return string */ public function getEventHumanStart() { return HumanTime::diff( $this->getEventStart() ); } /** * Get an human event end date * * @return string */ public function getEventHumanEnd() { return HumanTime::diff( $this->getEventEnd() ); } /** * Get event start date * * @param string If present, format of the date * @return DateTime|string */ public function getEventStart( $format = null ) { $date = $this->get( Event::START ); if( $format ) { return $date->format( $format ); } return $date; } /** * When event end date * * @param string If present, format of the date * @return DateTime|string */ public function getEventEnd( $format = null ) { $date = $this->get( Event::END ); if( $format ) { return $date->format( $format ); } return $date; } /** * Get the event duration * * @return DateInterval */ public function getEventDuration( $format ) { $start = $this->get( Event::START ); $end = $this->get( Event::END ); return $start->diff( $end )->format( $format ); } /** * Get the Event duration in a human-readable format * * @return string */ public function getHumanEventDuration( $args = [] ) { if( !isset( $args['adverb'] ) ) { $args['adverb'] = false; } return HumanTime::diff( $this->get( Event::START ), $this->get( Event::END ), $args ); } /** * It has an Event image? * * @return bool */ public function hasEventImage() { return $this->has( Event::IMAGE ); } /** * Get the path to the Event image * * @param boolean $absolute Try to force an absolute URL * @return string */ public function getEventImage( $absolute = false ) { return site_page( $this->get( Event::IMAGE ), $absolute ); } /** * Check if the Event has a language * * @return boolean */ public function hasEventLanguage() { return $this->has( Event::LANGUAGE ); } /** * Get the Event language * * @return string */ public function getEventLanguage() { return $this->get( Event::LANGUAGE ); } /** * It has event description? * * @return bool */ public function hasEventDescription() { return null !== $this->get( Event::DESCRIPTION ); } /** * It has an event abstract? * * @return bool */ public function hasEventAbstract() { return null !== $this->get( Event::ABSTRACT ); } /** * It has an event note? * * @return bool */ function hasEventNote() { return null !== $this->get( Event::NOTE ); } /** * Get the event description * * @return string */ public function getEventDescription() { return $this->get( Event::DESCRIPTION ); } /** * Get the event abstract * * @return string */ public function getEventAbstract() { return $this->get( Event::ABSTRACT ); } /** * Get the event note * * @return string */ public function getEventNote() { return $this->get( Event::NOTE ); } /** * Get the Event description rendered in HTML * * @return string */ public function getEventDescriptionHTML( $args = [] ) { return Markdown::parse( $this->getEventDescription(), $args ); } /** * Get the Event abstract rendered in HTML * * @return string */ public function getEventAbstractHTML( $args = [] ) { return Markdown::parse( $this->getEventAbstract(), $args ); } /** * Get the Event notes rendered in HTML * * @return string */ public function getEventNoteHTML( $args = [] ) { return Markdown::parse( $this->getEventNote(), $args ); } /** * Factory Users by this event * * @return Query */ public function factoryUserByEvent() { return User::factoryByEvent( $this->getEventID() ); } /** * Factory Sharables by this event * * @return Query */ public function factorySharebleByEvent() { return Sharable::factoryByEvent( $this->getEventID() ); } /** * You can edit this event? * * @return bool */ public function isEventEditable() { return has_permission('edit-events'); } /** * Get the edit URL for this Event * * @param boolean $absolute Flag to require an absolute URL * @return string */ public function getEventEditURL( $absolute = false ) { return Event::editURL( [ 'id' => $this->getEventID(), ], $absolute ); } /** * Check if I can translate this Event * * @return boolean */ public function isEventTranslatable() { return $this->isEventEditable() || has_permission( 'translate' ); } + /** + * Check if the Event was aborted + * + * @return boolean + */ + public function isEventAborted() { + return $this->get( Event::ABORTED ); + } + /** * Insert subscription if not exists */ function addSubscription($email) { $exists = Subscription::getStandardQuery( $email, $this->getEventID() )->getRow('Subscription'); $exists || Subscription::insert( $email, $this->getEventID() ); return $exists; } /** * Get URL to trop-iCal API for this event * * @param boolean $absolute Set to true for an absolute URL * @return string */ public function getEventCalURL( $absolute = false ) { $event = urlencode( $this->getEventUID() ); $conf = urlencode( $this->getConferenceUID() ); return site_page( "api/tropical.php?conference=$conf&event=$event", $absolute ); } /** * Are event subscriptions available? * * @return bool */ public function areEventSubscriptionsAvailable() { return $this->get( 'event_subscriptions' ) && ! $this->isEventPassed(); } /** * Is event passed? * * @return bool */ public function isEventPassed() { $now = new DateTime('now'); return $now->diff( $this->get('event_end') )->invert === 1; } /** * Get the URL to the page that allow to translate this Event * * @return string */ public function getEventTranslateURL() { // well, actually the translate page it's in the 2016 directory :^) $page = ROOT . '/2016/event-translate.php'; return http_build_get_query( $page, [ 'id' => $this->getEventID(), ] ); } /** * Normalize an Event object */ protected function normalizeEvent() { $this->integers( Event::ID ); $this->datetimes( Event::START, Event::END ); - $this->booleans('event_subscriptions'); + $this->booleans( + 'event_subscriptions', + Event::ABORTED + ); } } /** * An Event can be a talk or a lesson etc. */ class Event extends Queried { use EventTrait; /** * Database table name */ const T = 'event'; /** * ID column name */ const ID = 'event_ID'; /** * UID column name */ const UID = 'event_uid'; /** * Event external URL */ const EXTERNAL_URL = 'event_url'; /** * Title column name */ const TITLE = 'event_title'; /** * Subtitle column name */ const SUBTITLE = 'event_subtitle'; /** * Image column name */ const IMAGE = 'event_img'; /** * Start column name */ const START = 'event_start'; /** * End column name */ const END = 'event_end'; /** * Description column name */ const DESCRIPTION = 'event_description'; /** * Description column name */ const ABSTRACT = 'event_abstract'; /** * Note column name */ const NOTE = 'event_note'; /** * Language column name */ const LANGUAGE = 'event_language'; + /** + * Check if the Event was aborted or not + */ + const ABORTED = 'event_aborted'; + /** * Complete ID column name */ const ID_ = self::T . DOT . self::ID; /** * Complete conference ID column name */ const CONFERENCE_ = self::T . DOT . Conference::ID; /** * Complete room ID column name */ const ROOM_ = self::T . DOT . Room::ID; /** * Complete track ID column name */ const TRACK_ = self::T . DOT . Track::ID; /** * Complete chapter ID column name */ const CHAPTER_ = self::T . DOT . Chapter::ID; /** * Maximum UID length * * @override */ const MAXLEN_UID = 100; /** * Constructor */ public function __construct() { $this->normalizeEvent(); } /** * Generate the appropriate SELECT for the User Abstract * * @return string */ public static function ABSTRACT_L10N() { return i18n_coalesce( self::ABSTRACT ); } /** * Generate the appropriate SELECT for the User Description * * @return string */ public static function DESCRIPTION_L10N() { return i18n_coalesce( self::DESCRIPTION ); } /** * Generate the appropriate SELECT for the User Description * * @return string */ public static function NOTE_L10N() { return i18n_coalesce( self::NOTE ); } /** * All the public Event fields * * @return array */ public static function fields() { return [ self::ID_, self::UID, self::TITLE, self::DESCRIPTION_L10N(), self::ABSTRACT_L10N(), self::NOTE_L10n(), self::SUBTITLE, self::IMAGE, self::START, self::END, self::LANGUAGE, + self::ABORTED, + self::EXTERNAL_URL, ]; } /** * Get all the fields that support internationalization * * @return array */ public static function fields_i18n() { return [ self::ABSTRACT => __( "Abstract" ), self::DESCRIPTION => __( "Descrizione" ), self::NOTE => __( "Note" ), ]; } /** * Get the edit URL to an Event * * @param array $args Arguments for the edit page * @param boolean $absolute Flag to require an absolute URL * @return string */ public static function editURL( $args, $absolute = false ) { $url = site_page( ADMIN_BASE_URL . '/event-edit.php', $absolute ); return http_build_get_query( $url, $args ); } }