From b2faf65f5a20d3ff162bded03c7608f6d2f96abb Mon Sep 17 00:00:00 2001 From: Sebastian Marcet Date: Tue, 12 Dec 2017 10:26:03 -0300 Subject: [PATCH] Added private serializer for Speakers Change-Id: I6c5faaeb45e36d3177809400ac744268f517f537 --- Libs/ModelSerializers/AbstractSerializer.php | 10 +-- .../OAuth2SummitSpeakersApiController.php | 69 +++++++++++++++++-- app/Http/Utils/PagingResponse.php | 11 +-- .../AdminPresentationSpeakerSerializer.php | 52 ++++++++++++++ .../PresentationSpeakerSerializer.php | 22 +++--- ...ssistanceConfirmationRequestSerializer.php | 28 ++++++++ app/ModelSerializers/SerializerRegistry.php | 26 ++++--- ...rSummitRegistrationPromoCodeSerializer.php | 25 +++++++ .../SummitRegistrationPromoCodeSerializer.php | 27 ++++++++ app/Models/Foundation/Main/Group.php | 1 + app/Models/Foundation/Main/Member.php | 35 +++++++++- .../Presentations/PresentationSpeaker.php | 10 +++ ...kerSummitAssistanceConfirmationRequest.php | 26 +++---- .../SpeakerSummitRegistrationPromoCode.php | 12 ++++ tests/OAuth2SummitApiTest.php | 5 +- 15 files changed, 301 insertions(+), 58 deletions(-) create mode 100644 app/ModelSerializers/AdminPresentationSpeakerSerializer.php create mode 100644 app/ModelSerializers/PresentationSpeakerSummitAssistanceConfirmationRequestSerializer.php create mode 100644 app/ModelSerializers/SpeakerSummitRegistrationPromoCodeSerializer.php create mode 100644 app/ModelSerializers/SummitRegistrationPromoCodeSerializer.php diff --git a/Libs/ModelSerializers/AbstractSerializer.php b/Libs/ModelSerializers/AbstractSerializer.php index e12c4111..1cf1db7f 100644 --- a/Libs/ModelSerializers/AbstractSerializer.php +++ b/Libs/ModelSerializers/AbstractSerializer.php @@ -36,18 +36,18 @@ abstract class AbstractSerializer implements IModelSerializer } - protected static $array_mappings = array(); + protected static $array_mappings = []; - protected static $allowed_fields = array(); + protected static $allowed_fields = []; - protected static $allowed_relations = array(); + protected static $allowed_relations = []; /** * @return array */ protected function getAllowedFields() { - $mappings = array(); + $mappings = []; $hierarchy = $this->getClassHierarchy(); foreach($hierarchy as $class_name){ @@ -89,7 +89,7 @@ abstract class AbstractSerializer implements IModelSerializer */ private function getAttributeMappings() { - $mappings = array(); + $mappings = []; $hierarchy = $this->getClassHierarchy(); foreach($hierarchy as $class_name){ diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php index 6d844a97..824c6d84 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSpeakersApiController.php @@ -19,6 +19,8 @@ use Illuminate\Support\Facades\Validator; use libs\utils\HTMLCleaner; use models\exceptions\EntityNotFoundException; use models\exceptions\ValidationException; +use models\main\Group; +use models\main\IMemberRepository; use models\oauth2\IResourceServerContext; use models\summit\IEventFeedbackRepository; use models\summit\ISpeakerRepository; @@ -58,13 +60,29 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController */ private $event_feedback_repository; + /** + * @var IMemberRepository + */ + private $member_repository; + + /** + * OAuth2SummitSpeakersApiController constructor. + * @param ISummitRepository $summit_repository + * @param ISummitEventRepository $event_repository + * @param ISpeakerRepository $speaker_repository + * @param IEventFeedbackRepository $event_feedback_repository + * @param IMemberRepository $member_repository + * @param ISpeakerService $service + * @param IResourceServerContext $resource_server_context + */ public function __construct ( ISummitRepository $summit_repository, ISummitEventRepository $event_repository, ISpeakerRepository $speaker_repository, IEventFeedbackRepository $event_feedback_repository, + IMemberRepository $member_repository, ISpeakerService $service, IResourceServerContext $resource_server_context ) { @@ -72,6 +90,7 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController $this->repository = $summit_repository; $this->speaker_repository = $speaker_repository; $this->event_repository = $event_repository; + $this->member_repository = $member_repository; $this->event_feedback_repository = $event_feedback_repository; $this->service = $service; } @@ -87,8 +106,8 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController public function getSpeakers($summit_id) { try { - - $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); + $serializer_type = SerializerRegistry::SerializerType_Public; + $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); $values = Input::all(); @@ -140,17 +159,28 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController )); } + $current_member_id = $this->resource_server_context->getCurrentUserId(); + if(!is_null($current_member_id) && $member = $this->member_repository->getById($current_member_id)){ + if($member->isOnGroup(Group::SummitAdministrators)){ + $serializer_type = SerializerRegistry::SerializerType_Private; + } + } $result = $this->speaker_repository->getSpeakersBySummit($summit, new PagingInfo($page, $per_page), $filter, $order); return $this->ok ( - $result->toArray(Request::input('expand', ''),[],[],['summit_id' => $summit_id, 'published' => true]) + $result->toArray(Request::input('expand', ''),[],[],['summit_id' => $summit_id, 'published' => true, 'summit' => $summit], $serializer_type) ); } catch(FilterParserException $ex1){ Log::warning($ex1); return $this->error412($ex1->getMessages()); } + catch(EntityNotFoundException $ex2) + { + Log::warning($ex2); + return $this->error404(array('message'=> $ex2->getMessage())); + } catch (Exception $ex) { Log::error($ex); @@ -222,6 +252,11 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController Log::warning($ex1); return $this->error412($ex1->getMessages()); } + catch(EntityNotFoundException $ex2) + { + Log::warning($ex2); + return $this->error404(array('message'=> $ex2->getMessage())); + } catch (Exception $ex) { Log::error($ex); @@ -238,16 +273,38 @@ final class OAuth2SummitSpeakersApiController extends OAuth2ProtectedController { try { - + $serializer_type = SerializerRegistry::SerializerType_Public; $summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); $speaker = CheckSpeakerStrategyFactory::build(CheckSpeakerStrategyFactory::Me, $this->resource_server_context)->check($speaker_id, $summit); if (is_null($speaker)) return $this->error404(); - return $this->ok(SerializerRegistry::getInstance()->getSerializer($speaker)->serialize(Request::input('expand', ''))); + $current_member_id = $this->resource_server_context->getCurrentUserId(); + if(!is_null($current_member_id) && $member = $this->member_repository->getById($current_member_id)){ + if($member->isOnGroup(Group::SummitAdministrators)){ + $serializer_type = SerializerRegistry::SerializerType_Private; + } + } - } catch (Exception $ex) { + return $this->ok + ( + SerializerRegistry::getInstance()->getSerializer($speaker, $serializer_type)->serialize + ( + Request::input('expand', ''), + [], + [], + ['summit_id' => $summit_id, 'published' => true, 'summit' => $summit] + ) + ); + + } + catch(EntityNotFoundException $ex2) + { + Log::warning($ex2); + return $this->error404(array('message'=> $ex2->getMessage())); + } + catch (Exception $ex) { Log::error($ex); return $this->error500($ex); } diff --git a/app/Http/Utils/PagingResponse.php b/app/Http/Utils/PagingResponse.php index 70fc75e5..02ee74b6 100644 --- a/app/Http/Utils/PagingResponse.php +++ b/app/Http/Utils/PagingResponse.php @@ -101,27 +101,28 @@ final class PagingResponse * @param array $fields * @param array $relations * @param array $params + * @param string $serializer_type * @return array */ - public function toArray($expand = null, array $fields = [], array $relations = [], array $params = [] ) + public function toArray($expand = null, array $fields = [], array $relations = [], array $params = [], $serializer_type = SerializerRegistry::SerializerType_Public ) { $items = []; foreach($this->items as $i) { if($i instanceof IEntity) { - $i = SerializerRegistry::getInstance()->getSerializer($i)->serialize($expand, $fields, $relations, $params); + $i = SerializerRegistry::getInstance()->getSerializer($i, $serializer_type)->serialize($expand, $fields, $relations, $params); } $items[] = $i; } - return array - ( + return + [ 'total' => $this->total, 'per_page' => $this->per_page, 'current_page' => $this->page, 'last_page' => $this->last_page, 'data' => $items, - ); + ]; } } \ No newline at end of file diff --git a/app/ModelSerializers/AdminPresentationSpeakerSerializer.php b/app/ModelSerializers/AdminPresentationSpeakerSerializer.php new file mode 100644 index 00000000..93ffd57c --- /dev/null +++ b/app/ModelSerializers/AdminPresentationSpeakerSerializer.php @@ -0,0 +1,52 @@ +getAllowedRelations(); + + $speaker = $this->object; + if(!$speaker instanceof PresentationSpeaker) return []; + + $values = parent::serialize($expand, $fields, $relations, $params); + $summit = isset($params['summit'])? $params['summit']:null; + + if(!is_null($summit)){ + $summit_assistance = $speaker->getAssistanceFor($summit); + if($summit_assistance){ + $values['summit_assistance'] = SerializerRegistry::getInstance()->getSerializer($summit_assistance)->serialize(); + } + $registration_code = $speaker->getPromoCodeFor($summit); + if($registration_code){ + $values['registration_code'] = SerializerRegistry::getInstance()->getSerializer($registration_code)->serialize(); + } + } + return $values; + } +} \ No newline at end of file diff --git a/app/ModelSerializers/PresentationSpeakerSerializer.php b/app/ModelSerializers/PresentationSpeakerSerializer.php index 8c6603b9..5d8e1dd6 100644 --- a/app/ModelSerializers/PresentationSpeakerSerializer.php +++ b/app/ModelSerializers/PresentationSpeakerSerializer.php @@ -11,9 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ - use Illuminate\Support\Facades\Config; -use models\summit\Presentation; use models\summit\PresentationSpeaker; /** @@ -22,20 +20,19 @@ use models\summit\PresentationSpeaker; */ class PresentationSpeakerSerializer extends SilverStripeSerializer { - protected static $array_mappings = array - ( + protected static $array_mappings = [ + 'FirstName' => 'first_name:json_string', 'LastName' => 'last_name:json_string', 'Title' => 'title:json_string', 'Bio' => 'bio:json_string', 'IRCHandle' => 'irc:json_string', 'TwitterName' => 'twitter:json_string', - ); + ]; - protected static $allowed_relations = array - ( + protected static $allowed_relations = [ 'member', - ); + ]; /** * @param null $expand @@ -44,7 +41,7 @@ class PresentationSpeakerSerializer extends SilverStripeSerializer * @param array $params * @return array */ - public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array() ) + public function serialize($expand = null, array $fields = [], array $relations = [], array $params = [] ) { if(!count($relations)) $relations = $this->getAllowedRelations(); @@ -55,8 +52,11 @@ class PresentationSpeakerSerializer extends SilverStripeSerializer $summit_id = isset($params['summit_id'])? intval($params['summit_id']):null; $published = isset($params['published'])? intval($params['published']):true; - $values['presentations'] = $speaker->getPresentationIds($summit_id, $published); - $values['moderated_presentations'] = $speaker->getModeratedPresentationIds($summit_id, $published); + if(!is_null($summit_id)) { + $values['presentations'] = $speaker->getPresentationIds($summit_id, $published); + $values['moderated_presentations'] = $speaker->getModeratedPresentationIds($summit_id, $published); + } + $values['pic'] = Config::get("server.assets_base_url", 'https://www.openstack.org/') . 'profile_images/speakers/' . $speaker->getId(); if (in_array('member', $relations) && $speaker->hasMember()) diff --git a/app/ModelSerializers/PresentationSpeakerSummitAssistanceConfirmationRequestSerializer.php b/app/ModelSerializers/PresentationSpeakerSummitAssistanceConfirmationRequestSerializer.php new file mode 100644 index 00000000..3e9dddda --- /dev/null +++ b/app/ModelSerializers/PresentationSpeakerSummitAssistanceConfirmationRequestSerializer.php @@ -0,0 +1,28 @@ + 'on_site_phone:json_string', + 'Registered' => 'registered:json_boolean', + 'Confirmed' => 'is_confirmed:json_boolean', + 'CheckedIn' => 'checked_in:json_boolean', + 'SummitId' => 'summit_id:json_int', + 'SpeakerId' => 'speaker_id:json_int', + ]; +} \ No newline at end of file diff --git a/app/ModelSerializers/SerializerRegistry.php b/app/ModelSerializers/SerializerRegistry.php index ab47f75d..b1adc160 100644 --- a/app/ModelSerializers/SerializerRegistry.php +++ b/app/ModelSerializers/SerializerRegistry.php @@ -37,6 +37,7 @@ use App\ModelSerializers\Marketplace\SupportChannelTypeSerializer; use App\ModelSerializers\Software\OpenStackComponentSerializer; use App\ModelSerializers\Software\OpenStackReleaseSerializer; use Libs\ModelSerializers\IModelSerializer; +use models\summit\SummitRegistrationPromoCode; use ModelSerializers\ChatTeams\ChatTeamInvitationSerializer; use ModelSerializers\ChatTeams\ChatTeamMemberSerializer; use ModelSerializers\ChatTeams\ChatTeamPushNotificationMessageSerializer; @@ -98,14 +99,23 @@ final class SerializerRegistry $this->registry['PresentationSlide'] = PresentationSlideSerializer::class; $this->registry['PresentationLink'] = PresentationLinkSerializer::class; $this->registry['Company'] = CompanySerializer::class; - $this->registry['PresentationSpeaker'] = PresentationSpeakerSerializer::class; - $this->registry['SummitEventFeedback'] = SummitEventFeedbackSerializer::class; - $this->registry['SummitAttendee'] = SummitAttendeeSerializer::class; - $this->registry['SummitMemberSchedule'] = SummitMemberScheduleSerializer::class; - $this->registry['SummitMemberFavorite'] = SummitMemberFavoriteSerializer::class; - $this->registry['SummitEntityEvent'] = SummitEntityEventSerializer::class; - $this->registry['SummitEventWithFile'] = SummitEventWithFileSerializer::class; - $this->registry['SummitScheduleEmptySpot'] = SummitScheduleEmptySpotSerializer::class; + + $this->registry['PresentationSpeaker'] = + [ + self::SerializerType_Public => PresentationSpeakerSerializer::class, + self::SerializerType_Private => AdminPresentationSpeakerSerializer::class + ]; + + $this->registry['SummitEventFeedback'] = SummitEventFeedbackSerializer::class; + $this->registry['SummitAttendee'] = SummitAttendeeSerializer::class; + $this->registry['SummitMemberSchedule'] = SummitMemberScheduleSerializer::class; + $this->registry['SummitMemberFavorite'] = SummitMemberFavoriteSerializer::class; + $this->registry['SummitEntityEvent'] = SummitEntityEventSerializer::class; + $this->registry['SummitEventWithFile'] = SummitEventWithFileSerializer::class; + $this->registry['SummitScheduleEmptySpot'] = SummitScheduleEmptySpotSerializer::class; + $this->registry['SummitRegistrationPromoCode'] = SummitRegistrationPromoCodeSerializer::class; + $this->registry['SpeakerSummitRegistrationPromoCode'] = SpeakerSummitRegistrationPromoCodeSerializer::class; + $this->registry['PresentationSpeakerSummitAssistanceConfirmationRequest'] = PresentationSpeakerSummitAssistanceConfirmationRequestSerializer::class; // locations $this->registry['SummitVenue'] = SummitVenueSerializer::class; $this->registry['SummitVenueRoom'] = SummitVenueRoomSerializer::class; diff --git a/app/ModelSerializers/SpeakerSummitRegistrationPromoCodeSerializer.php b/app/ModelSerializers/SpeakerSummitRegistrationPromoCodeSerializer.php new file mode 100644 index 00000000..6e142ea8 --- /dev/null +++ b/app/ModelSerializers/SpeakerSummitRegistrationPromoCodeSerializer.php @@ -0,0 +1,25 @@ + 'type:json_string', + 'SpeakerId' => 'speaker_id:json_int', + ]; +} \ No newline at end of file diff --git a/app/ModelSerializers/SummitRegistrationPromoCodeSerializer.php b/app/ModelSerializers/SummitRegistrationPromoCodeSerializer.php new file mode 100644 index 00000000..67dcbbb2 --- /dev/null +++ b/app/ModelSerializers/SummitRegistrationPromoCodeSerializer.php @@ -0,0 +1,27 @@ + 'code:json_string', + 'Redeemed' => 'redeemed:json_boolean', + 'Source' => 'source:json_string', + 'SummitId' => 'summit_id:json_int', + ]; +} \ No newline at end of file diff --git a/app/Models/Foundation/Main/Group.php b/app/Models/Foundation/Main/Group.php index a32c1908..1214ea30 100644 --- a/app/Models/Foundation/Main/Group.php +++ b/app/Models/Foundation/Main/Group.php @@ -27,6 +27,7 @@ class Group extends SilverstripeBaseModel const AdminGroupCode = 'administrators'; const CommunityMembersCode = 'community-members'; const FoundationMembersCode = 'foundation-members'; + const SummitAdministrators = 'summit-front-end-administrators'; public function __construct(){ parent::__construct(); diff --git a/app/Models/Foundation/Main/Member.php b/app/Models/Foundation/Main/Member.php index 3ae131b1..20425d34 100644 --- a/app/Models/Foundation/Main/Member.php +++ b/app/Models/Foundation/Main/Member.php @@ -582,12 +582,41 @@ class Member extends SilverstripeBaseModel */ public function isAdmin() { + $admin_group = $this->getGroupByCode(Group::AdminGroupCode); + return $admin_group != false && !is_null($admin_group); + } - $admin_group = $this->groups->filter(function ($entity) { - return $entity->getCode() == Group::AdminGroupCode; + /** + * @param string $code + * @return bool + */ + public function isOnGroup($code){ + if($this->isAdmin()) return true; + $group = $this->getGroupByCode($code); + return $group != false && !is_null($group); + } + + /** + * @param string $code + * @return Group|null + */ + public function getGroupByCode($code){ + /** + * + * this is the rite way to do it but due a bug that will + * be fixed on doctrine 2.6 (https://github.com/doctrine/doctrine2/pull/1399)this + * should be carried on on following + * way + * $criteria = Criteria::create(); + * $criteria->where(Criteria::expr()->eq('code', $code)); + * return $this->groups->matching($criteria)->first(); + */ + + $groups = $this->groups->filter(function ($entity) use($code){ + return $entity->getCode() == $code; }); - return !is_null($admin_group) && $admin_group != false && $admin_group->count() > 0; + return !is_null($groups) && $groups != false && $groups->count() > 0 ? $groups[0]: null; } /** diff --git a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php index 1b62d8c9..3c274e03 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php +++ b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeaker.php @@ -245,6 +245,16 @@ class PresentationSpeaker extends SilverstripeBaseModel return $this; } + /** + * @param Summit $summit + * @return SpeakerSummitRegistrationPromoCode + */ + public function getPromoCodeFor(Summit $summit){ + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('summit', $summit)); + return $this->promo_codes->matching($criteria)->first(); + } + /** * @param null|int $summit_id * @param bool|true $published_ones diff --git a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeakerSummitAssistanceConfirmationRequest.php b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeakerSummitAssistanceConfirmationRequest.php index 3978a45e..c3d694f2 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeakerSummitAssistanceConfirmationRequest.php +++ b/app/Models/Foundation/Summit/Events/Presentations/PresentationSpeakerSummitAssistanceConfirmationRequest.php @@ -52,12 +52,6 @@ class PresentationSpeakerSummitAssistanceConfirmationRequest extends Silverstrip */ private $speaker; - /** - * @ORM\ManyToOne(targetEntity="Summit") - * @ORM\JoinColumn(name="SummitID", referencedColumnName="ID") - * @var Summit - */ - private $summit; /** * @return string @@ -139,19 +133,17 @@ class PresentationSpeakerSummitAssistanceConfirmationRequest extends Silverstrip $this->speaker = $speaker; } - /** - * @return Summit - */ - public function getSummit() - { - return $this->summit; - } + use SummitOwned; /** - * @param Summit $summit + * @return int */ - public function setSummit($summit) - { - $this->summit = $summit; + public function getSpeakerId(){ + try { + return !is_null($this->speaker) ? $this->speaker->getId() : 0; + } + catch(\Exception $ex){ + return 0; + } } } \ No newline at end of file diff --git a/app/Models/Foundation/Summit/PromoCodes/SpeakerSummitRegistrationPromoCode.php b/app/Models/Foundation/Summit/PromoCodes/SpeakerSummitRegistrationPromoCode.php index e2b55a92..7cb413eb 100644 --- a/app/Models/Foundation/Summit/PromoCodes/SpeakerSummitRegistrationPromoCode.php +++ b/app/Models/Foundation/Summit/PromoCodes/SpeakerSummitRegistrationPromoCode.php @@ -70,4 +70,16 @@ class SpeakerSummitRegistrationPromoCode extends SummitRegistrationPromoCode parent::__construct(); $this->redeemed = false; } + + /** + * @return int + */ + public function getSpeakerId(){ + try { + return !is_null($this->speaker) ? $this->speaker->getId() : 0; + } + catch(\Exception $ex){ + return 0; + } + } } \ No newline at end of file diff --git a/tests/OAuth2SummitApiTest.php b/tests/OAuth2SummitApiTest.php index ad99218e..70a1c8ff 100644 --- a/tests/OAuth2SummitApiTest.php +++ b/tests/OAuth2SummitApiTest.php @@ -216,10 +216,9 @@ final class OAuth2SummitApiTest extends ProtectedApiTest { $params = [ - 'id' => 'current', + 'id' => 23, 'page' => 1, - 'per_page' => 15, - 'filter' => 'first_name=@John,last_name=@Bryce,email=@sebastian@', + 'per_page' => 50, 'order' => '+first_name,-last_name' ];