Added Member Summit Event Favorites Collecction

* added following endpoints
** add to my favorites
** remove from my favorites
** get my favorites

Change-Id: I6a9ecc82f771f227f7bd28be9cab344a903381bc
This commit is contained in:
Sebastian Marcet 2017-02-09 14:47:36 -03:00
parent cecb957176
commit cf3bd09929
28 changed files with 996 additions and 137 deletions

View File

@ -179,4 +179,24 @@ abstract class AbstractSerializer implements IModelSerializer
return $values;
}
/**
* @param string $expand_str
* @param string $prefix
* @return string
*/
protected static function filterExpandByPrefix($expand_str, $prefix ){
$expand_to = explode(',', $expand_str);
$filtered_expand = array_filter($expand_to, function($element) use($prefix){
return preg_match('/^' . preg_quote($prefix, '/') . '/', strtolower(trim($element))) > 0;
});
$res = '';
foreach($filtered_expand as $filtered_expand_elem){
if(strlen($res) > 0) $res .= ',';
$res .= explode('.', strtolower(trim($filtered_expand_elem)))[1];
}
return $res;
}
}

View File

@ -0,0 +1,50 @@
<?php namespace App\Events;
/**
* 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 models\main\Member;
use models\summit\Summit;
/**
* Class MyFavoritesAdd
* @package App\Events
*/
class MyFavoritesAdd extends SummitEventAction
{
/**
* @var Member
*/
protected $member;
/**
* @var Summit
*/
protected $summit;
/**
* MyFavoritesAdd constructor.
* @param Member $member
* @param Summit $summit
* @param int $event_id
*/
public function __construct($member, $summit, $event_id){
$this->member = $member;
$this->summit = $summit;
parent::__construct($event_id);
}
public function getMember(){ return $this->member; }
public function getSummit(){ return $this->summit;}
}

View File

@ -0,0 +1,22 @@
<?php namespace App\Events;
/**
* 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 MyFavoritesRemove
* @package App\Events
*/
class MyFavoritesRemove extends MyFavoritesAdd
{
}

View File

@ -1,27 +1,19 @@
<?php namespace App\Events;
use Illuminate\Queue\SerializesModels;
use models\summit\SummitAttendee;
/**
* Class MyScheduleAdd
* @package App\Events
*/
class MyScheduleAdd extends Event
class MyScheduleAdd extends SummitEventAction
{
use SerializesModels;
/**
* @var SummitAttendee
*/
protected $attendee;
/**
* @var int
*/
protected $event_id;
/**
* MyScheduleAdd constructor.
* @param SummitAttendee $attendee
@ -30,16 +22,11 @@ class MyScheduleAdd extends Event
function __construct(SummitAttendee $attendee, $event_id)
{
$this->attendee = $attendee;
$this->event_id = $event_id;
parent::__construct($event_id);
}
/**
* @return SummitAttendee
*/
public function getAttendee(){ return $this->attendee;}
/**
* @return int
*/
public function getEventId(){ return $this->event_id;}
}

View File

@ -0,0 +1,45 @@
<?php namespace App\Events;
/**
* 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 Illuminate\Queue\SerializesModels;
/**
* Class SummitEventAction
* @package App\Events
*/
class SummitEventAction extends Event
{
use SerializesModels;
/**
* @var int
*/
protected $event_id;
/**
* SummitEventAction constructor.
* @param int $event_id
*/
function __construct($event_id)
{
$this->event_id = $event_id;
}
/**
* @return int
*/
public function getEventId(){ return $this->event_id;}
}

View File

@ -90,7 +90,17 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
$locations[] = SerializerRegistry::getInstance()->getSerializer($location)->serialize();
}
return $this->ok($locations);
$response = new PagingResponse
(
count($locations),
count($locations),
1,
1,
$locations
);
return $this->ok($response->toArray($expand = Input::get('expand','')));
} catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);
@ -280,7 +290,17 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
$locations[] = SerializerRegistry::getInstance()->getSerializer($location)->serialize();
}
return $this->ok($locations);
$response = new PagingResponse
(
count($locations),
count($locations),
1,
1,
$locations
);
return $this->ok($response->toArray($expand = Input::get('expand','')));
} catch (Exception $ex) {
Log::error($ex);
@ -305,7 +325,17 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
$locations[] = SerializerRegistry::getInstance()->getSerializer($location)->serialize();
}
return $this->ok($locations);
$response = new PagingResponse
(
count($locations),
count($locations),
1,
1,
$locations
);
return $this->ok($response->toArray($expand = Input::get('expand','')));
} catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);
@ -329,7 +359,17 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
$locations[] = SerializerRegistry::getInstance()->getSerializer($location)->serialize();
}
return $this->ok($locations);
$response = new PagingResponse
(
count($locations),
count($locations),
1,
1,
$locations
);
return $this->ok($response->toArray($expand = Input::get('expand','')));
} catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);
@ -354,7 +394,17 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
$locations[] = SerializerRegistry::getInstance()->getSerializer($location)->serialize();
}
return $this->ok($locations);
$response = new PagingResponse
(
count($locations),
count($locations),
1,
1,
$locations
);
return $this->ok($response->toArray($expand = Input::get('expand','')));
} catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);

View File

