Endpoint get summit schedule empty spots
Added endpoint GET /api/v1/summit/{:summit_id}/events/schedule/empty-spots params filter * location_id [==] ( supports OR) * start_date [>=] (epoch) * end_date [<=] ( epoch) * gap [==,<,>,>=,<=] ( in minutes) Change-Id: I6b4147205c96b32f6f6afc3a771300e588bc7740
This commit is contained in:
parent
dd78b729b6
commit
ec1b904092
@ -32,6 +32,7 @@ use utils\FilterParser;
|
||||
use utils\FilterParserException;
|
||||
use utils\OrderParser;
|
||||
use utils\PagingInfo;
|
||||
use utils\PagingResponse;
|
||||
|
||||
/**
|
||||
* Class OAuth2SummitEventsApiController
|
||||
@ -851,7 +852,6 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
@ -881,4 +881,60 @@ final class OAuth2SummitEventsApiController extends OAuth2ProtectedController
|
||||
}
|
||||
}
|
||||
|
||||
public function getScheduleEmptySpots($summit_id){
|
||||
try
|
||||
{
|
||||
$summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id);
|
||||
if (is_null($summit)) return $this->error404();
|
||||
$filter = null;
|
||||
if (Input::has('filter')) {
|
||||
$filter = FilterParser::parse(Input::get('filter'), [
|
||||
'location_id' => ['=='],
|
||||
'start_date' => ['>='],
|
||||
'end_date' => ['<='],
|
||||
'gap' => ['>', '<', '<=', '>=', '=='],
|
||||
]);
|
||||
}
|
||||
|
||||
if(empty($filter))
|
||||
throw new ValidationException("filter param is mandatory!");
|
||||
|
||||
$gaps = [];
|
||||
foreach ($this->service->getSummitScheduleEmptySpots($summit, $filter) as $gap)
|
||||
{
|
||||
$gaps[] = SerializerRegistry::getInstance()->getSerializer($gap)->serialize();
|
||||
}
|
||||
|
||||
$response = new PagingResponse
|
||||
(
|
||||
count($gaps),
|
||||
count($gaps),
|
||||
1,
|
||||
1,
|
||||
$gaps
|
||||
);
|
||||
|
||||
return $this->ok($response->toArray());
|
||||
}
|
||||
catch (EntityNotFoundException $ex1)
|
||||
{
|
||||
Log::warning($ex1);
|
||||
return $this->error404();
|
||||
}
|
||||
catch (ValidationException $ex2)
|
||||
{
|
||||
Log::warning($ex2);
|
||||
return $this->error412($ex2->getMessages());
|
||||
}
|
||||
catch(FilterParserException $ex3){
|
||||
Log::warning($ex3);
|
||||
return $this->error412($ex3->getMessages());
|
||||
}
|
||||
catch (Exception $ex)
|
||||
{
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -356,4 +356,24 @@ final class Filter
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getFilterCollectionByField($field){
|
||||
$list = [];
|
||||
$filter = $this->getFilter($field);
|
||||
|
||||
if(is_array($filter)){
|
||||
if(is_array($filter[0])){
|
||||
foreach ($filter[0] as $filter_element)
|
||||
$list[] = intval($filter_element->getValue());
|
||||
}
|
||||
else{
|
||||
$list[] = intval($filter[0]->getValue());
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -23,8 +23,9 @@ final class FilterParser
|
||||
*/
|
||||
public static function parse($filters, $allowed_fields = array())
|
||||
{
|
||||
$res = [];
|
||||
$matches = [];
|
||||
$res = [];
|
||||
$matches = [];
|
||||
$and_fields = [];
|
||||
|
||||
if (!is_array($filters))
|
||||
$filters = array($filters);
|
||||
@ -81,6 +82,10 @@ final class FilterParser
|
||||
throw new FilterParserException(sprintf("%s op is not allowed for filter by field %s",$op, $field));
|
||||
}
|
||||
|
||||
if(in_array($field, $and_fields))
|
||||
throw new FilterParserException(sprintf("filter by field %s is already on an and expression", $field));
|
||||
|
||||
$and_fields[] = $field;
|
||||
$f = self::buildFilter($field, $op, $value);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ final class Order
|
||||
*/
|
||||
private $ordering;
|
||||
|
||||
public function __construct($ordering = array())
|
||||
public function __construct($ordering = [])
|
||||
{
|
||||
$this->ordering = $ordering;
|
||||
}
|
||||
|
@ -198,7 +198,11 @@ Route::group([
|
||||
Route::get('', 'OAuth2SummitEventsApiController@getUnpublishedEvents');
|
||||
//Route::get('{event_id}', 'OAuth2SummitEventsApiController@getUnpublisedEvent');
|
||||
});
|
||||
Route::get('/published', 'OAuth2SummitEventsApiController@getScheduledEvents');
|
||||
Route::group(array('prefix' => 'published'), function () {
|
||||
Route::get('', 'OAuth2SummitEventsApiController@getScheduledEvents');
|
||||
Route::get('/empty-spots', 'OAuth2SummitEventsApiController@getScheduleEmptySpots');
|
||||
});
|
||||
|
||||
Route::post('', [ 'middleware' => 'auth.user:administrators', 'uses' => 'OAuth2SummitEventsApiController@addEvent']);
|
||||
Route::group(array('prefix' => '{event_id}'), function () {
|
||||
|
||||
|
@ -1,4 +1,16 @@
|
||||
<?php namespace ModelSerializers;
|
||||
/**
|
||||
* Copyright 2016 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use App\ModelSerializers\CCLA\TeamSerializer;
|
||||
use App\ModelSerializers\Marketplace\CloudServiceOfferedSerializer;
|
||||
use App\ModelSerializers\Marketplace\ConfigurationManagementTypeSerializer;
|
||||
@ -37,19 +49,11 @@ use ModelSerializers\Locations\SummitVenueFloorSerializer;
|
||||
use ModelSerializers\Locations\SummitVenueRoomSerializer;
|
||||
use ModelSerializers\Locations\SummitVenueSerializer;
|
||||
use App\ModelSerializers\Marketplace\ApplianceSerializer;
|
||||
|
||||
use ModelSerializers\SummitScheduleEmptySpotSerializer;
|
||||
/**
|
||||
* Copyright 2016 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
* Class SerializerRegistry
|
||||
* @package ModelSerializers
|
||||
*/
|
||||
final class SerializerRegistry
|
||||
{
|
||||
/**
|
||||
@ -101,7 +105,7 @@ final class SerializerRegistry
|
||||
$this->registry['SummitMemberFavorite'] = SummitMemberFavoriteSerializer::class;
|
||||
$this->registry['SummitEntityEvent'] = SummitEntityEventSerializer::class;
|
||||
$this->registry['SummitEventWithFile'] = SummitEventWithFileSerializer::class;
|
||||
|
||||
$this->registry['SummitScheduleEmptySpot'] = SummitScheduleEmptySpotSerializer::class;
|
||||
// locations
|
||||
$this->registry['SummitVenue'] = SummitVenueSerializer::class;
|
||||
$this->registry['SummitVenueRoom'] = SummitVenueRoomSerializer::class;
|
||||
|
29
app/ModelSerializers/SummitScheduleEmptySpotSerializer.php
Normal file
29
app/ModelSerializers/SummitScheduleEmptySpotSerializer.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php namespace ModelSerializers;
|
||||
/**
|
||||
* Copyright 2017 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use Libs\ModelSerializers\AbstractSerializer;
|
||||
|
||||
/**
|
||||
* Class SummitScheduleEmptySpotSerializer
|
||||
* @package ModelSerializers
|
||||
*/
|
||||
final class SummitScheduleEmptySpotSerializer extends AbstractSerializer
|
||||
{
|
||||
protected static $array_mappings = [
|
||||
|
||||
'LocationId' => 'location_id:json_int',
|
||||
'StartDateTime' => 'start_date:datetime_epoch',
|
||||
'EndDateTime' => 'end_date:datetime_epoch',
|
||||
'TotalMinutes' => 'total_minutes:json_int',
|
||||
];
|
||||
}
|
83
app/Models/Foundation/Summit/SummitScheduleEmptySpot.php
Normal file
83
app/Models/Foundation/Summit/SummitScheduleEmptySpot.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php namespace models\summit;
|
||||
/**
|
||||
* Copyright 2017 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use DateTime;
|
||||
/**
|
||||
* Class SummitScheduleEmptySpot
|
||||
* @package models\summit
|
||||
*/
|
||||
final class SummitScheduleEmptySpot
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $location_id;
|
||||
|
||||
/**
|
||||
* @var DateTime
|
||||
*/
|
||||
private $start_date_time;
|
||||
|
||||
/**
|
||||
* @var DateTime
|
||||
*/
|
||||
private $end_date_time;
|
||||
|
||||
/**
|
||||
* SummitScheduleEmptySpot constructor.
|
||||
* @param int $location_id
|
||||
* @param DateTime $start_date_time
|
||||
* @param DateTime $end_date_time
|
||||
*/
|
||||
public function __construct($location_id, DateTime $start_date_time, DateTime $end_date_time)
|
||||
{
|
||||
$this->location_id = $location_id;
|
||||
$this->start_date_time = $start_date_time;
|
||||
$this->end_date_time = $end_date_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLocationId()
|
||||
{
|
||||
return $this->location_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
*/
|
||||
public function getStartDateTime()
|
||||
{
|
||||
return $this->start_date_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
*/
|
||||
public function getEndDateTime()
|
||||
{
|
||||
return $this->end_date_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalMinutes(){
|
||||
$interval = $this->end_date_time->diff($this->start_date_time);
|
||||
$total_minutes = $interval->days * 24 * 60;
|
||||
$total_minutes += $interval->h * 60;
|
||||
$total_minutes += $interval->i;
|
||||
return intval($total_minutes);
|
||||
}
|
||||
}
|
51
app/Models/Utils/IntervalParser.php
Normal file
51
app/Models/Utils/IntervalParser.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php namespace App\Models\Utils;
|
||||
/**
|
||||
* Copyright 2017 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Class IntervalParser
|
||||
* @package App\Models\Utils
|
||||
*/
|
||||
final class IntervalParser
|
||||
{
|
||||
/**
|
||||
* @param \DateTime $from
|
||||
* @param \DateTime $to
|
||||
* @return array
|
||||
*/
|
||||
public static function getInterval(\DateTime $from, \DateTime $to){
|
||||
$intervals = [];
|
||||
$aux_from = clone $from;
|
||||
$start_hour = intval($from->format('h'));
|
||||
$start_min = intval($from->format('i'));
|
||||
|
||||
do{
|
||||
$aux_to = clone $aux_from;
|
||||
$aux_to->setTime(23, 59, 59);
|
||||
|
||||
if($aux_to > $to){
|
||||
$aux_to = clone $to;
|
||||
}
|
||||
$intervals[] = [
|
||||
$aux_from,
|
||||
$aux_to
|
||||
];
|
||||
$aux_from = clone $aux_from;
|
||||
$aux_from->add(new \DateInterval('P1D'));
|
||||
|
||||
} while($aux_to < $to);
|
||||
|
||||
return $intervals;
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
<?php namespace App\Repositories\Summit;
|
||||
|
||||
/**
|
||||
* Copyright 2016 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -12,7 +11,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||
use models\summit\ISummitEventRepository;
|
||||
use models\summit\SummitEvent;
|
||||
|
@ -1,16 +1,4 @@
|
||||
<?php namespace services\model;
|
||||
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\main\File;
|
||||
use models\main\Member;
|
||||
use models\summit\ConfirmationExternalOrderRequest;
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitAttendee;
|
||||
use models\summit\SummitEvent;
|
||||
use models\summit\SummitEventFeedback;
|
||||
|
||||
/**
|
||||
* Copyright 2015 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -23,6 +11,19 @@ use models\summit\SummitEventFeedback;
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\main\File;
|
||||
use models\main\Member;
|
||||
use models\summit\ConfirmationExternalOrderRequest;
|
||||
use models\summit\Summit;
|
||||
use models\summit\SummitAttendee;
|
||||
use models\summit\SummitEvent;
|
||||
use models\summit\SummitEventFeedback;
|
||||
use models\summit\SummitScheduleEmptySpot;
|
||||
use DateTime;
|
||||
use utils\Filter;
|
||||
|
||||
/**
|
||||
* Interface ISummitService
|
||||
@ -147,7 +148,7 @@ interface ISummitService
|
||||
* @param $event_id
|
||||
* @return bool
|
||||
*/
|
||||
public function unRSVPEvent(Summit $summit ,Member $member, $event_id);
|
||||
public function unRSVPEvent(Summit $summit, Member $member, $event_id);
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
@ -159,4 +160,15 @@ interface ISummitService
|
||||
* @return File
|
||||
*/
|
||||
public function addEventAttachment(Summit $summit, $event_id, UploadedFile $file, $max_file_size = 10485760);
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param Filter $filter
|
||||
* @return SummitScheduleEmptySpot[]
|
||||
*/
|
||||
public function getSummitScheduleEmptySpots
|
||||
(
|
||||
Summit $summit,
|
||||
Filter $filter
|
||||
);
|
||||
}
|
@ -16,11 +16,11 @@ use App\Events\MyFavoritesRemove;
|
||||
use App\Events\MyScheduleAdd;
|
||||
use App\Events\MyScheduleRemove;
|
||||
use App\Http\Utils\FileUploader;
|
||||
use App\Models\Utils\IntervalParser;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
use models\exceptions\ValidationException;
|
||||
use models\main\File;
|
||||
@ -55,11 +55,19 @@ use models\summit\SummitEventFeedback;
|
||||
use models\summit\SummitEventType;
|
||||
use models\summit\SummitEventWithFile;
|
||||
use models\summit\SummitGroupEvent;
|
||||
use models\summit\SummitScheduleEmptySpot;
|
||||
use services\apis\IEventbriteAPI;
|
||||
use libs\utils\ITransactionService;
|
||||
use Exception;
|
||||
use DateTime;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use utils\Filter;
|
||||
use utils\FilterElement;
|
||||
use utils\FilterParser;
|
||||
use utils\Order;
|
||||
use utils\OrderElement;
|
||||
use utils\PagingInfo;
|
||||
use DateInterval;
|
||||
/**
|
||||
* Class SummitService
|
||||
* @package services\model
|
||||
@ -1158,4 +1166,170 @@ final class SummitService implements ISummitService
|
||||
return $attachment;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Summit $summit
|
||||
* @param Filter $filter
|
||||
* @return SummitScheduleEmptySpot[]
|
||||
*/
|
||||
public function getSummitScheduleEmptySpots
|
||||
(
|
||||
Summit $summit,
|
||||
Filter $filter
|
||||
)
|
||||
{
|
||||
return $this->tx_service->transaction(function () use
|
||||
(
|
||||
$summit,
|
||||
$filter
|
||||
){
|
||||
$gaps = [];
|
||||
$order = new Order([
|
||||
OrderElement::buildAscFor("location_id"),
|
||||
OrderElement::buildAscFor("start_date"),
|
||||
]);
|
||||
|
||||
// parse locations ids
|
||||
|
||||
if(!$filter->hasFilter('location_id'))
|
||||
throw new ValidationException("missing required filter location_id");
|
||||
|
||||
$location_ids = $filter->getFilterCollectionByField('location_id');
|
||||
|
||||
// parse start_date filter
|
||||
$start_datetime_filter = $filter->getFilter('start_date');
|
||||
if(is_null($start_datetime_filter))
|
||||
throw new ValidationException("missing required filter start_date");
|
||||
$start_datetime_unix = intval($start_datetime_filter[0]->getValue());
|
||||
$start_datetime = new \DateTime("@$start_datetime_unix");
|
||||
// parse end_date filter
|
||||
$end_datetime_filter = $filter->getFilter('end_date');
|
||||
if(is_null($end_datetime_filter))
|
||||
throw new ValidationException("missing required filter end_date");
|
||||
$end_datetime_unix = intval($end_datetime_filter[0]->getValue());
|
||||
$end_datetime = new \DateTime("@$end_datetime_unix");
|
||||
// gap size filter
|
||||
|
||||
$gap_size_filter = $filter->getFilter('gap');
|
||||
if(is_null($end_datetime_filter))
|
||||
throw new ValidationException("missing required filter gap");
|
||||
|
||||
$gap_size = $gap_size_filter[0];
|
||||
|
||||
$summit_time_zone = $summit->getTimeZone();
|
||||
$start_datetime->setTimezone($summit_time_zone);
|
||||
$end_datetime->setTimezone($summit_time_zone);
|
||||
|
||||
$intervals = IntervalParser::getInterval($start_datetime, $end_datetime);
|
||||
|
||||
foreach($location_ids as $location_id) {
|
||||
|
||||
foreach($intervals as $interval) {
|
||||
|
||||
$events_filter = new Filter();
|
||||
$events_filter->addFilterCondition(FilterParser::buildFilter('published', '==', '1'));
|
||||
$events_filter->addFilterCondition(FilterParser::buildFilter('summit_id', '==', $summit->getId()));
|
||||
$events_filter->addFilterCondition(FilterParser::buildFilter('location_id', '==', intval($location_id)));
|
||||
$events_filter->addFilterCondition(FilterParser::buildFilter('start_date', '>=', $interval[0]->getTimestamp()));
|
||||
$events_filter->addFilterCondition(FilterParser::buildFilter('end_date', '<=', $interval[1]->getTimestamp()));
|
||||
|
||||
$paging_response = $this->event_repository->getAllByPage
|
||||
(
|
||||
new PagingInfo(1, PHP_INT_MAX),
|
||||
$events_filter,
|
||||
$order
|
||||
);
|
||||
|
||||
$gap_start_date = $interval[0];
|
||||
$gap_end_date = clone $gap_start_date;
|
||||
// check published items
|
||||
foreach ($paging_response->getItems() as $event) {
|
||||
|
||||
while
|
||||
(
|
||||
(
|
||||
$gap_end_date->getTimestamp() + (self::MIN_EVENT_MINUTES * 60)
|
||||
)
|
||||
<= $event->getLocalStartDate()->getTimestamp()
|
||||
) {
|
||||
$max_gap_end_date = clone $gap_end_date;
|
||||
$max_gap_end_date->setTime(23, 59, 59);
|
||||
if ($gap_end_date->getTimestamp() + (self::MIN_EVENT_MINUTES * 60) > $max_gap_end_date->getTimestamp()) break;
|
||||
$gap_end_date->add(new DateInterval('PT' . self::MIN_EVENT_MINUTES . 'M'));
|
||||
}
|
||||
|
||||
if ($gap_start_date->getTimestamp() == $gap_end_date->getTimestamp()) {
|
||||
// no gap!
|
||||
$gap_start_date = $event->getLocalEndDate();
|
||||
$gap_end_date = clone $gap_start_date;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check min gap ...
|
||||
if(self::checkGapCriteria($gap_size, $gap_end_date->diff($gap_start_date)))
|
||||
$gaps[] = new SummitScheduleEmptySpot($location_id, $gap_start_date, $gap_end_date);
|
||||
$gap_start_date = $event->getLocalEndDate();
|
||||
$gap_end_date = clone $gap_start_date;
|
||||
}
|
||||
|
||||
// check last possible gap ( from last $gap_start_date till $interval[1]
|
||||
|
||||
if($gap_start_date < $interval[1]){
|
||||
// last possible gap
|
||||
if(self::checkGapCriteria($gap_size, $interval[1]->diff($gap_start_date)))
|
||||
$gaps[] = new SummitScheduleEmptySpot($location_id, $gap_start_date, $interval[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $gaps;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param FilterElement $gap_size_criteria
|
||||
* @param DateInterval $interval
|
||||
* @return bool
|
||||
*/
|
||||
private static function checkGapCriteria
|
||||
(
|
||||
FilterElement $gap_size_criteria,
|
||||
DateInterval $interval
|
||||
)
|
||||
{
|
||||
$total_minutes = $interval->days * 24 * 60;
|
||||
$total_minutes += $interval->h * 60;
|
||||
$total_minutes += $interval->i;
|
||||
|
||||
switch($gap_size_criteria->getOperator()){
|
||||
case '=':
|
||||
{
|
||||
return intval($gap_size_criteria->getValue()) == $total_minutes;
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
{
|
||||
return $total_minutes < intval($gap_size_criteria->getValue());
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
{
|
||||
return $total_minutes > intval($gap_size_criteria->getValue());
|
||||
}
|
||||
break;
|
||||
case '<=':
|
||||
{
|
||||
return $total_minutes <= intval($gap_size_criteria->getValue());
|
||||
}
|
||||
break;
|
||||
case '>=':
|
||||
{
|
||||
return $total_minutes >= intval($gap_size_criteria->getValue());
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -200,6 +200,15 @@ class ApiEndpointsSeeder extends Seeder
|
||||
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
|
||||
],
|
||||
),
|
||||
array(
|
||||
'name' => 'get-schedule-empty-spots',
|
||||
'route' => '/api/v1/summits/{id}/events/published/empty-spots',
|
||||
'http_method' => 'GET',
|
||||
'scopes' => [
|
||||
sprintf(SummitScopes::ReadSummitData, $current_realm),
|
||||
sprintf(SummitScopes::ReadAllSummitData, $current_realm)
|
||||
],
|
||||
),
|
||||
array(
|
||||
'name' => 'get-unpublished-events',
|
||||
'route' => '/api/v1/summits/{id}/events/unpublished',
|
||||
|
@ -15,7 +15,6 @@ use models\summit\IAbstractCalendarSyncWorkRequestRepository;
|
||||
use models\summit\ICalendarSyncInfoRepository;
|
||||
use models\summit\SummitEvent;
|
||||
use models\summit\CalendarSync\WorkQueue\AdminSummitEventActionSyncWorkRequest;
|
||||
use models\summit\CalendarSync\WorkQueue\AdminSummitLocationActionSyncWorkRequest;
|
||||
use models\summit\CalendarSync\WorkQueue\AbstractCalendarSyncWorkRequest;
|
||||
/**
|
||||
* Class AdminActionsCalendarSyncPreProcessorTest
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright 2015 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -12,6 +11,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use LaravelDoctrine\ORM\Facades\EntityManager;
|
||||
|
||||
/**
|
||||
* Class OAuth2SummitApiTest
|
||||
*/
|
||||
final class OAuth2SummitApiTest extends ProtectedApiTest
|
||||
{
|
||||
|
||||
@ -1897,11 +1901,11 @@ final class OAuth2SummitApiTest extends ProtectedApiTest
|
||||
{
|
||||
$params = array
|
||||
(
|
||||
'id' => $summit_id,
|
||||
'page' => 1,
|
||||
'per_page' => 50,
|
||||
'id' => $summit_id,
|
||||
'page' => 1,
|
||||
'per_page' => 50,
|
||||
'location_id' => 52,
|
||||
'filter' => array
|
||||
'filter' => array
|
||||
(
|
||||
'tags=@Nova',
|
||||
'speaker=@Todd'
|
||||
@ -2460,4 +2464,50 @@ final class OAuth2SummitApiTest extends ProtectedApiTest
|
||||
}
|
||||
|
||||
|
||||
public function testGetScheduleEmptySpotsBySummit()
|
||||
{
|
||||
$summit_repository = EntityManager::getRepository(\models\summit\Summit::class);
|
||||
$summit = $summit_repository->getById(23);
|
||||
$summit_time_zone = $summit->getTimeZone();
|
||||
$start_datetime = new DateTime( "2017-11-04 07:00:00", $summit_time_zone);
|
||||
$end_datetime = new DateTime("2017-11-05 18:00:00", $summit_time_zone);
|
||||
$start_datetime_unix = $start_datetime->getTimestamp();
|
||||
$end_datetime_unix = $end_datetime->getTimestamp();
|
||||
|
||||
$params = [
|
||||
|
||||
'id' => 23,
|
||||
'filter' =>
|
||||
[
|
||||
'location_id==318,location_id==320',
|
||||
'start_date>='.$start_datetime_unix,
|
||||
'end_date<='.$end_datetime_unix,
|
||||
'gap==10',
|
||||
],
|
||||
];
|
||||
|
||||
$headers = [
|
||||
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
"CONTENT_TYPE" => "application/json"
|
||||
];
|
||||
|
||||
$response = $this->action
|
||||
(
|
||||
"GET",
|
||||
"OAuth2SummitEventsApiController@getScheduleEmptySpots",
|
||||
$params,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
$headers
|
||||
);
|
||||
|
||||
$content = $response->getContent();
|
||||
$this->assertResponseStatus(200);
|
||||
|
||||
$gaps = json_decode($content);
|
||||
$this->assertTrue(!is_null($gaps));
|
||||
}
|
||||
|
||||
}
|
97
tests/SearchEmptySpotsTest.php
Normal file
97
tests/SearchEmptySpotsTest.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
use Illuminate\Support\Facades\App;
|
||||
use LaravelDoctrine\ORM\Facades\EntityManager;
|
||||
use App\Models\Utils\IntervalParser;
|
||||
use services\model\ISummitService;
|
||||
use utils\FilterParser;
|
||||
|
||||
/**
|
||||
* Class SearchEmptySpotsTest
|
||||
*/
|
||||
final class SearchEmptySpotsTest extends TestCase
|
||||
{
|
||||
|
||||
public function testIntervalParser2(){
|
||||
$summit_repository = EntityManager::getRepository(\models\summit\Summit::class);
|
||||
$summit = $summit_repository->getById(23);
|
||||
$summit_time_zone = $summit->getTimeZone();
|
||||
$start_datetime = new DateTime( "2017-11-04 07:00:00", $summit_time_zone);
|
||||
$end_datetime = new DateTime("2017-11-05 18:00:00", $summit_time_zone);
|
||||
|
||||
$intervals = IntervalParser::getInterval($start_datetime, $end_datetime);
|
||||
|
||||
$this->assertTrue(count($intervals) == 2);
|
||||
}
|
||||
|
||||
public function testIntervalParse1(){
|
||||
$summit_repository = EntityManager::getRepository(\models\summit\Summit::class);
|
||||
$summit = $summit_repository->getById(23);
|
||||
$summit_time_zone = $summit->getTimeZone();
|
||||
$start_datetime = new DateTime( "2017-11-04 07:00:00", $summit_time_zone);
|
||||
$end_datetime = new DateTime("2017-11-04 18:00:00", $summit_time_zone);
|
||||
|
||||
$intervals = IntervalParser::getInterval($start_datetime, $end_datetime);
|
||||
|
||||
$this->assertTrue(count($intervals) == 1);
|
||||
}
|
||||
|
||||
public function testIntervalParser3(){
|
||||
$summit_repository = EntityManager::getRepository(\models\summit\Summit::class);
|
||||
$summit = $summit_repository->getById(23);
|
||||
$summit_time_zone = $summit->getTimeZone();
|
||||
$start_datetime = new DateTime( "2017-11-04 07:00:00", $summit_time_zone);
|
||||
$end_datetime = new DateTime("2017-11-06 18:00:00", $summit_time_zone);
|
||||
|
||||
$intervals = IntervalParser::getInterval($start_datetime, $end_datetime);
|
||||
|
||||
$this->assertTrue(count($intervals) == 4);
|
||||
}
|
||||
|
||||
public function testFindSpots(){
|
||||
|
||||
$summit_repository = EntityManager::getRepository(\models\summit\Summit::class);
|
||||
$summit = $summit_repository->getById(23);
|
||||
$summit_time_zone = $summit->getTimeZone();
|
||||
$start_datetime = new DateTime( "2017-11-04 07:00:00", $summit_time_zone);
|
||||
$end_datetime = new DateTime("2017-11-05 18:00:00", $summit_time_zone);
|
||||
$start_datetime_unix = $start_datetime->getTimestamp();
|
||||
$end_datetime_unix = $end_datetime->getTimestamp();
|
||||
|
||||
$service = App::make(\services\model\ISummitService::class);
|
||||
if(!$service instanceof ISummitService )
|
||||
return ;
|
||||
|
||||
$filter = FilterParser::parse
|
||||
(
|
||||
[
|
||||
'location_id==318,location_id==320',
|
||||
'start_date>='.$start_datetime_unix,
|
||||
'end_date<='.$end_datetime_unix,
|
||||
'gap==10',
|
||||
],
|
||||
[
|
||||
'location_id' => ['=='],
|
||||
'start_date' => ['>='],
|
||||
'end_date' => ['<='],
|
||||
'gap' => ['>', '<', '<=', '>=', '=='],
|
||||
]
|
||||
);
|
||||
|
||||
$gaps = $service->getSummitScheduleEmptySpots($summit, $filter);
|
||||
|
||||
$this->assertTrue(count($gaps) > 0);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user