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" )
),
] );
}
?>
= esc_html( $warning ) ?>
= HTML::a(
$conference->getConferenceURL(),
esc_html( $conference->getConferenceTitle() ) . icon( 'home', 'left' )
) ?>
hasEventPermalink() ): ?>
= HTML::a(
// href
$event->getEventURL(),
// text
__( "Vedi" ) . icon( 'account_box', 'left' )
) ?>
= HTML::a(
ROOT . '/2016/user-edit.php',
sprintf(
__( "Aggiungi %s" ),
sprintf(
__( "Nuovo %s" ),
__( "Utente" )
)
)
) ?>
factoryUserByEvent()
->select( [
User::UID,
EventUser::ORDER,
] )
->defaultClass( EventUser::class )
->orderBy( EventUser::ORDER )
->queryGenerator();
?>
valid() ): ?>
.
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 );
}
}