@ -12,11 +12,17 @@
* limitations under the License.
**/
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Request;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\IMemberRepository;
use models\oauth2\IResourceServerContext;
use models\summit\ISummitRepository;
use ModelSerializers\SerializerRegistry;
use services\model\ISummitService;
use utils\PagingResponse;
use Illuminate\Support\Facades\Input;
/**
* Class OAuth2SummitMembersApiController
@ -29,24 +35,32 @@ final class OAuth2SummitMembersApiController extends OAuth2ProtectedController
*/
private $summit_repository;
/**
* @var ISummitService
*/
private $summit_service;
/**
* OAuth2SummitMembersApiController constructor.
* @param IMemberRepository $member_repository
* @param ISummitRepository $summit_repository
* @param ISummitService $summit_service
* @param IResourceServerContext $resource_server_context
*/
public function __construct
(
IMemberRepository $member_repository,
ISummitRepository $summit_repository,
ISummitService $summit_service,
IResourceServerContext $resource_server_context
) {
parent::__construct($resource_server_context);
$this->summit_repository = $summit_repository;
$this->repository = $member_repository;
$this->summit_service = $summit_service;
}
public function getMyMember($summit_id){
public function getMyMember($summit_id, $member_id){
$summit = SummitFinderStrategyFactory::build($this->summit_repository)->find($summit_id);
if (is_null($summit)) return $this->error404();
@ -60,10 +74,10 @@ final class OAuth2SummitMembersApiController extends OAuth2ProtectedController
$fields = Request::input('fields', null);
$relations = Request::input('relations', null);
return $this->ok
(
SerializerRegistry::getInstance()->getSerializer($current_member)->serialize
SerializerRegistry::getInstance()->getSerializer($current_member, SerializerRegistry::SerializerType_Private)
->serialize
(
Request::input('expand', ''),
is_null($fields) ? [] : explode(',', $fields),
@ -72,4 +86,134 @@ final class OAuth2SummitMembersApiController extends OAuth2ProtectedController
)
);
}
public function getMemberFavoritesSummitEvents($summit_id, $member_id){
try {
$summit = SummitFinderStrategyFactory::build($this->summit_repository)->find($summit_id);
if (is_null($summit)) return $this->error404();
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
if (is_null($current_member_id)) return $this->error403();
$current_member = $this->repository->getById($current_member_id);
if (is_null($current_member)) return $this->error404();
$favorites = array();
foreach ($current_member->getFavoritesSummitEvents() as $favorite_event)
{
if(!$summit->isEventOnSchedule($favorite_event->getId())) continue;
$favorites[] = SerializerRegistry::getInstance()->getSerializer($favorite_event)->serialize();
}
$response = new PagingResponse
(
count($favorites),
count($favorites),
1,
1,
$favorites
);
return $this->ok($response->toArray($expand = Input::get('expand','')));
}
catch (ValidationException $ex1)
{
Log::warning($ex1);
return $this->error412(array( $ex1->getMessage()));
}
catch (EntityNotFoundException $ex2)
{
Log::warning($ex2);
return $this->error404(array('message' => $ex2->getMessage()));
}
catch(\HTTP401UnauthorizedException $ex3)
{
Log::warning($ex3);
return $this->error401();
}
catch (\Exception $ex)
{
Log::error($ex);
return $this->error500($ex);
}
}
public function addEventToMemberFavorites($summit_id, $member_id, $event_id){
try {
$summit = SummitFinderStrategyFactory::build($this->summit_repository)->find($summit_id);
if (is_null($summit)) return $this->error404();
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
if (is_null($current_member_id)) return $this->error403();
$current_member = $this->repository->getById($current_member_id);
if (is_null($current_member)) return $this->error404();
$this->summit_service->addEventToMemberFavorites($summit, $current_member, intval($event_id));
return $this->created();
}
catch (ValidationException $ex1)
{
Log::warning($ex1);
return $this->error412(array( $ex1->getMessage()));
}
catch (EntityNotFoundException $ex2)
{
Log::warning($ex2);
return $this->error404(array('message' => $ex2->getMessage()));
}
catch(\HTTP401UnauthorizedException $ex3)
{
Log::warning($ex3);
return $this->error401();
}
catch (\Exception $ex)
{
Log::error($ex);
return $this->error500($ex);
}
}
public function removeEventFromMemberFavorites($summit_id, $member_id, $event_id){
try {
$summit = SummitFinderStrategyFactory::build($this->summit_repository)->find($summit_id);
if (is_null($summit)) return $this->error404();
$current_member_id = $this->resource_server_context->getCurrentUserExternalId();
if (is_null($current_member_id)) return $this->error403();
$current_member = $this->repository->getById($current_member_id);
if (is_null($current_member)) return $this->error404();
$this->summit_service->removeEventFromMemberFavorites($summit, $current_member, intval($event_id));
return $this->deleted();
}
catch (ValidationException $ex1)
{
Log::warning($ex1);
return $this->error412(array( $ex1->getMessage()));
}
catch (EntityNotFoundException $ex2)
{
Log::warning($ex2);
return $this->error404(array('message' => $ex2->getMessage()));
}
catch(\HTTP401UnauthorizedException $ex3)
{
Log::warning($ex3);
return $this->error401();
}
catch (\Exception $ex)
{
Log::error($ex);
return $this->error500($ex);
}
}
}

View File

@ -43,7 +43,7 @@ final class RateLimitMiddleware
public function __construct(IApiEndpointRepository $endpoint_repository, ICacheService $cache_service)
{
$this->endpoint_repository = $endpoint_repository;
$this->cache_service = $cache_service;
$this->cache_service = $cache_service;
}
/**

View File

@ -14,13 +14,13 @@
use Illuminate\Support\Facades\Config;
//OAuth2 Protected API
Route::group(array(
Route::group([
'namespace' => 'App\Http\Controllers',
'prefix' => 'api/v1',
'before' => [],
'after' => [],
'prefix' => 'api/v1',
'before' => [],
'after' => [],
'middleware' => ['ssl', 'oauth2.protected', 'rate.limit','etags']
), function () {
], function () {
Route::group(array('prefix' => 'marketplace'), function () {
@ -105,11 +105,11 @@ Route::group(array(
Route::group(array('prefix' => '{attendee_id}'), function () {
Route::get('', 'OAuth2SummitAttendeesApiController@getAttendee')->where('attendee_id', 'me|[0-9]+');
Route::get('', 'OAuth2SummitAttendeesApiController@getAttendee')->where('attendee_id', 'me');
Route::group(array('prefix' => 'schedule'), function ()
{
Route::get('', 'OAuth2SummitAttendeesApiController@getAttendeeSchedule')->where('attendee_id', 'me|[0-9]+');
Route::get('', 'OAuth2SummitAttendeesApiController@getAttendeeSchedule')->where('attendee_id', 'me');
Route::group(array('prefix' => '{event_id}'), function (){
Route::post('', 'OAuth2SummitAttendeesApiController@addEventToAttendeeSchedule')->where('attendee_id', 'me|[0-9]+');
@ -198,8 +198,17 @@ Route::group(array(
// member
Route::group(array('prefix' => 'members'), function () {
Route::group(array('prefix' => 'me'), function () {
Route::get('', 'OAuth2SummitMembersApiController@getMyMember');
Route::group(array('prefix' => '{member_id}'), function () {
Route::get('', 'OAuth2SummitMembersApiController@getMyMember')->where('member_id', 'me');
Route::group(array('prefix' => 'favorites'), function ()
{
Route::get('', 'OAuth2SummitMembersApiController@getMemberFavoritesSummitEvents')->where('member_id', 'me');
Route::group(array('prefix' => '{event_id}'), function (){
Route::post('', 'OAuth2SummitMembersApiController@addEventToMemberFavorites')->where('member_id', 'me');
Route::delete('', 'OAuth2SummitMembersApiController@removeEventFromMemberFavorites')->where('member_id', 'me');
});
});
});
});
@ -220,13 +229,13 @@ Route::group(array(
});
//OAuth2 Protected API V2
Route::group(array(
'namespace' => 'App\Http\Controllers',
'prefix' => 'api/v2',
'before' => [],
'after' => [],
Route::group([
'namespace' => 'App\Http\Controllers',
'prefix' => 'api/v2',
'before' => [],
'after' => [],
'middleware' => ['ssl', 'oauth2.protected', 'rate.limit','etags']
), function () {
], function () {
// summits
Route::group(array('prefix' => 'summits'), function () {

View File

@ -0,0 +1,91 @@
<?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 models\main\Member;
use Illuminate\Support\Facades\Config;
/**
* Class AbstractMemberSerializer
* @package ModelSerializers
*/
class AbstractMemberSerializer extends SilverStripeSerializer
{
protected static $array_mappings = [
'FirstName' => 'first_name:json_string',
'LastName' => 'last_name:json_string',
'Gender' => 'gender:json_string',
'Bio' => 'bio:json_string',
'LinkedInProfile' => 'linked_in:json_string',
'IrcHandle' => 'irc:json_string',
'TwitterHandle' => 'twitter:json_string',
'State' => 'state:json_string',
'Country' => 'country:json_string',
];
protected static $allowed_relations = [
'groups',
'affiliations',
];
/**
* @param null $expand
* @param array $fields
* @param array $relations
* @param array $params
* @return array
*/
public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array())
{
$member = $this->object;
if(!$member instanceof Member) return [];
if(!count($relations)) $relations = $this->getAllowedRelations();
$values = parent::serialize($expand, $fields, $relations, $params);
$values['pic'] = Config::get("server.assets_base_url", 'https://www.openstack.org/'). 'profile_images/members/'. $member->getId();
if(in_array('groups', $relations))
$values['groups'] = $member->getGroupsIds();
if(in_array('affiliations', $relations)){
$res = [];
foreach ($member->getAffiliations() as $affiliation){
$res[] = SerializerRegistry::getInstance()
->getSerializer($affiliation)
->serialize('organization');
}
$values['affiliations'] = $res;
}
if (!empty($expand)) {
$exp_expand = explode(',', $expand);
foreach ($exp_expand as $relation) {
switch (trim($relation)) {
case 'groups': {
if(!in_array('groups', $relations)) break;
$groups = [];
unset($values['groups']);
foreach ($member->getGroups() as $g) {
$groups[] = SerializerRegistry::getInstance()->getSerializer($g)->serialize(null, [], ['none']);
}
$values['groups'] = $groups;
}
break;
}
}
}
return $values;
}
}

View File

@ -53,6 +53,14 @@ final class ChatTeamMemberSerializer extends SilverStripeSerializer
}
}
break;
case 'team': {
if (isset($values['team_id'])) {
unset($values['team_id']);
$values['team'] = SerializerRegistry::getInstance()->getSerializer($team_member->getTeam())->serialize(self::filterExpandByPrefix($expand, 'team.'));
}
}
break;
}
}
}

View File

@ -77,7 +77,7 @@ final class ChatTeamSerializer extends SilverStripeSerializer
// add pending invitations
$invitations = [];
foreach($team->getInvitations() as $invitation){
$invitations[] = SerializerRegistry::getInstance()->getSerializer($invitation)->serialize('inviter,invitee,');
$invitations[] = SerializerRegistry::getInstance()->getSerializer($invitation)->serialize('inviter,invitee');
}
$values['invitations'] = $invitations;
}

View File

@ -1,6 +1,6 @@
<?php namespace ModelSerializers;
/**
* Copyright 2016 OpenStack Foundation
* 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
@ -11,33 +11,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Illuminate\Support\Facades\Config;
use models\main\Member;
/**
* Class MemberSerializer
* Class OwnMemberSerializer
* @package ModelSerializers
*/
final class MemberSerializer extends SilverStripeSerializer
final class OwnMemberSerializer extends AbstractMemberSerializer
{
protected static $array_mappings = [
'FirstName' => 'first_name:json_string',
'LastName' => 'last_name:json_string',
'Gender' => 'gender:json_string',
'Bio' => 'bio:json_string',
'LinkedInProfile' => 'linked_in:json_string',
'IrcHandle' => 'irc:json_string',
'TwitterHandle' => 'twitter:json_string',
];
protected static $allowed_relations = [
'groups',
'team_memberships',
'groups_events',
'feedback',
'affiliations',
'favorite_summit_events'
];
private static $expand_group_events = [
@ -64,16 +50,11 @@ final class MemberSerializer extends SilverStripeSerializer
if(!count($relations)) $relations = $this->getAllowedRelations();
$values = parent::serialize($expand, $fields, $relations, $params);
$values['pic'] = Config::get("server.assets_base_url", 'https://www.openstack.org/'). 'profile_images/members/'. $member->getId();
$summit = isset($params['summit'])? $params['summit'] :null;
$speaker = !is_null($summit)? $summit->getSpeakerByMember($member): null;
$attendee = !is_null($summit)? $summit->getAttendeeByMember($member): null;
$groups_events = !is_null($summit)? $summit->getGroupEventsFor($member): null;
if(in_array('groups', $relations))
$values['groups'] = $member->getGroupsIds();
if(!is_null($speaker))
$values['speaker_id'] = $speaker->getId();
@ -90,14 +71,22 @@ final class MemberSerializer extends SilverStripeSerializer
$values['groups_events'] = $res;
}
if(in_array('affiliations', $relations)){
if(in_array('team_memberships', $relations)){
$res = [];
foreach ($member->getAffiliations() as $affiliation){
foreach ($member->getTeamMemberships() as $team_membership){
$res[] = SerializerRegistry::getInstance()
->getSerializer($affiliation)
->serialize('organization');
->getSerializer($team_membership)
->serialize('team,team.member');
}
$values['affiliations'] = $res;
$values['team_memberships'] = $res;
}
if(in_array('favorite_summit_events', $relations) && !is_null($summit)){
$res = [];
foreach ($member->getFavoritesEventsIds($summit) as $event_id){
$res[] = intval($event_id);
}
$values['favorite_summit_events'] = $res;
}
if (!empty($expand)) {
@ -131,20 +120,21 @@ final class MemberSerializer extends SilverStripeSerializer
$values['feedback'] = $feedback;
}
break;
case 'groups': {
if(!in_array('groups', $relations)) break;
$groups = [];
unset($values['groups']);
foreach ($member->getGroups() as $g) {
$groups[] = SerializerRegistry::getInstance()->getSerializer($g)->serialize(null, [], ['none']);
case 'favorite_summit_events':{
if(!in_array('favorite_summit_events', $relations)) break;
if(is_null($summit)) break;
$favorites = [];
foreach ($member->getFavoritesSummitEvents($summit) as $events){
$favorites[] = SerializerRegistry::getInstance()
->getSerializer($events)
->serialize($expand);
}
$values['groups'] = $groups;
$values['favorite_summit_events'] = $favorites;
}
break;
}
}
}
return $values;
}
}

View File

@ -0,0 +1,22 @@
<?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.
**/
/**
* Class PublicMemberSerializer
* @package ModelSerializers
*/
final class PublicMemberSerializer extends AbstractMemberSerializer
{
}

View File

@ -34,6 +34,8 @@ final class SerializerRegistry
*/
private static $instance;
const SerializerType_Public = 'PUBLIC';
const SerializerType_Private = 'PRIVATE';
private function __clone()
{
@ -47,7 +49,6 @@ final class SerializerRegistry
if (!is_object(self::$instance)) {
self::$instance = new SerializerRegistry();
}
return self::$instance;
}
@ -88,7 +89,10 @@ final class SerializerRegistry
$this->registry['SummitLocationImage'] = SummitLocationImageSerializer::class;
// member
$this->registry['Member'] = MemberSerializer::class;
$this->registry['Member'] = [
self::SerializerType_Public => PublicMemberSerializer::class,
self::SerializerType_Private => OwnMemberSerializer::class
];
$this->registry['Group'] = GroupSerializer::class;
$this->registry['Affiliation'] = AffiliationSerializer::class;
$this->registry['Organization'] = OrganizationSerializer::class;
@ -105,15 +109,24 @@ final class SerializerRegistry
/**
* @param object $object
* @param string $type
* @return IModelSerializer
*/
public function getSerializer($object){
public function getSerializer($object, $type = self::SerializerType_Public){
$reflect = new \ReflectionClass($object);
$class = $reflect->getShortName();
if(!isset($this->registry[$class]))
throw new \InvalidArgumentException('Serializer not found for '.$class);
$serializer_class = $this->registry[$class];
if(is_array($serializer_class)){
if(!isset($serializer_class[$type]))
throw new \InvalidArgumentException(sprintf('Serializer not found for %s , type %s', $class, $type));
$serializer_class = $serializer_class[$type];
}
return new $serializer_class($object);
}
}

View File

@ -14,6 +14,7 @@
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use models\exceptions\ValidationException;
use models\summit\Summit;
use models\summit\SummitEvent;
use models\summit\SummitEventFeedback;
@ -28,11 +29,16 @@ use models\utils\SilverstripeBaseModel;
*/
class Member extends SilverstripeBaseModel
{
/**
* Member constructor.
*/
public function __construct(){
parent::__construct();
$this->feedback = new ArrayCollection();
$this->groups = new ArrayCollection();
$this->affiliations = new ArrayCollection();
$this->feedback = new ArrayCollection();
$this->groups = new ArrayCollection();
$this->affiliations = new ArrayCollection();
$this->team_memberships = new ArrayCollection();
$this->favorites_summit_events = new ArrayCollection();
}
/**
@ -50,6 +56,22 @@ class Member extends SilverstripeBaseModel
return $this->groups;
}
/**
* @return ChatTeamMember[]
*/
public function getTeamMemberships()
{
return $this->team_memberships;
}
/**
* @param ChatTeamMember[] $team_memberships
*/
public function setTeamMemberships($team_memberships)
{
$this->team_memberships = $team_memberships;
}
/**
* @param mixed $groups
*/
@ -68,6 +90,39 @@ class Member extends SilverstripeBaseModel
*/
private $groups;
/**
* @ORM\OneToMany(targetEntity="ChatTeamMember", mappedBy="member", cascade={"persist"}, orphanRemoval=true)
* @var ChatTeamMember[]
*/
private $team_memberships;
/**
* @return SummitEvent[]
*/
public function getFavoritesSummitEvents()
{
return $this->favorites_summit_events;
}
/**
* @param SummitEvent[] $favorites_summit_events
*/
public function setFavoritesSummitEvents($favorites_summit_events)
{
$this->favorites_summit_events = $favorites_summit_events;
}
/**
* @ORM\ManyToMany(targetEntity="models\summit\SummitEvent")
* @ORM\JoinTable(name="Member_FavoriteSummitEvents",
* joinColumns={@ORM\JoinColumn(name="MemberID", referencedColumnName="ID")},
* inverseJoinColumns={@ORM\JoinColumn(name="SummitEventID", referencedColumnName="ID")}
* )
* @var SummitEvent[]
*/
private $favorites_summit_events;
/**
* @return string
*/
@ -118,6 +173,82 @@ class Member extends SilverstripeBaseModel
*/
private $bio;
/**
* @ORM\Column(name="State", type="string")
* @var string
*/
private $state;
/**
* @return string
*/
public function getState()
{
return $this->state;
}
/**
* @param string $state
*/
public function setState($state)
{
$this->state = $state;
}
/**
* @return string
*/
public function getCountry()
{
return $this->country;
}
/**
* @param string $country
*/
public function setCountry($country)
{
$this->country = $country;
}
/**
* @return string
*/
public function getSecondEmail()
{
return $this->second_email;
}
/**
* @param string $second_email
*/
public function setSecondEmail($second_email)
{
$this->second_email = $second_email;
}
/**
* @return string
*/
public function getThirdEmail()
{
return $this->third_email;
}
/**
* @param string $third_email
*/
public function setThirdEmail($third_email)
{
$this->third_email = $third_email;
}
/**
* @ORM\Column(name="Country", type="string")
* @var string
*/
private $country;
/**
* @ORM\Column(name="Email", type="string")
* @var string
@ -373,4 +504,73 @@ class Member extends SilverstripeBaseModel
}
return $codes;
}
/**
* @param SummitEvent $event
* @throws ValidationException
*/
public function addFavoriteSummitEvent(SummitEvent $event){
if($this->isOnFavorite($event))
throw new ValidationException
(
sprintf('Event %s already belongs to member %s favorites.', $event->getId(), $this->getId())
);
if(!$event->isPublished())
throw new ValidationException
(
sprintf('Event %s is not published', $event->getId())
);
$this->favorites_summit_events->add($event);
}
/**
* @param SummitEvent $event
* @return bool
*/
public function isOnFavorite(SummitEvent $event){
$sql = <<<SQL
SELECT COUNT(SummitEventID) AS QTY
FROM Member_FavoriteSummitEvents
WHERE MemberID = :member_id AND SummitEventID = :event_id
SQL;
$stmt = $this->prepareRawSQL($sql);
$stmt->execute([
'member_id' => $this->getId(),
'event_id' => $event->getId()
]);
$res = $stmt->fetchAll(\PDO::FETCH_COLUMN);
return count($res) > 0 ? intval($res[0]) > 0 : false;
}
/**
* @param SummitEvent $event
* @throws ValidationException
*/
public function removeFavoriteSummitEvent(SummitEvent $event){
if(!$this->isOnFavorite($event)){
throw new ValidationException
(
sprintf('Event %s does not belongs to member %s favorites.', $event->getId(), $this->getId())
);
}
$this->favorites_summit_events->removeElement($event);
}
/**
* @return int[]
*/
public function getFavoritesEventsIds(){
$sql = <<<SQL
SELECT SummitEventID
FROM Member_FavoriteSummitEvents
INNER JOIN SummitEvent ON SummitEvent.ID = Member_FavoriteSummitEvents.SummitEventID
WHERE MemberID = :member_id AND SummitEvent.Published = 1
SQL;
$stmt = $this->prepareRawSQL($sql);
$stmt->execute(['member_id' => $this->getId()]);
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
}
}

View File

@ -179,6 +179,12 @@ class SummitAttendee extends SilverstripeBaseModel
sprintf('Event %s already belongs to attendee %s schedule.', $event->getId(), $this->getId())
);
if(!$event->isPublished())
throw new ValidationException
(
sprintf('Event %s is not published', $event->getId())
);
$schedule = new SummitAttendeeSchedule;
$schedule->setAttendee($this);

View File

@ -156,8 +156,9 @@ final class SummitEntityEventProcessContext
foreach ($ops as $op) {
if (!is_null($last_idx))
unset($this->list[$last_idx]);
$last_op = $op['op'];
$last_idx = intval($op['idx']);
$last_op = $op['op'];
$last_idx = intval($op['idx']);
$must_insert = !$must_insert && $last_op === 'INSERT' ? true : $must_insert;
}
$last_op = $must_insert && $last_op !== 'DELETE' ? 'INSERT' : $last_op;

View File

@ -68,6 +68,7 @@ final class EntityEventTypeFactory
}
break;
case 'MySchedule':
case 'MyFavorite':
{
return new MyScheduleEntityEventType($e, $ctx);
}
@ -77,11 +78,6 @@ final class EntityEventTypeFactory
return new SummitEntityEventType($e, $ctx);
}
break;
case 'SummitType':
{
return new SummitTypeEntityEventType($e, $ctx);
}
break;
case 'SummitEventType':
{
return new SummitEventTypeEntityEventType($e, $ctx);

View File

@ -1,5 +1,6 @@
<?php namespace App\Providers;
use App\Events\MyFavoritesAdd;
use App\Events\SummitEventCreated;
use App\Events\SummitEventDeleted;
use App\Events\SummitEventUpdated;
@ -43,8 +44,6 @@ class EventServiceProvider extends ServiceProvider
Event::listen(\App\Events\MyScheduleAdd::class, function($event)
{
if(!$event instanceof MyScheduleAdd) return;
$entity_event = new SummitEntityEvent;
$entity_event->setEntityClassName('MySchedule');
$entity_event->setEntityId($event->getEventId());
@ -58,10 +57,23 @@ class EventServiceProvider extends ServiceProvider
$em->flush();
});
Event::listen(\App\Events\MyFavoritesAdd::class, function($event)
{
$entity_event = new SummitEntityEvent;
$entity_event->setEntityClassName('MyFavorite');
$entity_event->setEntityId($event->getEventId());
$entity_event->setType('INSERT');
$entity_event->setOwner($event->getMember());
$entity_event->setSummit($event->getSummit());
$entity_event->setMetadata('');
$em = Registry::getManager('ss');
$em->persist($entity_event);
$em->flush();
});
Event::listen(\App\Events\MyScheduleRemove::class, function($event)
{
if(!$event instanceof MyScheduleRemove) return;
$entity_event = new SummitEntityEvent;
$entity_event->setEntityClassName('MySchedule');
$entity_event->setEntityId($event->getEventId());
@ -76,10 +88,25 @@ class EventServiceProvider extends ServiceProvider
});
Event::listen(\App\Events\MyFavoritesRemove::class, function($event)
{
$entity_event = new SummitEntityEvent;
$entity_event->setEntityClassName('MyFavorite');
$entity_event->setEntityId($event->getEventId());
$entity_event->setType('DELETE');
$entity_event->setOwner($event->getMember());
$entity_event->setSummit($event->getSummit());
$entity_event->setMetadata('');
$em = Registry::getManager('ss');
$em->persist($entity_event);
$em->flush();
});
Event::listen(\App\Events\SummitEventCreated::class, function($event)
{
if(!$event instanceof SummitEventCreated) return;
$resource_server_context = App::make(\models\oauth2\IResourceServerContext::class);
$member_repository = App::make(\models\main\IMemberRepository::class);
$owner_id = $resource_server_context->getCurrentUserExternalId();

View File

@ -39,11 +39,11 @@ final class DoctrineSummitEntityEventRepository
public function getEntityEvents
(
Summit $summit,
$member_id = null,
$from_id = null,
$member_id = null,
$from_id = null,
DateTime $from_date = null,
$limit = 25,
$detach = true
$limit = 25,
$detach = true
)
{
$filters = '';
@ -65,7 +65,7 @@ SELECT * FROM
SELECT * FROM SummitEntityEvent
WHERE
(
(EntityClassName <> 'MySchedule' AND EntityClassName <> 'SummitAttendee')
(EntityClassName <> 'MySchedule' AND EntityClassName <> 'SummitAttendee' AND EntityClassName <> 'MyFavorite')
-- GLOBAL TRUNCATE
OR (EntityClassName = 'WipeData' AND EntityID = 0)
)
@ -84,7 +84,7 @@ SELECT * FROM
SELECT * FROM SummitEntityEvent
WHERE
(
EntityClassName = 'MySchedule'
EntityClassName = 'MySchedule' OR EntityClassName = 'MyFavorite'
AND OwnerID = {$member_id}
)
AND SummitID = {$summit->getId()}

View File

@ -1,9 +1,11 @@
<?php namespace services\model;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\Member;
use models\summit\ConfirmationExternalOrderRequest;
use models\summit\Summit;
use models\summit\SummitAttendee;
use models\summit\SummitEntityEvent;
use models\summit\SummitEvent;
use models\summit\SummitEventFeedback;
@ -19,6 +21,11 @@ use models\summit\SummitEventFeedback;
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Interface ISummitService
* @package services\model
*/
interface ISummitService
{
/**
@ -112,4 +119,23 @@ interface ISummitService
* @return SummitAttendee
*/
public function confirmExternalOrderAttendee(ConfirmationExternalOrderRequest $request);
/**
* @param Summit $summit
* @param Member $member
* @param int $event_id
* @throws EntityNotFoundException
*/
public function removeEventFromMemberFavorites(Summit $summit, Member $member, $event_id);
/**
* @param Summit $summit
* @param Member $member
* @param int $event_id
* @throws ValidationException
* @throws EntityNotFoundException
*/
public function addEventToMemberFavorites(Summit $summit, Member $member, $event_id);
}

View File

@ -13,6 +13,8 @@
* limitations under the License.
**/
use App\Events\MyFavoritesAdd;
use App\Events\MyFavoritesRemove;
use App\Events\MyScheduleAdd;
use App\Events\MyScheduleRemove;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
@ -24,6 +26,7 @@ use models\main\IMemberRepository;
use models\main\ITagRepository;
use Models\foundation\summit\EntityEvents\EntityEventTypeFactory;
use Models\foundation\summit\EntityEvents\SummitEntityEventProcessContext;
use models\main\Member;
use models\main\Tag;
use models\summit\ConfirmationExternalOrderRequest;
use models\summit\ISpeakerRepository;
@ -165,6 +168,34 @@ final class SummitService implements ISummitService
}
}
/**
* @param Summit $summit
* @param Member $member
* @param int $event_id
* @throws ValidationException
* @throws EntityNotFoundException
*/
public function addEventToMemberFavorites(Summit $summit, Member $member, $event_id){
try {
$this->tx_service->transaction(function () use ($summit, $member, $event_id) {
$event = $summit->getScheduleEvent($event_id);
if (is_null($event)) {
throw new EntityNotFoundException('event not found on summit!');
}
if(!Summit::allowToSee($event, $member))
throw new EntityNotFoundException('event not found on summit!');
$member->addFavoriteSummitEvent($event);
});
Event::fire(new MyFavoritesAdd($member, $summit, $event_id));
}
catch (UniqueConstraintViolationException $ex){
throw new ValidationException
(
sprintf('Event %s already belongs to member %s favorites.', $event_id, $member->getId())
);
}
}
/**
* @param Summit $summit
* @param SummitAttendee $attendee
@ -203,6 +234,24 @@ final class SummitService implements ISummitService
Event::fire(new MyScheduleRemove($attendee, $event_id));
}
/**
* @param Summit $summit
* @param Member $member
* @param int $event_id
* @throws EntityNotFoundException
*/
public function removeEventFromMemberFavorites(Summit $summit, Member $member, $event_id){
$this->tx_service->transaction(function () use ($summit, $member, $event_id) {
$event = $summit->getScheduleEvent($event_id);
if (is_null($event))
throw new EntityNotFoundException('event not found on summit!');
$member->removeFavoriteSummitEvent($event);
});
Event::fire(new MyFavoritesRemove($member, $summit, $event_id));
}
/**
* @param Summit $summit
* @param SummitEvent $event

View File

@ -453,10 +453,28 @@ class ApiEndpointsSeeder extends Seeder
//members
array(
'name' => 'get-own-member',
'route' => '/api/v1/summits/{id}/members/me',
'route' => '/api/v1/summits/{id}/members/{member_id}',
'http_method' => 'GET',
'scopes' => [sprintf('%s/me/read', $current_realm)],
),
array(
'name' => 'get-own-member-favorites',
'route' => '/api/v1/summits/{id}/members/{member_id}/favorites',
'http_method' => 'GET',
'scopes' => [sprintf('%s/me/read', $current_realm)],
),
array(
'name' => 'add-2-own-member-favorites',
'route' => '/api/v1/summits/{id}/members/{member_id}/favorites/{event_id}',
'http_method' => 'POST',
'scopes' => [sprintf('%s/me/summits/events/favorites/add', $current_realm)],
),
array(
'name' => 'remove-from-own-member-favorites',
'route' => '/api/v1/summits/{id}/members/{member_id}/favorites/{event_id}',
'http_method' => 'DELETE',
'scopes' => [sprintf('%s/me/summits/events/favorites/delete', $current_realm)],
),
// notifications
array(
'name' => 'get-notifications',

View File

@ -105,8 +105,18 @@ final class ApiScopesSeeder extends Seeder
),
array(
'name' => sprintf('%s/me/read', $current_realm),
'short_description' => 'Get own member data',
'description' => 'Grants read only access for our own member data',
'short_description' => 'Get own summit member data',
'description' => 'Grants read only access for our own summit member data',
),
array(
'name' => sprintf('%s/me/summits/events/favorites/add', $current_realm),
'short_description' => 'Allows to add Summit events as favorite',
'description' => 'Allows to add Summit events as favorite',
),
array(
'name' => sprintf('%s/me/summits/events/favorites/delete', $current_realm),
'short_description' => 'Allows to remove Summit events as favorite',
'description' => 'Allows to remove Summit events as favorite',
),
array(
'name' => sprintf('%s/summits/write', $current_realm),

View File

@ -22,7 +22,7 @@ final class OAuth2MembersApiTest extends ProtectedApiTest
//AND FILTER
'filter' => 'first_name=@Seba',
'filter' => 'last_name=@Marcet',
'order' => '+first_name,-last_name'
'order' => '+first_name,-last_name'
];
$headers = array("HTTP_Authorization" => " Bearer " . $this->access_token);

View File

@ -109,7 +109,7 @@ final class OAuth2SummitApiTest extends ProtectedApiTest
array(),
$headers
);
$end = time();
$end = time();
$delta = $end - $start;
echo "execution call " . $delta . " seconds ...";
$content = $response->getContent();
@ -1216,7 +1216,7 @@ final class OAuth2SummitApiTest extends ProtectedApiTest
{
$params = array
(
'id' => 'current',
'id' => '7',
'from_date' => 1460148342,
'limit' => 100
);
@ -1278,7 +1278,7 @@ final class OAuth2SummitApiTest extends ProtectedApiTest
$this->assertTrue(!is_null($events));
}
public function testGetEntityEventsFromCurrentSummitGreaterThanGivenID($summit_id = 7, $last_event_id = 665707)
public function testGetEntityEventsFromCurrentSummitGreaterThanGivenID($summit_id = 7, $last_event_id = 702471)
{
$params = array
(
@ -1997,32 +1997,6 @@ final class OAuth2SummitApiTest extends ProtectedApiTest
}
public function testGetMyMemberFromCurrentSummit()
{
$params = [
'expand' => 'attendee,speaker,feedback,groups, presentations',
'id' => 7,
];
$headers = array("HTTP_Authorization" => " Bearer " . $this->access_token);
$response = $this->action(
"GET",
"OAuth2SummitMembersApiController@getMyMember",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(200);
$member = json_decode($content);
$this->assertTrue(!is_null($member));
}
public function testGetSummitNotifications()
{
@ -2134,4 +2108,101 @@ final class OAuth2SummitApiTest extends ProtectedApiTest
$events = json_decode($content);
$this->assertTrue(!is_null($events));
}
public function testAdd2Favorite($summit_id = 7, $event_id = 14964){
$params = array
(
'id' => $summit_id,
'member_id' => 'me',
'event_id' => $event_id
);
$headers = array("HTTP_Authorization" => " Bearer " . $this->access_token);
$response = $this->action(
"POST",
"OAuth2SummitMembersApiController@addEventToMemberFavorites",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(201);
}
public function testRemoveFromFavorites($summit_id = 7, $event_id = 14964){
$params = array
(
'id' => $summit_id,
'member_id' => 'me',
'event_id' => $event_id
);
$headers = array("HTTP_Authorization" => " Bearer " . $this->access_token);
$response = $this->action(
"DELETE",
"OAuth2SummitMembersApiController@removeEventFromMemberFavorites",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(204);
}
public function testGetMyFavorites(){
$params = [
'member_id' => 'me',
'id' => 7,
];
$headers = array("HTTP_Authorization" => " Bearer " . $this->access_token);
$response = $this->action(
"GET",
"OAuth2SummitMembersApiController@getMemberFavoritesSummitEvents",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(200);
$favorites = json_decode($content);
$this->assertTrue(!is_null($favorites));
}
public function testGetMyMemberFromCurrentSummit()
{
$params = [
'expand' => 'attendee,speaker,feedback,groups,presentations',
'member_id' => 'me',
'id' => 7,
];
$headers = array("HTTP_Authorization" => " Bearer " . $this->access_token);
$response = $this->action(
"GET",
"OAuth2SummitMembersApiController@getMyMember",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(200);
$member = json_decode($content);
$this->assertTrue(!is_null($member));
}
}

View File

@ -53,9 +53,11 @@ class AccessTokenServiceStub implements IAccessTokenService
$url . '/members/invitations/write',
$url . '/teams/read',
$url . '/teams/write',
$url . '/me/summits/events/favorites/add',
$url . '/me/summits/events/favorites/delete',
);
return AccessToken::createFromParams('123456789', implode(' ', $scopes), '1', $realm, '1','11624', 3600, 'WEB_APPLICATION', '', '');
return AccessToken::createFromParams('123456789', implode(' ', $scopes), '1', $realm, '1','13867', 3600, 'WEB_APPLICATION', '', '');
}
}
@ -93,6 +95,8 @@ class AccessTokenServiceStub2 implements IAccessTokenService
$url . '/members/invitations/write',
$url . '/teams/read',
$url . '/teams/write',
$url . '/me/summits/events/favorites/add',
$url . '/me/summits/events/favorites/delete',
);
return AccessToken::createFromParams('123456789', implode(' ', $scopes), '1', $realm, null,null, 3600, 'SERVICE', '', '');