diff --git a/app/Http/Controllers/Apis/Protected/Summit/Factories/ExtraQuestionTypeValidationRulesFactory.php b/app/Http/Controllers/Apis/Protected/Summit/Factories/ExtraQuestionTypeValidationRulesFactory.php new file mode 100644 index 00000000..5b3573fd --- /dev/null +++ b/app/Http/Controllers/Apis/Protected/Summit/Factories/ExtraQuestionTypeValidationRulesFactory.php @@ -0,0 +1,49 @@ + 'sometimes|string', + 'type' => 'sometimes|string|in:'.implode(",", ExtraQuestionTypeConstants::ValidQuestionTypes), + 'label' => 'sometimes|string', + 'mandatory' => 'sometimes|boolean', + 'placeholder' => 'sometimes|string', + 'order' => 'sometimes|integer|min:1', + ]; + } + + return [ + 'name' => 'required|string', + 'type' => 'required|string|in:'.implode(",", ExtraQuestionTypeConstants::ValidQuestionTypes), + 'label' => 'required|string', + 'mandatory' => 'required|boolean', + 'placeholder' => 'sometimes|string', + ]; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Apis/Protected/Summit/Factories/ExtraQuestionTypeValueValidationRulesFactory.php b/app/Http/Controllers/Apis/Protected/Summit/Factories/ExtraQuestionTypeValueValidationRulesFactory.php new file mode 100644 index 00000000..a57c69a8 --- /dev/null +++ b/app/Http/Controllers/Apis/Protected/Summit/Factories/ExtraQuestionTypeValueValidationRulesFactory.php @@ -0,0 +1,42 @@ + 'sometimes|string', + 'value' => 'sometimes|string', + 'order' => 'sometimes|integer|min:1' + ]; + } + + return [ + 'label' => 'sometimes|string', + 'value' => 'required|string', + ]; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Apis/Protected/Summit/Factories/Registration/SummitOrderExtraQuestionTypeValidationRulesFactory.php b/app/Http/Controllers/Apis/Protected/Summit/Factories/Registration/SummitOrderExtraQuestionTypeValidationRulesFactory.php index b4c72e30..0c7b4bd4 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/Factories/Registration/SummitOrderExtraQuestionTypeValidationRulesFactory.php +++ b/app/Http/Controllers/Apis/Protected/Summit/Factories/Registration/SummitOrderExtraQuestionTypeValidationRulesFactory.php @@ -16,7 +16,8 @@ use models\summit\SummitOrderExtraQuestionTypeConstants; * Class SummitOrderExtraQuestionTypeValidationRulesFactory * @package App\Http\Controllers */ -final class SummitOrderExtraQuestionTypeValidationRulesFactory +class SummitOrderExtraQuestionTypeValidationRulesFactory +extends ExtraQuestionTypeValidationRulesFactory { /** * @param array $data @@ -25,27 +26,19 @@ final class SummitOrderExtraQuestionTypeValidationRulesFactory */ public static function build(array $data, $update = false){ + $rules = static::build($data,$update); + if($update){ - return [ - 'name' => 'sometimes|string', - 'type' => 'sometimes|string|in:'.implode(",", SummitOrderExtraQuestionTypeConstants::ValidQuestionTypes), - 'label' => 'sometimes|string', - 'mandatory' => 'sometimes|boolean', + return array_merge([ 'usage' => 'sometimes|string|in:'.implode(",", SummitOrderExtraQuestionTypeConstants::ValidQuestionUsages), 'printable' => 'sometimes|boolean', - 'placeholder' => 'sometimes|string', - 'order' => 'sometimes|integer|min:1', - ]; + ], $rules); } - return [ - 'name' => 'required|string', - 'type' => 'required|string|in:'.implode(",", SummitOrderExtraQuestionTypeConstants::ValidQuestionTypes), - 'label' => 'required|string', - 'mandatory' => 'required|boolean', + return array_merge([ 'usage' => 'required|string|in:'.implode(",", SummitOrderExtraQuestionTypeConstants::ValidQuestionUsages), 'printable' => 'sometimes|boolean', - 'placeholder' => 'sometimes|string', - ]; + + ], $rules); } } \ No newline at end of file diff --git a/app/Http/Controllers/Apis/Protected/Summit/Factories/SelectionPlanExtraQuestionValidationRulesFactory.php b/app/Http/Controllers/Apis/Protected/Summit/Factories/SelectionPlanExtraQuestionValidationRulesFactory.php new file mode 100644 index 00000000..68462fe0 --- /dev/null +++ b/app/Http/Controllers/Apis/Protected/Summit/Factories/SelectionPlanExtraQuestionValidationRulesFactory.php @@ -0,0 +1,22 @@ + 'required|boolean', 'will_all_speakers_attend' => 'sometimes|boolean', 'links' => 'sometimes|url_array', - 'extra_questions' => 'sometimes|entity_value_array', 'tags' => 'sometimes|string_array', + 'extra_questions' => 'sometimes|entity_value_array', ]; $data = $data->all(); @@ -397,8 +397,8 @@ final class OAuth2PresentationApiController extends OAuth2ProtectedController 'track_id' => 'required|integer', 'attending_media' => 'required|boolean', 'links' => 'sometimes|url_array', - 'extra_questions' => 'sometimes|entity_value_array', 'tags' => 'sometimes|string_array', + 'extra_questions' => 'sometimes|entity_value_array', ]; $data = $data->all(); diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitOrderExtraQuestionTypeApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitOrderExtraQuestionTypeApiController.php index d0e43043..bd6e4058 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitOrderExtraQuestionTypeApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitOrderExtraQuestionTypeApiController.php @@ -205,10 +205,7 @@ final class OAuth2SummitOrderExtraQuestionTypeApiController if (is_null($summit)) return $this->error404(); // Creates a Validator instance and validates the data. - $validation = Validator::make($payload, [ - 'label' => 'sometimes|string', - 'value' => 'required|string', - ]); + $validation = Validator::make($payload, ExtraQuestionTypeValueValidationRulesFactory::build($payload)); if ($validation->fails()) { $messages = $validation->messages()->toArray(); @@ -254,11 +251,7 @@ final class OAuth2SummitOrderExtraQuestionTypeApiController if (is_null($summit)) return $this->error404(); // Creates a Validator instance and validates the data. - $validation = Validator::make($payload, [ - 'label' => 'sometimes|string', - 'value' => 'sometimes|string', - 'order' => 'sometimes|integer|min:1' - ]); + $validation = Validator::make($payload, ExtraQuestionTypeValueValidationRulesFactory::build($payload, true)); if ($validation->fails()) { $messages = $validation->messages()->toArray(); diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSelectionPlansApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSelectionPlansApiController.php index 9c5b49d2..4cbeba0c 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSelectionPlansApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSelectionPlansApiController.php @@ -15,6 +15,8 @@ use App\Http\Utils\EpochCellFormatter; use App\Models\Exceptions\AuthzException; use App\Models\Foundation\Summit\Repositories\ISummitCategoryChangeRepository; +use App\Models\Foundation\Summit\Repositories\ISummitSelectionPlanExtraQuestionTypeRepository; +use App\Services\Model\ISelectionPlanExtraQuestionTypeService; use App\Services\Model\ISummitSelectionPlanService; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Validator; @@ -58,12 +60,23 @@ final class OAuth2SummitSelectionPlansApiController extends OAuth2ProtectedContr */ private $category_change_request_repository; + /** + * ISelectionPlanOrderExtraQuestionTypeService + */ + private $selection_plan_extra_questions_service; + + /** + * @var ISummitSelectionPlanExtraQuestionTypeRepository + */ + private $selection_plan_extra_questions_repository; /** * OAuth2SummitSelectionPlansApiController constructor. * @param ISummitRepository $summit_repository * @param ISummitEventRepository $summit_event_repository * @param ISummitCategoryChangeRepository $category_change_request_repository + * @param ISummitSelectionPlanExtraQuestionTypeRepository $selection_plan_extra_questions_repository * @param ISummitSelectionPlanService $selection_plan_service + * @param ISelectionPlanExtraQuestionTypeService $selection_plan_extra_questions_service * @param IResourceServerContext $resource_server_context */ public function __construct @@ -71,7 +84,9 @@ final class OAuth2SummitSelectionPlansApiController extends OAuth2ProtectedContr ISummitRepository $summit_repository, ISummitEventRepository $summit_event_repository, ISummitCategoryChangeRepository $category_change_request_repository, + ISummitSelectionPlanExtraQuestionTypeRepository $selection_plan_extra_questions_repository, ISummitSelectionPlanService $selection_plan_service, + ISelectionPlanExtraQuestionTypeService $selection_plan_extra_questions_service, IResourceServerContext $resource_server_context ) { @@ -81,6 +96,8 @@ final class OAuth2SummitSelectionPlansApiController extends OAuth2ProtectedContr $this->summit_event_repository = $summit_event_repository; $this->category_change_request_repository = $category_change_request_repository; $this->selection_plan_service = $selection_plan_service; + $this->selection_plan_extra_questions_service = $selection_plan_extra_questions_service; + $this->selection_plan_extra_questions_repository = $selection_plan_extra_questions_repository; } /** @@ -911,4 +928,272 @@ final class OAuth2SummitSelectionPlansApiController extends OAuth2ProtectedContr return $this->error500($ex); } } + + /** + * Extra questions + */ + + /** + * @param $summit_id + * @param $selection_plan_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function getExtraQuestions($summit_id, $selection_plan_id){ + try { + + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + return $this->_getAll( + function () { + return [ + 'name' => ['=@', '=='], + 'type' => ['=@', '=='], + 'label' => ['=@', '=='], + ]; + }, + function () { + return [ + 'name' => 'sometimes|string', + 'type' => 'sometimes|string', + 'label' => 'sometimes|string', + ]; + }, + function () { + return [ + 'id', + 'name', + 'label', + 'order', + ]; + }, + function ($filter) use ($summit, $selection_plan_id) { + if ($filter instanceof Filter) { + $filter->addFilterCondition + ( + FilterElement::makeEqual('selection_plan_id', intval($selection_plan_id)) + ); + } + return $filter; + }, + function () { + return SerializerRegistry::SerializerType_Public; + }, + null, + null, + function ($page, $per_page, $filter, $order, $applyExtraFilters) { + return $this->selection_plan_extra_questions_repository->getAllByPage + ( + new PagingInfo($page, $per_page), + call_user_func($applyExtraFilters, $filter), + $order + ); + } + ); + } catch (ValidationException $ex) { + Log::warning($ex); + return $this->error412($ex->getMessages()); + } + catch (EntityNotFoundException $ex) { + Log::warning($ex); + return $this->error404($ex->getMessage()); + } + catch (AuthzException $ex) { + Log::warning($ex); + return $this->error403($ex); + } + catch (Exception $ex) { + Log::error($ex); + return $this->error500($ex); + } + } + + /** + * @param $summit_id + * @param $selection_plan_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function getExtraQuestionsMetadata($summit_id, $selection_plan_id){ + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + return $this->ok + ( + $this->selection_plan_extra_questions_repository->getQuestionsMetadata() + ); + } + + use ParametrizedAddEntity; + + /** + * @param $summit_id + * @param $selection_plan_id + * @return \Illuminate\Http\JsonResponse + */ + public function addExtraQuestion($summit_id, $selection_plan_id){ + + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $selection_plan = $summit->getSelectionPlanById($selection_plan_id); + if (is_null($selection_plan)) return $this->error404(); + + $args = [$selection_plan]; + + return $this->_add( + function ($payload) { + return SelectionPlanExtraQuestionValidationRulesFactory::build($payload); + }, + function ($payload, $selection_plan){ + return $this->selection_plan_extra_questions_service->addExtraQuestion($selection_plan, $payload); + }, + ...$args + ); + } + + use ParametrizedGetEntity; + + /** + * @param $summit_id + * @param $selection_plan_id + * @param $question_id + * @return \Illuminate\Http\JsonResponse + */ + public function getExtraQuestion($summit_id, $selection_plan_id, $question_id){ + + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $selection_plan = $summit->getSelectionPlanById($selection_plan_id); + if (is_null($selection_plan)) return $this->error404(); + + return $this->_get($question_id, function($id) use($selection_plan){ + return $selection_plan->getExtraQuestionById(intval($id)); + }); + } + + use ParametrizedUpdateEntity; + + /** + * @param $summit_id + * @param $selection_plan_id + * @param $question_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function updateExtraQuestion($summit_id, $selection_plan_id, $question_id){ + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $selection_plan = $summit->getSelectionPlanById($selection_plan_id); + if (is_null($selection_plan)) return $this->error404(); + + $args = [$selection_plan]; + + return $this->_update($question_id, function($payload){ + return SelectionPlanExtraQuestionValidationRulesFactory::build($payload, true); + }, + function ($question_id, $payload, $selection_plan){ + return $this->selection_plan_extra_questions_service->updateExtraQuestion($selection_plan, $question_id, $payload); + }, ...$args); + } + + use ParametrizedDeleteEntity; + + /** + * @param $summit_id + * @param $selection_plan_id + * @param $question_id + * @return \Illuminate\Http\JsonResponse + */ + public function deleteExtraQuestion($summit_id, $selection_plan_id, $question_id){ + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $selection_plan = $summit->getSelectionPlanById($selection_plan_id); + if (is_null($selection_plan)) return $this->error404(); + + $args = [$selection_plan]; + + return $this->_delete(intval($question_id) , function($question_id, $selection_plan){ + $this->selection_plan_extra_questions_service->deleteExtraQuestion($selection_plan, $question_id); + }, ...$args); + } + + /** + * @param $summit_id + * @param $selection_plan_id + * @param $question_id + * @return \Illuminate\Http\JsonResponse + */ + public function addExtraQuestionValue($summit_id, $selection_plan_id, $question_id){ + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $selection_plan = $summit->getSelectionPlanById($selection_plan_id); + if (is_null($selection_plan)) return $this->error404(); + + $args = [$selection_plan, intval($question_id)]; + + return $this->_add( + function($payload){ + return ExtraQuestionTypeValueValidationRulesFactory::build($payload); + }, + function($payload, $selection_plan, $question_id){ + return $this->selection_plan_extra_questions_service-> + addExtraQuestionValue($selection_plan, $question_id, $payload); + }, + ...$args); + } + + /** + * @param $summit_id + * @param $selection_plan_id + * @param $question_id + * @param $value_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function updateExtraQuestionValue($summit_id, $selection_plan_id, $question_id, $value_id){ + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $selection_plan = $summit->getSelectionPlanById($selection_plan_id); + if (is_null($selection_plan)) return $this->error404(); + + $args = [$selection_plan, intval($question_id)]; + + return $this->_update($value_id, function($payload){ + return ExtraQuestionTypeValueValidationRulesFactory::build($payload, false); + }, + function($value_id, $payload, $selection_plan, $question_id){ + return $this->selection_plan_extra_questions_service->updateExtraQuestionValue + ( + $selection_plan, + $question_id, + $value_id, + $payload + ); + }, ...$args); + } + + /** + * @param $summit_id + * @param $selection_plan_id + * @param $question_id + * @param $value_id + * @return \Illuminate\Http\JsonResponse|mixed + */ + public function deleteExtraQuestionValue($summit_id, $selection_plan_id, $question_id, $value_id){ + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $selection_plan = $summit->getSelectionPlanById($selection_plan_id); + if (is_null($selection_plan)) return $this->error404(); + + $args = [$selection_plan, intval($question_id)]; + + return $this->_delete($value_id, function($value_id, $selection_plan, $question_id){ + $this->selection_plan_extra_questions_service->deleteExtraQuestionValue($selection_plan, $question_id, $value_id); + } + , ...$args); + } } \ No newline at end of file diff --git a/app/Http/Controllers/Apis/Protected/Summit/Traits/ParametrizedAddEntity.php b/app/Http/Controllers/Apis/Protected/Summit/Traits/ParametrizedAddEntity.php index d9d0916c..34531633 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/Traits/ParametrizedAddEntity.php +++ b/app/Http/Controllers/Apis/Protected/Summit/Traits/ParametrizedAddEntity.php @@ -19,6 +19,7 @@ use Illuminate\Support\Facades\Validator; use models\exceptions\EntityNotFoundException; use models\exceptions\ValidationException; use ModelSerializers\SerializerRegistry; +use Exception; /** * Trait ParametrizedAddEntity * @package App\Http\Controllers diff --git a/app/Http/routes.php b/app/Http/routes.php index 92c034da..d024a11d 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -244,6 +244,26 @@ Route::group([ Route::delete('{track_group_id}', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitSelectionPlansApiController@deleteTrackGroupToSelectionPlan']); }); + // extra questions + + Route::group(['prefix' => 'extra-questions'], function(){ + Route::get('', ['uses' => 'OAuth2SummitSelectionPlansApiController@getExtraQuestions']); + Route::get('metadata', [ 'uses' => 'OAuth2SummitSelectionPlansApiController@getExtraQuestionsMetadata']); + Route::post('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2SummitSelectionPlansApiController@addExtraQuestion']); + Route::group(['prefix' => '{question_id}'], function(){ + Route::get('', ['uses' => 'OAuth2SummitSelectionPlansApiController@getExtraQuestion']); + Route::put('', ['uses' => 'OAuth2SummitSelectionPlansApiController@updateExtraQuestion']); + Route::delete('', ['uses' => 'OAuth2SummitSelectionPlansApiController@deleteExtraQuestion']); + Route::group(['prefix' => 'values'], function () { + Route::post('', ['middleware' => 'auth.user', 'uses' => 'OAuth2SummitSelectionPlansApiController@addExtraQuestionValue']); + Route::group(['prefix' => '{value_id}'], function () { + Route::put('', ['middleware' => 'auth.user', 'uses' => 'OAuth2SummitSelectionPlansApiController@updateExtraQuestionValue']); + Route::delete('', ['middleware' => 'auth.user', 'uses' => 'OAuth2SummitSelectionPlansApiController@deleteExtraQuestionValue']); + }); + }); + }); + }); + // presentations Route::group(['prefix' => 'presentations'], function () { diff --git a/app/ModelSerializers/ExtraQuestionAnswerSerializer.php b/app/ModelSerializers/ExtraQuestionAnswerSerializer.php new file mode 100644 index 00000000..97684714 --- /dev/null +++ b/app/ModelSerializers/ExtraQuestionAnswerSerializer.php @@ -0,0 +1,65 @@ + 'value:json_string', + 'QuestionId' => 'question_id:json_int', + ]; + + /** + * @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()) + { + $answer = $this->object; + if (!$answer instanceof ExtraQuestionAnswer) return []; + $values = parent::serialize($expand, $fields, $relations, $params); + + if (!count($relations)) $relations = $this->getAllowedRelations(); + + if (!empty($expand)) { + $exp_expand = explode(',', $expand); + foreach ($exp_expand as $relation) { + switch (trim($relation)) { + case 'question': + { + + if ($answer->hasQuestion()) { + unset($values['question_id']); + $values['question'] = SerializerRegistry::getInstance()->getSerializer($answer->getQuestion()) + ->serialize(AbstractSerializer::getExpandForPrefix('question', $expand)); + } + } + break; + + + } + } + } + + return $values; + } +} \ No newline at end of file diff --git a/app/ModelSerializers/ExtraQuestionTypeSerializer.php b/app/ModelSerializers/ExtraQuestionTypeSerializer.php new file mode 100644 index 00000000..2a78a691 --- /dev/null +++ b/app/ModelSerializers/ExtraQuestionTypeSerializer.php @@ -0,0 +1,79 @@ + 'name:json_string', + 'Type' => 'type:json_string', + 'Label' => 'label:json_string', + 'Placeholder' => 'placeholder:json_string', + 'Order' => 'order:json_int', + 'Mandatory' => 'mandatory:json_boolean', + ]; + + protected static $allowed_relations = [ + 'values', + ]; + + /** + * @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() ) + { + $question = $this->object; + if (!$question instanceof ExtraQuestionType) return []; + if(!count($relations)) $relations = $this->getAllowedRelations(); + $values = parent::serialize($expand, $fields, $relations, $params); + + if(in_array('values', $relations) && $question->allowsValues()) { + $question_values = []; + foreach ($question->getValues() as $value) { + $question_values[] = $value->getId(); + } + $values['values'] = $question_values; + } + + if (!empty($expand)) { + $exp_expand = explode(',', $expand); + foreach ($exp_expand as $relation) { + switch (trim($relation)) { + case 'values': + { + if (!$question->allowsValues()) + break; + unset($values['values']); + $question_values = []; + foreach ($question->getValues() as $value) { + $question_values[] = SerializerRegistry::getInstance()->getSerializer($value)->serialize(); + } + $values['values'] = $question_values; + } + break; + + + } + } + } + return $values; + } +} \ No newline at end of file diff --git a/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionValueSerializer.php b/app/ModelSerializers/ExtraQuestionTypeValueSerializer.php similarity index 87% rename from app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionValueSerializer.php rename to app/ModelSerializers/ExtraQuestionTypeValueSerializer.php index 554d7b4f..2591b8c8 100644 --- a/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionValueSerializer.php +++ b/app/ModelSerializers/ExtraQuestionTypeValueSerializer.php @@ -13,10 +13,10 @@ **/ /** - * Class SummitOrderExtraQuestionValueSerializer + * Class ExtraQuestionTypeValueSerializer * @package ModelSerializers */ -final class SummitOrderExtraQuestionValueSerializer extends SilverStripeSerializer +class ExtraQuestionTypeValueSerializer extends SilverStripeSerializer { protected static $array_mappings = [ 'Label' => 'label:json_string', diff --git a/app/ModelSerializers/SerializerRegistry.php b/app/ModelSerializers/SerializerRegistry.php index c08589bb..2f4f8a43 100644 --- a/app/ModelSerializers/SerializerRegistry.php +++ b/app/ModelSerializers/SerializerRegistry.php @@ -11,6 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + use App\ModelSerializers\CCLA\TeamSerializer; use App\ModelSerializers\FileSerializer; use App\ModelSerializers\ISummitAttendeeTicketSerializerTypes; @@ -21,6 +22,7 @@ use App\ModelSerializers\Locations\SummitBookableVenueRoomAttributeValueSerializ use App\ModelSerializers\Locations\SummitBookableVenueRoomAvailableSlotSerializer; use App\ModelSerializers\Locations\SummitBookableVenueRoomSerializer; use App\ModelSerializers\Locations\SummitRoomReservationSerializer; +use App\ModelSerializers\Marketplace\ApplianceSerializer; use App\ModelSerializers\Marketplace\CloudServiceOfferedSerializer; use App\ModelSerializers\Marketplace\ConfigurationManagementTypeSerializer; use App\ModelSerializers\Marketplace\ConsultantClientSerializer; @@ -62,11 +64,6 @@ use App\ModelSerializers\Summit\Presentation\TrackQuestions\TrackQuestionValueTe use App\ModelSerializers\Summit\Presentation\TrackQuestions\TrackSingleValueTemplateQuestionSerializer; use App\ModelSerializers\Summit\Registration\SummitAttendeeCSVSerializer; use App\ModelSerializers\Summit\Registration\SummitAttendeeTicketCSVSerializer; -use App\ModelSerializers\Summit\SponsorBadgeScanCSVSerializer; -use App\ModelSerializers\Summit\SponsorBadgeScanSerializer; -use App\ModelSerializers\Summit\SponsorUserInfoGrantSerializer; -use App\ModelSerializers\Summit\StripePaymentProfileSerializer; -use App\ModelSerializers\Summit\SummitAttendeeBadgeSerializer; use App\ModelSerializers\Summit\RSVP\Templates\RSVPDropDownQuestionTemplateSerializer; use App\ModelSerializers\Summit\RSVP\Templates\RSVPLiteralContentQuestionTemplateSerializer; use App\ModelSerializers\Summit\RSVP\Templates\RSVPMultiValueQuestionTemplateSerializer; @@ -74,13 +71,17 @@ use App\ModelSerializers\Summit\RSVP\Templates\RSVPQuestionValueTemplateSerializ use App\ModelSerializers\Summit\RSVP\Templates\RSVPSingleValueTemplateQuestionSerializer; use App\ModelSerializers\Summit\RSVPTemplateSerializer; use App\ModelSerializers\Summit\ScheduledSummitLocationBannerSerializer; -use App\ModelSerializers\Summit\SelectionPlanSerializer; +use App\ModelSerializers\Summit\SponsorBadgeScanCSVSerializer; +use App\ModelSerializers\Summit\SponsorBadgeScanSerializer; +use App\ModelSerializers\Summit\SponsorUserInfoGrantSerializer; +use App\ModelSerializers\Summit\StripePaymentProfileSerializer; +use App\ModelSerializers\Summit\SummitAttendeeBadgeSerializer; use App\ModelSerializers\Summit\SummitEmailEventFlowSerializer; use App\ModelSerializers\Summit\SummitLocationBannerSerializer; use App\ModelSerializers\Summit\TrackTagGroups\TrackTagGroupAllowedTagSerializer; use App\ModelSerializers\Summit\TrackTagGroups\TrackTagGroupSerializer; +use Illuminate\Support\Facades\App; use Libs\ModelSerializers\IModelSerializer; -use models\main\LegalDocument; use models\oauth2\IResourceServerContext; use ModelSerializers\ChatTeams\ChatTeamInvitationSerializer; use ModelSerializers\ChatTeams\ChatTeamMemberSerializer; @@ -93,8 +94,7 @@ use ModelSerializers\Locations\SummitLocationImageSerializer; use ModelSerializers\Locations\SummitVenueFloorSerializer; use ModelSerializers\Locations\SummitVenueRoomSerializer; use ModelSerializers\Locations\SummitVenueSerializer; -use App\ModelSerializers\Marketplace\ApplianceSerializer; -use Illuminate\Support\Facades\App; + /** * Class SerializerRegistry * @package ModelSerializers @@ -111,12 +111,14 @@ final class SerializerRegistry */ private $resource_server_context; - const SerializerType_Public = 'PUBLIC'; + const SerializerType_Public = 'PUBLIC'; const SerializerType_Private = 'PRIVATE'; - const SerializerType_Admin = 'ADMIN'; - const SerializerType_CSV = 'CSV'; + const SerializerType_Admin = 'ADMIN'; + const SerializerType_CSV = 'CSV'; - private function __clone(){} + private function __clone() + { + } /** * @return SerializerRegistry @@ -135,10 +137,13 @@ final class SerializerRegistry { $this->resource_server_context = App::make(IResourceServerContext::class); // resource server config - $this->registry['Api'] = ApiSerializer::class; - $this->registry['ApiEndpoint'] = ApiEndpointSerializer::class; - $this->registry['ApiScope'] = ApiScopeSerializer::class; + $this->registry['Api'] = ApiSerializer::class; + $this->registry['ApiEndpoint'] = ApiEndpointSerializer::class; + $this->registry['ApiScope'] = ApiScopeSerializer::class; $this->registry['ApiEndpointAuthzGroup'] = ApiEndpointAuthzGroupSerializer::class; + + // extra questions base + $this->registry['ExtraQuestionTypeValue'] = ExtraQuestionTypeValueSerializer::class; // metrics $this->registry['SummitMetric'] = SummitMetricSerializer::class; @@ -148,32 +153,33 @@ final class SerializerRegistry // stripe $this->registry['StripePaymentProfile'] = [ self::SerializerType_Public => StripePaymentProfileSerializer::class, - self::SerializerType_Private => AdminStripePaymentProfileSerializer::class, + self::SerializerType_Private => AdminStripePaymentProfileSerializer::class, ]; $this->registry['SummitAdministratorPermissionGroup'] = SummitAdministratorPermissionGroupSerializer::class; - $this->registry['Summit'] = + $this->registry['Summit'] = [ - self::SerializerType_Public => SummitSerializer::class, - self::SerializerType_Private => AdminSummitSerializer::class + self::SerializerType_Public => SummitSerializer::class, + self::SerializerType_Private => AdminSummitSerializer::class ]; - $this->registry['SummitDocument'] = SummitDocumentSerializer::class; - $this->registry['SummitEmailEventFlow'] = SummitEmailEventFlowSerializer::class; - $this->registry['SelectionPlan'] = SelectionPlanSerializer::class; - $this->registry['SummitWIFIConnection'] = SummitWIFIConnectionSerializer::class; - $this->registry['SummitType'] = SummitTypeSerializer::class; - $this->registry['SummitEventType'] = SummitEventTypeSerializer::class; - $this->registry['PresentationType'] = PresentationTypeSerializer::class; - $this->registry['SummitTicketType'] = SummitTicketTypeSerializer::class; - $this->registry['PresentationCategory'] = PresentationCategorySerializer::class; - $this->registry['PresentationCategoryGroup'] = PresentationCategoryGroupSerializer::class; + $this->registry['SummitDocument'] = SummitDocumentSerializer::class; + $this->registry['SummitEmailEventFlow'] = SummitEmailEventFlowSerializer::class; + $this->registry['SelectionPlan'] = SelectionPlanSerializer::class; + $this->registry['SummitSelectionPlanExtraQuestionType'] = SummitSelectionPlanExtraQuestionTypeSerializer::class; + $this->registry['SummitWIFIConnection'] = SummitWIFIConnectionSerializer::class; + $this->registry['SummitType'] = SummitTypeSerializer::class; + $this->registry['SummitEventType'] = SummitEventTypeSerializer::class; + $this->registry['PresentationType'] = PresentationTypeSerializer::class; + $this->registry['SummitTicketType'] = SummitTicketTypeSerializer::class; + $this->registry['PresentationCategory'] = PresentationCategorySerializer::class; + $this->registry['PresentationCategoryGroup'] = PresentationCategoryGroupSerializer::class; $this->registry['PrivatePresentationCategoryGroup'] = PrivatePresentationCategoryGroupSerializer::class; - $this->registry['Tag'] = TagSerializer::class; + $this->registry['Tag'] = TagSerializer::class; $this->registry['Language'] = LanguageSerializer::class; // track questions - $this->registry['TrackAnswer'] = TrackAnswerSerializer::class; + $this->registry['TrackAnswer'] = TrackAnswerSerializer::class; $this->registry['TrackQuestionValueTemplate'] = TrackQuestionValueTemplateSerializer::class; $this->registry['TrackTextBoxQuestionTemplate'] = TrackSingleValueTemplateQuestionSerializer::class; $this->registry['TrackCheckBoxQuestionTemplate'] = TrackSingleValueTemplateQuestionSerializer::class; @@ -183,19 +189,19 @@ final class SerializerRegistry $this->registry['TrackLiteralContentQuestionTemplate'] = TrackLiteralContentQuestionTemplateSerializer::class; // events - $this->registry['SummitEvent'] = [ + $this->registry['SummitEvent'] = [ self::SerializerType_Public => SummitEventSerializer::class, self::SerializerType_Private => SummitEventSerializer::class, self::SerializerType_CSV => AdminSummitEventCSVSerializer::class ]; - $this->registry['SummitGroupEvent'] = SummitGroupEventSerializer::class; - $this->registry['TrackTagGroup'] = TrackTagGroupSerializer::class; - $this->registry['Presentation'] = + $this->registry['SummitGroupEvent'] = SummitGroupEventSerializer::class; + $this->registry['TrackTagGroup'] = TrackTagGroupSerializer::class; + $this->registry['Presentation'] = [ - self::SerializerType_Public => PresentationSerializer::class, - self::SerializerType_Private => AdminPresentationSerializer::class, - self::SerializerType_CSV => AdminPresentationCSVSerializer::class, + self::SerializerType_Public => PresentationSerializer::class, + self::SerializerType_Private => AdminPresentationSerializer::class, + self::SerializerType_CSV => AdminPresentationCSVSerializer::class, IPresentationSerializerTypes::TrackChairs => TrackChairPresentationSerializer::class, IPresentationSerializerTypes::TrackChairs_CSV => TrackChairPresentationCSVSerializer::class ]; @@ -211,71 +217,71 @@ final class SerializerRegistry $this->registry['SummitSelectedPresentation'] = SummitSelectedPresentationSerializer::class; $this->registry['SummitTrackChair'] = [ - self::SerializerType_Public => SummitTrackChairSerializer::class, + self::SerializerType_Public => SummitTrackChairSerializer::class, self::SerializerType_CSV => SummitTrackChairCSVSerializer::class ]; - $this->registry['SummitPresentationComment'] = SummitPresentationCommentSerializer::class; - $this->registry['SummitMediaFileType'] = SummitMediaFileTypeSerializer::class; - $this->registry['SummitMediaUploadType'] = SummitMediaUploadTypeSerializer::class; - $this->registry['PresentationVideo'] = PresentationVideoSerializer::class; - $this->registry['PresentationSlide'] = PresentationSlideSerializer::class; - $this->registry['PresentationLink'] = PresentationLinkSerializer::class; + $this->registry['SummitPresentationComment'] = SummitPresentationCommentSerializer::class; + $this->registry['SummitMediaFileType'] = SummitMediaFileTypeSerializer::class; + $this->registry['SummitMediaUploadType'] = SummitMediaUploadTypeSerializer::class; + $this->registry['PresentationVideo'] = PresentationVideoSerializer::class; + $this->registry['PresentationSlide'] = PresentationSlideSerializer::class; + $this->registry['PresentationLink'] = PresentationLinkSerializer::class; $this->registry['PresentationMediaUpload'] = [ - self::SerializerType_Public => PresentationMediaUploadSerializer::class, - self::SerializerType_Private => AdminPresentationMediaUploadSerializer::class + self::SerializerType_Public => PresentationMediaUploadSerializer::class, + self::SerializerType_Private => AdminPresentationMediaUploadSerializer::class ]; // Company - $this->registry['Company'] = CompanySerializer::class; - $this->registry['SponsoredProject'] = SponsoredProjectSerializer::class; + $this->registry['Company'] = CompanySerializer::class; + $this->registry['SponsoredProject'] = SponsoredProjectSerializer::class; $this->registry['ProjectSponsorshipType'] = ProjectSponsorshipTypeSerializer::class; - $this->registry['SupportingCompany'] = SupportingCompanySerializer::class; + $this->registry['SupportingCompany'] = SupportingCompanySerializer::class; - $this->registry['PresentationSpeaker'] = + $this->registry['PresentationSpeaker'] = [ - self::SerializerType_Public => PresentationSpeakerSerializer::class, - self::SerializerType_Private => AdminPresentationSpeakerSerializer::class + self::SerializerType_Public => PresentationSpeakerSerializer::class, + self::SerializerType_Private => AdminPresentationSpeakerSerializer::class ]; $this->registry['SpeakerEditPermissionRequest'] = SpeakerEditPermissionRequestSerializer::class; // RSVP - $this->registry['RSVP'] = RSVPSerializer::class; - $this->registry['RSVPAnswer'] = RSVPAnswerSerializer::class; - $this->registry['RSVPTemplate'] = RSVPTemplateSerializer::class; - $this->registry['RSVPQuestionValueTemplate'] = RSVPQuestionValueTemplateSerializer::class; + $this->registry['RSVP'] = RSVPSerializer::class; + $this->registry['RSVPAnswer'] = RSVPAnswerSerializer::class; + $this->registry['RSVPTemplate'] = RSVPTemplateSerializer::class; + $this->registry['RSVPQuestionValueTemplate'] = RSVPQuestionValueTemplateSerializer::class; - $this->registry['RSVPSingleValueTemplateQuestion'] = RSVPSingleValueTemplateQuestionSerializer::class; - $this->registry['RSVPTextBoxQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; - $this->registry['RSVPTextAreaQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; - $this->registry['RSVPLiteralContentQuestionTemplate'] = RSVPLiteralContentQuestionTemplateSerializer::class; - $this->registry['RSVPMemberEmailQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; + $this->registry['RSVPSingleValueTemplateQuestion'] = RSVPSingleValueTemplateQuestionSerializer::class; + $this->registry['RSVPTextBoxQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; + $this->registry['RSVPTextAreaQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; + $this->registry['RSVPLiteralContentQuestionTemplate'] = RSVPLiteralContentQuestionTemplateSerializer::class; + $this->registry['RSVPMemberEmailQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; $this->registry['RSVPMemberFirstNameQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; - $this->registry['RSVPMemberLastNameQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; - $this->registry['RSVPMemberLastNameQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; + $this->registry['RSVPMemberLastNameQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; + $this->registry['RSVPMemberLastNameQuestionTemplate'] = RSVPSingleValueTemplateQuestionSerializer::class; - $this->registry['RSVPCheckBoxListQuestionTemplate'] = RSVPMultiValueQuestionTemplateSerializer::class; + $this->registry['RSVPCheckBoxListQuestionTemplate'] = RSVPMultiValueQuestionTemplateSerializer::class; $this->registry['RSVPRadioButtonListQuestionTemplate'] = RSVPMultiValueQuestionTemplateSerializer::class; - $this->registry['RSVPDropDownQuestionTemplate'] = RSVPDropDownQuestionTemplateSerializer::class; + $this->registry['RSVPDropDownQuestionTemplate'] = RSVPDropDownQuestionTemplateSerializer::class; - $this->registry['SpeakerExpertise'] = SpeakerExpertiseSerializer::class; - $this->registry['SpeakerTravelPreference'] = SpeakerTravelPreferenceSerializer::class; - $this->registry['SpeakerPresentationLink'] = SpeakerPresentationLinkSerializer::class; - $this->registry['SpeakerActiveInvolvement'] = SpeakerActiveInvolvementSerializer::class; - $this->registry['SpeakerOrganizationalRole'] = SpeakerOrganizationalRoleSerializer::class; + $this->registry['SpeakerExpertise'] = SpeakerExpertiseSerializer::class; + $this->registry['SpeakerTravelPreference'] = SpeakerTravelPreferenceSerializer::class; + $this->registry['SpeakerPresentationLink'] = SpeakerPresentationLinkSerializer::class; + $this->registry['SpeakerActiveInvolvement'] = SpeakerActiveInvolvementSerializer::class; + $this->registry['SpeakerOrganizationalRole'] = SpeakerOrganizationalRoleSerializer::class; - $this->registry['SummitEventFeedback'] = SummitEventFeedbackSerializer::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['SummitEventFeedback'] = SummitEventFeedbackSerializer::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; // promo codes - $this->registry['SummitRegistrationPromoCode'] = SummitRegistrationPromoCodeSerializer::class; - $this->registry['MemberSummitRegistrationPromoCode'] = MemberSummitRegistrationPromoCodeSerializer::class; + $this->registry['SummitRegistrationPromoCode'] = SummitRegistrationPromoCodeSerializer::class; + $this->registry['MemberSummitRegistrationPromoCode'] = MemberSummitRegistrationPromoCodeSerializer::class; $this->registry['SpeakerSummitRegistrationPromoCode'] = SpeakerSummitRegistrationPromoCodeSerializer::class; $this->registry['SponsorSummitRegistrationPromoCode'] = SponsorSummitRegistrationPromoCodeSerializer::class; $this->registry['PresentationSpeakerSummitAssistanceConfirmationRequest'] = PresentationSpeakerSummitAssistanceConfirmationRequestSerializer::class; @@ -286,58 +292,58 @@ final class SerializerRegistry $this->registry['SponsorSummitRegistrationDiscountCode'] = SponsorSummitRegistrationDiscountCodeSerializer::class; // registration - $this->registry['SummitRegistrationInvitation'] = - [ - self::SerializerType_Public => SummitRegistrationInvitationSerializer::class, - self::SerializerType_CSV => SummitRegistrationInvitationCSVSerializer::class, - ]; + $this->registry['SummitRegistrationInvitation'] = + [ + self::SerializerType_Public => SummitRegistrationInvitationSerializer::class, + self::SerializerType_CSV => SummitRegistrationInvitationCSVSerializer::class, + ]; - $this->registry['SummitAccessLevelType'] = SummitAccessLevelTypeSerializer::class; - $this->registry['SummitTaxType'] = SummitTaxTypeSerializer::class; - $this->registry['SummitBadgeType'] = SummitBadgeTypeSerializer::class; + $this->registry['SummitAccessLevelType'] = SummitAccessLevelTypeSerializer::class; + $this->registry['SummitTaxType'] = SummitTaxTypeSerializer::class; + $this->registry['SummitBadgeType'] = SummitBadgeTypeSerializer::class; $this->registry['SummitBadgeFeatureType'] = SummitBadgeFeatureTypeSerializer::class; $this->registry['SummitRefundPolicyType'] = SummitRefundPolicyTypeSerializer::class; - $this->registry['SummitOrderExtraQuestionValue'] = SummitOrderExtraQuestionValueSerializer::class; $this->registry['SummitOrderExtraQuestionType'] = SummitOrderExtraQuestionTypeSerializer::class; + // orders $this->registry['SummitOrder'] = [ - self::SerializerType_Public => SummitOrderBaseSerializer::class, - ISummitOrderSerializerTypes::CheckOutType => SummitOrderBaseSerializer::class, - ISummitOrderSerializerTypes::ReservationType => SummitOrderReservationSerializer::class, - ISummitOrderSerializerTypes::AdminType => SummitOrderAdminSerializer::class, + self::SerializerType_Public => SummitOrderBaseSerializer::class, + ISummitOrderSerializerTypes::CheckOutType => SummitOrderBaseSerializer::class, + ISummitOrderSerializerTypes::ReservationType => SummitOrderReservationSerializer::class, + ISummitOrderSerializerTypes::AdminType => SummitOrderAdminSerializer::class, ]; $this->registry['SummitOrderExtraQuestionAnswer'] = SummitOrderExtraQuestionAnswerSerializer::class; - $this->registry['SummitAttendee'] = [ - self::SerializerType_Public => SummitAttendeeSerializer::class, + $this->registry['SummitAttendee'] = [ + self::SerializerType_Public => SummitAttendeeSerializer::class, self::SerializerType_Private => SummitAttendeeAdminSerializer::class, - self::SerializerType_CSV => SummitAttendeeCSVSerializer::class, + self::SerializerType_CSV => SummitAttendeeCSVSerializer::class, ]; - $this->registry['SummitAttendeeTicket'] = [ - self::SerializerType_Public => BaseSummitAttendeeTicketSerializer::class, - ISummitAttendeeTicketSerializerTypes::AdminType => SummitAttendeeTicketSerializer::class, - ISummitAttendeeTicketSerializerTypes::PublicEdition => PublicEditionSummitAttendeeTicketSerializer::class, - ISummitAttendeeTicketSerializerTypes::GuestEdition => GuestEditionSummitAttendeeTicketSerializer::class, - self::SerializerType_CSV => SummitAttendeeTicketCSVSerializer::class, + $this->registry['SummitAttendeeTicket'] = [ + self::SerializerType_Public => BaseSummitAttendeeTicketSerializer::class, + ISummitAttendeeTicketSerializerTypes::AdminType => SummitAttendeeTicketSerializer::class, + ISummitAttendeeTicketSerializerTypes::PublicEdition => PublicEditionSummitAttendeeTicketSerializer::class, + ISummitAttendeeTicketSerializerTypes::GuestEdition => GuestEditionSummitAttendeeTicketSerializer::class, + self::SerializerType_CSV => SummitAttendeeTicketCSVSerializer::class, ]; - $this->registry['SummitAttendeeBadge'] = SummitAttendeeBadgeSerializer::class; + $this->registry['SummitAttendeeBadge'] = SummitAttendeeBadgeSerializer::class; - $this->registry['SponsorBadgeScan'] = [ - self::SerializerType_Public => SponsorBadgeScanSerializer::class, - self::SerializerType_CSV => SponsorBadgeScanCSVSerializer::class, + $this->registry['SponsorBadgeScan'] = [ + self::SerializerType_Public => SponsorBadgeScanSerializer::class, + self::SerializerType_CSV => SponsorBadgeScanCSVSerializer::class, ]; - $this->registry['SponsorUserInfoGrant'] = [ - self::SerializerType_Public => SponsorUserInfoGrantSerializer::class, - self::SerializerType_CSV => SponsorUserInfoGrantSerializer::class, + $this->registry['SponsorUserInfoGrant'] = [ + self::SerializerType_Public => SponsorUserInfoGrantSerializer::class, + self::SerializerType_CSV => SponsorUserInfoGrantSerializer::class, ]; - $this->registry['SummitAttendeeTicketTax'] = SummitAttendeeTicketTaxSerializer::class; + $this->registry['SummitAttendeeTicketTax'] = SummitAttendeeTicketTaxSerializer::class; // summit sponsors @@ -345,20 +351,20 @@ final class SerializerRegistry $this->registry['Sponsor'] = SponsorSerializer::class; // locations - $this->registry['SummitVenue'] = SummitVenueSerializer::class; - $this->registry['SummitVenueRoom'] = SummitVenueRoomSerializer::class; - $this->registry['SummitVenueFloor'] = SummitVenueFloorSerializer::class; - $this->registry['SummitExternalLocation'] = SummitExternalLocationSerializer::class; - $this->registry['SummitHotel'] = SummitHotelSerializer::class; - $this->registry['SummitAirport'] = SummitAirportSerializer::class; - $this->registry['SummitLocationImage'] = SummitLocationImageSerializer::class; - $this->registry['SummitLocationBanner'] = SummitLocationBannerSerializer::class; - $this->registry['ScheduledSummitLocationBanner'] = ScheduledSummitLocationBannerSerializer::class; - $this->registry['SummitBookableVenueRoom'] = SummitBookableVenueRoomSerializer::class; - $this->registry['SummitBookableVenueRoomAttributeType'] = SummitBookableVenueRoomAttributeTypeSerializer::class; + $this->registry['SummitVenue'] = SummitVenueSerializer::class; + $this->registry['SummitVenueRoom'] = SummitVenueRoomSerializer::class; + $this->registry['SummitVenueFloor'] = SummitVenueFloorSerializer::class; + $this->registry['SummitExternalLocation'] = SummitExternalLocationSerializer::class; + $this->registry['SummitHotel'] = SummitHotelSerializer::class; + $this->registry['SummitAirport'] = SummitAirportSerializer::class; + $this->registry['SummitLocationImage'] = SummitLocationImageSerializer::class; + $this->registry['SummitLocationBanner'] = SummitLocationBannerSerializer::class; + $this->registry['ScheduledSummitLocationBanner'] = ScheduledSummitLocationBannerSerializer::class; + $this->registry['SummitBookableVenueRoom'] = SummitBookableVenueRoomSerializer::class; + $this->registry['SummitBookableVenueRoomAttributeType'] = SummitBookableVenueRoomAttributeTypeSerializer::class; $this->registry['SummitBookableVenueRoomAttributeValue'] = SummitBookableVenueRoomAttributeValueSerializer::class; - $this->registry['SummitBookableVenueRoomAvailableSlot'] = SummitBookableVenueRoomAvailableSlotSerializer::class; - $this->registry['SummitRoomReservation'] = SummitRoomReservationSerializer::class; + $this->registry['SummitBookableVenueRoomAvailableSlot'] = SummitBookableVenueRoomAvailableSlotSerializer::class; + $this->registry['SummitRoomReservation'] = SummitRoomReservationSerializer::class; // track tag groups $this->registry['TrackTagGroup'] = TrackTagGroupSerializer::class; @@ -368,62 +374,62 @@ final class SerializerRegistry // member $this->registry['Member'] = [ - self::SerializerType_Public => PublicMemberSerializer::class, + self::SerializerType_Public => PublicMemberSerializer::class, self::SerializerType_Private => OwnMemberSerializer::class, - self::SerializerType_Admin => AdminMemberSerializer::class + self::SerializerType_Admin => AdminMemberSerializer::class ]; $this->registry['LegalAgreement'] = LegalAgreementSerializer::class; $this->registry['LegalDocument'] = LegalDocumentSerializer::class; - $this->registry['Group'] = GroupSerializer::class; - $this->registry['Affiliation'] = AffiliationSerializer::class; - $this->registry['Organization'] = OrganizationSerializer::class; + $this->registry['Group'] = GroupSerializer::class; + $this->registry['Affiliation'] = AffiliationSerializer::class; + $this->registry['Organization'] = OrganizationSerializer::class; // push notification - $this->registry['PushNotificationMessage'] = PushNotificationMessageSerializer::class; - $this->registry['SummitPushNotification'] = SummitPushNotificationSerializer::class; + $this->registry['PushNotificationMessage'] = PushNotificationMessageSerializer::class; + $this->registry['SummitPushNotification'] = SummitPushNotificationSerializer::class; // teams - $this->registry['ChatTeam'] = ChatTeamSerializer::class; - $this->registry['ChatTeamMember'] = ChatTeamMemberSerializer::class; - $this->registry['ChatTeamInvitation'] = ChatTeamInvitationSerializer::class; + $this->registry['ChatTeam'] = ChatTeamSerializer::class; + $this->registry['ChatTeamMember'] = ChatTeamMemberSerializer::class; + $this->registry['ChatTeamInvitation'] = ChatTeamInvitationSerializer::class; $this->registry['ChatTeamPushNotificationMessage'] = ChatTeamPushNotificationMessageSerializer::class; // marketplace - $this->registry['Appliance'] = ApplianceSerializer::class; - $this->registry["Distribution"] = DistributionSerializer::class; - $this->registry['MarketPlaceReview'] = MarketPlaceReviewSerializer::class; + $this->registry['Appliance'] = ApplianceSerializer::class; + $this->registry["Distribution"] = DistributionSerializer::class; + $this->registry['MarketPlaceReview'] = MarketPlaceReviewSerializer::class; $this->registry['OpenStackImplementationApiCoverage'] = OpenStackImplementationApiCoverageSerializer::class; - $this->registry['GuestOSType'] = GuestOSTypeSerializer::class; - $this->registry['HyperVisorType'] = HyperVisorTypeSerializer::class; - $this->registry['Region'] = RegionSerializer::class; - $this->registry['RegionalSupport'] = RegionalSupportSerializer::class; - $this->registry['SupportChannelType'] = SupportChannelTypeSerializer::class; - $this->registry['Office'] = OfficeSerializer::class; - $this->registry['Consultant'] = ConsultantSerializer::class; - $this->registry['ConsultantClient'] = ConsultantClientSerializer::class; - $this->registry['SpokenLanguage'] = SpokenLanguageSerializer::class; - $this->registry['ConfigurationManagementType'] = ConfigurationManagementTypeSerializer::class; - $this->registry['ServiceOfferedType'] = ServiceOfferedTypeSerializer::class; - $this->registry['ConsultantServiceOfferedType'] = ConsultantServiceOfferedTypeSerializer::class; - $this->registry['DataCenterLocation'] = DataCenterLocationSerializer::class; - $this->registry['DataCenterRegion'] = DataCenterRegionSerializer::class; - $this->registry['PricingSchemaType'] = PricingSchemaTypeSerializer::class; - $this->registry['PrivateCloudService'] = PrivateCloudServiceSerializer::class; - $this->registry['PublicCloudService'] = PublicCloudServiceSerializer::class; - $this->registry['RemoteCloudService'] = RemoteCloudServiceSerializer::class; - $this->registry['CloudServiceOffered'] = CloudServiceOfferedSerializer::class; + $this->registry['GuestOSType'] = GuestOSTypeSerializer::class; + $this->registry['HyperVisorType'] = HyperVisorTypeSerializer::class; + $this->registry['Region'] = RegionSerializer::class; + $this->registry['RegionalSupport'] = RegionalSupportSerializer::class; + $this->registry['SupportChannelType'] = SupportChannelTypeSerializer::class; + $this->registry['Office'] = OfficeSerializer::class; + $this->registry['Consultant'] = ConsultantSerializer::class; + $this->registry['ConsultantClient'] = ConsultantClientSerializer::class; + $this->registry['SpokenLanguage'] = SpokenLanguageSerializer::class; + $this->registry['ConfigurationManagementType'] = ConfigurationManagementTypeSerializer::class; + $this->registry['ServiceOfferedType'] = ServiceOfferedTypeSerializer::class; + $this->registry['ConsultantServiceOfferedType'] = ConsultantServiceOfferedTypeSerializer::class; + $this->registry['DataCenterLocation'] = DataCenterLocationSerializer::class; + $this->registry['DataCenterRegion'] = DataCenterRegionSerializer::class; + $this->registry['PricingSchemaType'] = PricingSchemaTypeSerializer::class; + $this->registry['PrivateCloudService'] = PrivateCloudServiceSerializer::class; + $this->registry['PublicCloudService'] = PublicCloudServiceSerializer::class; + $this->registry['RemoteCloudService'] = RemoteCloudServiceSerializer::class; + $this->registry['CloudServiceOffered'] = CloudServiceOfferedSerializer::class; // software - $this->registry['OpenStackComponent'] = OpenStackComponentSerializer::class; - $this->registry['OpenStackRelease'] = OpenStackReleaseSerializer::class; + $this->registry['OpenStackComponent'] = OpenStackComponentSerializer::class; + $this->registry['OpenStackRelease'] = OpenStackReleaseSerializer::class; // ccla - $this->registry['Team'] = TeamSerializer::class; + $this->registry['Team'] = TeamSerializer::class; - $this->registry['File'] = FileSerializer::class; + $this->registry['File'] = FileSerializer::class; } /** @@ -431,17 +437,18 @@ final class SerializerRegistry * @param string $type * @return IModelSerializer */ - public function getSerializer($object, $type = self::SerializerType_Public){ - if(is_null($object)) return null; + public function getSerializer($object, $type = self::SerializerType_Public) + { + if (is_null($object)) return null; $reflect = new \ReflectionClass($object); - $class = $reflect->getShortName(); - if(!isset($this->registry[$class])) - throw new \InvalidArgumentException('Serializer not found for '.$class); + $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])) + 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]; } diff --git a/app/ModelSerializers/Summit/Presentation/PresentationSerializer.php b/app/ModelSerializers/Summit/Presentation/PresentationSerializer.php index c63b7b6c..eaad1574 100644 --- a/app/ModelSerializers/Summit/Presentation/PresentationSerializer.php +++ b/app/ModelSerializers/Summit/Presentation/PresentationSerializer.php @@ -148,7 +148,7 @@ class PresentationSerializer extends SummitEventSerializer if(in_array('extra_questions', $relations)) { $answers = []; - foreach ($presentation->getAnswers() as $answer) { + foreach ($presentation->getExtraQuestionAnswers() as $answer) { $answers[] = $answer->getId(); } $values['extra_questions'] = $answers; @@ -257,7 +257,7 @@ class PresentationSerializer extends SummitEventSerializer break; case 'extra_questions':{ $answers = []; - foreach ($presentation->getAnswers() as $answer) { + foreach ($presentation->getExtraQuestionAnswers() as $answer) { $answers[]= SerializerRegistry::getInstance()->getSerializer($answer)->serialize(AbstractSerializer::filterExpandByPrefix($expand, $relation)); } $values['extra_questions'] = $answers; diff --git a/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionAnswerSerializer.php b/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionAnswerSerializer.php index bb45c17c..4e6625c2 100644 --- a/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionAnswerSerializer.php +++ b/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionAnswerSerializer.php @@ -11,20 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ - use Libs\ModelSerializers\AbstractSerializer; use models\summit\SummitOrderExtraQuestionAnswer; /** * Class SummitOrderExtraQuestionAnswerSerializer * @package ModelSerializers */ -final class SummitOrderExtraQuestionAnswerSerializer extends SilverStripeSerializer +final class SummitOrderExtraQuestionAnswerSerializer extends ExtraQuestionAnswerSerializer { protected static $array_mappings = [ - 'Value' => 'value:json_string', 'OrderId' => 'order_id:json_int', 'AttendeeId' => 'attendee_id:json_int', - 'QuestionId' => 'question_id:json_int', ]; /** @@ -42,7 +39,6 @@ final class SummitOrderExtraQuestionAnswerSerializer extends SilverStripeSeriali if (!count($relations)) $relations = $this->getAllowedRelations(); - if (!empty($expand)) { $exp_expand = explode(',', $expand); foreach ($exp_expand as $relation) { @@ -53,7 +49,8 @@ final class SummitOrderExtraQuestionAnswerSerializer extends SilverStripeSeriali if ($answer->hasOrder()) { unset($values['order_id']); - $values['order'] = SerializerRegistry::getInstance()->getSerializer($answer->getOrder())->serialize(AbstractSerializer::getExpandForPrefix('order', $expand)); + $values['order'] = SerializerRegistry::getInstance()->getSerializer($answer->getOrder()) + ->serialize(AbstractSerializer::getExpandForPrefix('order', $expand)); } } break; @@ -63,22 +60,12 @@ final class SummitOrderExtraQuestionAnswerSerializer extends SilverStripeSeriali if ($answer->hasAttendee()) { unset($values['attendee_id']); - $values['attendee'] = SerializerRegistry::getInstance()->getSerializer($answer->getAttendee())->serialize(AbstractSerializer::getExpandForPrefix('attendee', $expand)); + $values['attendee'] = SerializerRegistry::getInstance()->getSerializer($answer->getAttendee()) + ->serialize(AbstractSerializer::getExpandForPrefix('attendee', $expand)); } } break; - case 'question': - { - - if ($answer->hasQuestion()) { - unset($values['question_id']); - $values['question'] = SerializerRegistry::getInstance()->getSerializer($answer->getQuestion())->serialize(AbstractSerializer::getExpandForPrefix('question', $expand)); - } - } - break; - - } } } diff --git a/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionTypeSerializer.php b/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionTypeSerializer.php index 521fbcde..6880f7e8 100644 --- a/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionTypeSerializer.php +++ b/app/ModelSerializers/Summit/Registration/SummitOrderExtraQuestionTypeSerializer.php @@ -16,24 +16,14 @@ use models\summit\SummitOrderExtraQuestionType; * Class SummitOrderExtraQuestionTypeSerializer * @package ModelSerializers */ -final class SummitOrderExtraQuestionTypeSerializer extends SilverStripeSerializer +final class SummitOrderExtraQuestionTypeSerializer extends ExtraQuestionTypeSerializer { protected static $array_mappings = [ - 'Name' => 'name:json_string', - 'Type' => 'type:json_string', - 'Label' => 'label:json_string', 'Usage' => 'usage:json_string', - 'Placeholder' => 'placeholder:json_string', 'Printable' => 'printable:json_boolean', - 'Order' => 'order:json_int', - 'Mandatory' => 'mandatory:json_boolean', 'SummitId' => 'summit_id:json_int', ]; - protected static $allowed_relations = [ - 'values', - ]; - /** * @param null $expand * @param array $fields @@ -47,36 +37,6 @@ final class SummitOrderExtraQuestionTypeSerializer extends SilverStripeSerialize if (!$question instanceof SummitOrderExtraQuestionType) return []; if(!count($relations)) $relations = $this->getAllowedRelations(); $values = parent::serialize($expand, $fields, $relations, $params); - - if(in_array('values', $relations) && $question->allowsValues()) { - $question_values = []; - foreach ($question->getValues() as $value) { - $question_values[] = $value->getId(); - } - $values['values'] = $question_values; - } - - if (!empty($expand)) { - $exp_expand = explode(',', $expand); - foreach ($exp_expand as $relation) { - switch (trim($relation)) { - case 'values': - { - if (!$question->allowsValues()) - break; - unset($values['values']); - $question_values = []; - foreach ($question->getValues() as $value) { - $question_values[] = SerializerRegistry::getInstance()->getSerializer($value)->serialize(); - } - $values['values'] = $question_values; - } - break; - - - } - } - } return $values; } } \ No newline at end of file diff --git a/app/ModelSerializers/Summit/SelectionPlanSerializer.php b/app/ModelSerializers/Summit/SelectionPlanSerializer.php index b207d1eb..1e19118e 100644 --- a/app/ModelSerializers/Summit/SelectionPlanSerializer.php +++ b/app/ModelSerializers/Summit/SelectionPlanSerializer.php @@ -1,4 +1,4 @@ -getExtraQuestions() as $extraQuestion) { + $extra_questions[] = $extraQuestion->getId(); + } + + $values['extra_questions'] = $extra_questions; + if (!empty($expand)) { $relations = explode(',', $expand); foreach ($relations as $relation) { @@ -68,6 +75,14 @@ final class SelectionPlanSerializer extends SilverStripeSerializer $values['track_groups'] = $category_groups; } break; + case 'extra_questions':{ + $extra_questions = []; + foreach ($selection_plan->getExtraQuestions() as $extraQuestion) { + $extra_questions[] = SerializerRegistry::getInstance()->getSerializer($extraQuestion)->serialize(AbstractSerializer::filterExpandByPrefix($expand, $relation)); + } + $values['extra_questions'] = $extra_questions; + } + break; case 'summit':{ unset($values['summit_id']); $values['summit'] = SerializerRegistry::getInstance()->getSerializer($selection_plan->getSummit())->serialize(AbstractSerializer::filterExpandByPrefix($expand, $relation)); diff --git a/app/ModelSerializers/Summit/SummitSelectionPlanExtraQuestionTypeSerializer.php b/app/ModelSerializers/Summit/SummitSelectionPlanExtraQuestionTypeSerializer.php new file mode 100644 index 00000000..a42c6325 --- /dev/null +++ b/app/ModelSerializers/Summit/SummitSelectionPlanExtraQuestionTypeSerializer.php @@ -0,0 +1,25 @@ + 'selection_plan_id:json_int', + ]; + +} \ No newline at end of file diff --git a/app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionAnswer.php b/app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionAnswer.php new file mode 100644 index 00000000..0a07c9a4 --- /dev/null +++ b/app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionAnswer.php @@ -0,0 +1,94 @@ + 'question', + ]; + + protected $hasPropertyMappings = [ + 'hasQuestion' => 'question', + ]; + + /** + * @return bool + */ + public function hasValue():bool { + return !empty($this->value); + } + + /** + * @return ExtraQuestionType + */ + public function getQuestion(): ExtraQuestionType + { + return $this->question; + } + + /** + * @param ExtraQuestionType $question + */ + public function setQuestion(ExtraQuestionType $question): void + { + $this->question = $question; + } + + /** + * @return string + */ + public function getValue(): string + { + return $this->value; + } + + /** + * @param string $value + */ + public function setValue(string $value): void + { + $this->value = $value; + } +} \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Registration/Questions/SummitOrderExtraQuestionType.php b/app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionType.php similarity index 66% rename from app/Models/Foundation/Summit/Registration/Questions/SummitOrderExtraQuestionType.php rename to app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionType.php index ffc7f141..c9972b47 100644 --- a/app/Models/Foundation/Summit/Registration/Questions/SummitOrderExtraQuestionType.php +++ b/app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionType.php @@ -1,6 +1,6 @@ -values = new ArrayCollection(); + $this->mandatory = false; + $this->order = 1; + } /** * @return string @@ -116,16 +112,19 @@ implements IOrderable /** * @return string */ - public function getPlaceholder(): string + public function getPlaceholder(): ?string { return $this->placeholder; } /** * @param string $placeholder + * @throws ValidationException */ public function setPlaceholder(string $placeholder): void { + if(!in_array($this->type, ExtraQuestionTypeConstants::AllowedPlaceHolderQuestionType)) + throw new ValidationException(sprintf("%s type does not allows a placeholder", $this->type)); $this->placeholder = $placeholder; } @@ -135,7 +134,7 @@ implements IOrderable */ public function setType(string $type): void { - if(!in_array($type, SummitOrderExtraQuestionTypeConstants::ValidQuestionTypes)) + if(!in_array($type, ExtraQuestionTypeConstants::ValidQuestionTypes)) throw new ValidationException(sprintf("%s type is not valid", $type)); $this->type = $type; @@ -190,67 +189,16 @@ implements IOrderable } /** - * @return string - */ - public function getUsage(): string - { - return $this->usage; - } - - /** - * @param string $usage + * @param ExtraQuestionTypeValue $value * @throws ValidationException */ - public function setUsage(string $usage): void - { - if(!in_array($usage, SummitOrderExtraQuestionTypeConstants::ValidQuestionUsages)) - throw new ValidationException(sprintf("%s usage is not valid", $usage)); - $this->usage = $usage; - } - - /** - * @return bool - */ - public function isPrintable(): bool - { - return $this->printable; - } - - /** - * @param bool $printable - */ - public function setPrintable(bool $printable): void - { - $this->printable = $printable; - } - - public function __construct() - { - parent::__construct(); - $this->values = new ArrayCollection(); - $this->mandatory = false; - $this->printable = false; - } - - /** - * @return SummitOrderExtraQuestionValue[] - */ - public function getValues() - { - return $this->values; - } - - /** - * @param SummitOrderExtraQuestionValue $value - * @throws ValidationException - */ - public function addValue(SummitOrderExtraQuestionValue $value){ + public function addValue(ExtraQuestionTypeValue $value){ if(!$this->allowsValues()) - throw new ValidationException(sprintf("%s type does not allow multivalues", $this->type)); + throw new ValidationException(sprintf("%s type does not allow multiple values.", $this->type)); if($this->values->contains($value)) return; + $value->setOrder($this->getValueMaxOrder() + 1); $this->values->add($value); $value->setQuestion($this); - $value->setOrder($this->getValueMaxOrder() + 1); } /** @@ -264,15 +212,15 @@ implements IOrderable } public function allowsValues():bool { - return in_array($this->type, SummitOrderExtraQuestionTypeConstants::AllowedMultivalueQuestionType); + return in_array($this->type, ExtraQuestionTypeConstants::AllowedMultiValueQuestionType); } /** - * @param SummitOrderExtraQuestionValue $value + * @param ExtraQuestionTypeValue $value * @throws ValidationException */ - public function removeValue(SummitOrderExtraQuestionValue $value){ + public function removeValue(ExtraQuestionTypeValue $value){ if(!$this->allowsValues()) - throw new ValidationException(sprintf("%s type does not allow multivalues", $this->type)); + throw new ValidationException(sprintf("%s type does not allow multiple values.", $this->type)); if(!$this->values->contains($value)) return; $this->values->removeElement($value); @@ -280,9 +228,9 @@ implements IOrderable /** * @param string $label - * @return SummitOrderExtraQuestionValue|null + * @return ExtraQuestionTypeValue|null */ - public function getValueByLabel(string $label):?SummitOrderExtraQuestionValue{ + public function getValueByLabel(string $label):?ExtraQuestionTypeValue{ $criteria = Criteria::create(); $criteria->where(Criteria::expr()->eq('label', trim($label))); $value = $this->values->matching($criteria)->first(); @@ -291,9 +239,9 @@ implements IOrderable /** * @param string $name - * @return SummitOrderExtraQuestionValue|null + * @return ExtraQuestionTypeValue|null */ - public function getValueByName(string $name):?SummitOrderExtraQuestionValue{ + public function getValueByName(string $name):?ExtraQuestionTypeValue{ $criteria = Criteria::create(); $criteria->where(Criteria::expr()->eq('value', trim($name))); $value = $this->values->matching($criteria)->first(); @@ -308,7 +256,7 @@ implements IOrderable if(empty($value) && !$this->isMandatory()) return true; - if($this->type == SummitOrderExtraQuestionTypeConstants::ComboBoxQuestionType) + if($this->type == ExtraQuestionTypeConstants::ComboBoxQuestionType) return !is_null($this->getValueById(intval($value))); foreach (explode(',',$value) as $v) @@ -321,9 +269,9 @@ implements IOrderable /** * @param int $id - * @return SummitOrderExtraQuestionValue|null + * @return ExtraQuestionTypeValue|null */ - public function getValueById(int $id):?SummitOrderExtraQuestionValue{ + public function getValueById(int $id):?ExtraQuestionTypeValue{ $criteria = Criteria::create(); $criteria->where(Criteria::expr()->eq('id', $id)); $value = $this->values->matching($criteria)->first(); @@ -333,11 +281,11 @@ implements IOrderable use OrderableChilds; /** - * @param SummitOrderExtraQuestionValue $value + * @param ExtraQuestionTypeValue $value * @param int $new_order * @throws ValidationException */ - public function recalculateValueOrder(SummitOrderExtraQuestionValue $value, $new_order){ + public function recalculateValueOrder(ExtraQuestionTypeValue $value, $new_order){ self::recalculateOrderForSelectable($this->values, $value, $new_order); } @@ -366,4 +314,11 @@ implements IOrderable return implode(',', $niceValues); } + /** + * @return ExtraQuestionTypeValue[]|ArrayCollection + */ + public function getValues(){ + return $this->values; + } + } \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Registration/Questions/SummitOrderExtraQuestionTypeConstants.php b/app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionTypeConstants.php similarity index 72% rename from app/Models/Foundation/Summit/Registration/Questions/SummitOrderExtraQuestionTypeConstants.php rename to app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionTypeConstants.php index b0b8587d..175bf730 100644 --- a/app/Models/Foundation/Summit/Registration/Questions/SummitOrderExtraQuestionTypeConstants.php +++ b/app/Models/Foundation/Main/ExtraQuestions/ExtraQuestionTypeConstants.php @@ -1,6 +1,6 @@ -question; } /** - * @param SummitOrderExtraQuestionType $question + * @param ExtraQuestionType $question */ - public function setQuestion(SummitOrderExtraQuestionType $question): void + public function setQuestion(ExtraQuestionType $question): void { $this->question = $question; } @@ -115,7 +115,7 @@ class SummitOrderExtraQuestionValue extends SilverstripeBaseModel public function __construct() { parent::__construct(); - $this->order = 0; + $this->order = 1; } /** @@ -130,5 +130,4 @@ class SummitOrderExtraQuestionValue extends SilverstripeBaseModel } } - } \ No newline at end of file diff --git a/app/Models/Foundation/Main/ExtraQuestions/Factories/ExtraQuestionTypeFactory.php b/app/Models/Foundation/Main/ExtraQuestions/Factories/ExtraQuestionTypeFactory.php new file mode 100644 index 00000000..9a25f31b --- /dev/null +++ b/app/Models/Foundation/Main/ExtraQuestions/Factories/ExtraQuestionTypeFactory.php @@ -0,0 +1,55 @@ +setName(trim($data['name'])); + + if(isset($data['label'])) + $question->setLabel(trim($data['label'])); + + if(isset($data['type'])) + $question->setType(trim($data['type'])); + + if(isset($data['placeholder'])) + $question->setPlaceholder(trim($data['placeholder'])); + + if(isset($data['mandatory'])) + $question->setMandatory(boolval($data['mandatory'])); + + return $question; + } +} \ No newline at end of file diff --git a/app/Models/Foundation/Main/ExtraQuestions/IExtraQuestionTypeRepository.php b/app/Models/Foundation/Main/ExtraQuestions/IExtraQuestionTypeRepository.php new file mode 100644 index 00000000..d799e62e --- /dev/null +++ b/app/Models/Foundation/Main/ExtraQuestions/IExtraQuestionTypeRepository.php @@ -0,0 +1,37 @@ +presentation; + } + + /** + * @param Presentation $presentation + */ + public function setPresentation(Presentation $presentation): void + { + $this->presentation = $presentation; + } + + public function clearPresentation(){ + $this->presentation = null; + } + +} \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Events/Presentations/Presentation.php b/app/Models/Foundation/Summit/Events/Presentations/Presentation.php index 82cc6cf9..79cdcb28 100644 --- a/app/Models/Foundation/Summit/Events/Presentations/Presentation.php +++ b/app/Models/Foundation/Summit/Events/Presentations/Presentation.php @@ -12,7 +12,7 @@ * limitations under the License. **/ -use Doctrine\ORM\Mapping AS ORM; +use App\Models\Foundation\Summit\ExtraQuestions\SummitSelectionPlanExtraQuestionType; use App\Models\Foundation\Main\OrderableChilds; use Behat\Transliterator\Transliterator; use App\Models\Foundation\Summit\Events\Presentations\TrackQuestions\TrackAnswer; @@ -24,6 +24,7 @@ use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Log; use models\exceptions\ValidationException; use models\main\Member; +use Doctrine\ORM\Mapping AS ORM; /** * Class Presentation @@ -205,6 +206,12 @@ class Presentation extends SummitEvent */ private $actions; + /** + * @ORM\OneToMany(targetEntity="models\summit\PresentationExtraQuestionAnswer", mappedBy="presentation", cascade={"persist","remove"}, orphanRemoval=true) + * @var PresentationExtraQuestionAnswer[] + */ + private $extra_question_answers; + /** * @return bool */ @@ -245,6 +252,7 @@ class Presentation extends SummitEvent $this->category_changes_requests = new ArrayCollection(); $this->selected_presentations = new ArrayCollection(); $this->actions = new ArrayCollection(); + $this->extra_question_answers = new ArrayCollection(); $this->to_record = false; $this->attending_media = false; $this->will_all_speakers_attend = false; @@ -872,6 +880,7 @@ class Presentation extends SummitEvent } /** + * @deprecated * @return TrackAnswer[] */ public function getAnswers() @@ -880,6 +889,7 @@ class Presentation extends SummitEvent } /** + * @deprecated * @param TrackAnswer[] $answers */ public function setAnswers($answers) @@ -888,6 +898,7 @@ class Presentation extends SummitEvent } /** + * @deprecated * @param TrackAnswer $answer */ public function addAnswer(TrackAnswer $answer) @@ -922,6 +933,7 @@ class Presentation extends SummitEvent } /** + * @deprecated * @param TrackQuestionTemplate $question * @return TrackAnswer|null */ @@ -1551,4 +1563,47 @@ class Presentation extends SummitEvent $this->will_all_speakers_attend = $will_all_speakers_attend; } + /** + * @return PresentationExtraQuestionAnswer[] + */ + public function getExtraQuestionAnswers() + { + return $this->extra_question_answers; + } + + /** + * @param SummitSelectionPlanExtraQuestionType $question + * @return PresentationExtraQuestionAnswer|null + */ + public function getExtraQuestionAnswerByQuestion(SummitSelectionPlanExtraQuestionType $question):?PresentationExtraQuestionAnswer{ + $answer = $this->extra_question_answers->matching( + $criteria = Criteria::create() + ->where(Criteria::expr()->eq("question", $question)) + )->first(); + return $answer ? $answer : null; + } + + public function clearExtraQuestionAnswers() + { + return $this->extra_question_answers->clear(); + } + + /** + * @param PresentationExtraQuestionAnswer $answer + */ + public function addExtraQuestionAnswer(PresentationExtraQuestionAnswer $answer){ + if($this->extra_question_answers->contains($answer)) return; + $this->extra_question_answers->add($answer); + $answer->setPresentation($this); + } + + /** + * @param PresentationExtraQuestionAnswer $answer + */ + public function removeExtraQuestionAnswer(PresentationExtraQuestionAnswer $answer){ + if(!$this->extra_question_answers->contains($answer)) return; + $this->extra_question_answers->removeElement($answer); + $answer->clearPresentation(); + } + } diff --git a/app/Models/Foundation/Summit/ExtraQuestions/SummitSelectionPlanExtraQuestionType.php b/app/Models/Foundation/Summit/ExtraQuestions/SummitSelectionPlanExtraQuestionType.php new file mode 100644 index 00000000..75fb4f92 --- /dev/null +++ b/app/Models/Foundation/Summit/ExtraQuestions/SummitSelectionPlanExtraQuestionType.php @@ -0,0 +1,63 @@ +selection_plan; + } + + /** + * @param SelectionPlan $selection_plan + */ + public function setSelectionPlan(SelectionPlan $selection_plan): void + { + $this->selection_plan = $selection_plan; + } + + use One2ManyPropertyTrait; + + protected $getIdMappings = [ + 'getSelectionPlanId' => 'selection_plan', + ]; + + protected $hasPropertyMappings = [ + 'hasSelectionPlan' => 'selection_plan', + ]; + + public function clearSelectionPlan():void{ + $this->selection_plan = null; + } +} \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Factories/SummitAttendeeFactory.php b/app/Models/Foundation/Summit/Factories/SummitAttendeeFactory.php index 7ce3fed8..20ffa58e 100644 --- a/app/Models/Foundation/Summit/Factories/SummitAttendeeFactory.php +++ b/app/Models/Foundation/Summit/Factories/SummitAttendeeFactory.php @@ -111,12 +111,12 @@ final class SummitAttendeeFactory $extra_questions = $payload['extra_questions'] ?? []; - if (count($extra_questions)) { + $mandatory_questions = $summit->getMandatoryOrderExtraQuestionsByUsage(SummitOrderExtraQuestionTypeConstants::TicketQuestionUsage); + if (count($extra_questions) < $mandatory_questions->count()) { + throw new ValidationException("You neglected to fill in all mandatory questions for the attendee."); + } - $mandatory_questions = $summit->getMandatoryOrderExtraQuestionsByUsage(SummitOrderExtraQuestionTypeConstants::TicketQuestionUsage); - if (count($extra_questions) < $mandatory_questions->count()) { - throw new ValidationException("You neglected to fill in all mandatory questions for the attendee."); - } + if (count($extra_questions)) { $questions = $summit->getOrderExtraQuestionsByUsage(SummitOrderExtraQuestionTypeConstants::TicketQuestionUsage); if ($questions->count() > 0) { diff --git a/app/Models/Foundation/Summit/Factories/SummitOrderExtraQuestionTypeFactory.php b/app/Models/Foundation/Summit/Factories/SummitOrderExtraQuestionTypeFactory.php index a3fb7eb9..a3640d3d 100644 --- a/app/Models/Foundation/Summit/Factories/SummitOrderExtraQuestionTypeFactory.php +++ b/app/Models/Foundation/Summit/Factories/SummitOrderExtraQuestionTypeFactory.php @@ -11,36 +11,24 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +use App\Models\Foundation\ExtraQuestions\ExtraQuestionType; +use App\Models\Foundation\ExtraQuestions\Factories\ExtraQuestionTypeFactory; use models\summit\SummitOrderExtraQuestionType; /** * Class SummitOrderExtraQuestionTypeFactory * @package App\Models\Foundation\Summit\Factories */ -final class SummitOrderExtraQuestionTypeFactory +final class SummitOrderExtraQuestionTypeFactory extends ExtraQuestionTypeFactory { /** + * @param ExtraQuestionType $question * @param array $data - * @return SummitOrderExtraQuestionType + * @return ExtraQuestionType + * @throws \models\exceptions\ValidationException */ - public static function build(array $data):SummitOrderExtraQuestionType{ - return self::populate(new SummitOrderExtraQuestionType, $data); - } + public static function populate(ExtraQuestionType $question, array $data):ExtraQuestionType{ - /** - * @param SummitOrderExtraQuestionType $question - * @param array $data - * @return SummitOrderExtraQuestionType - */ - public static function populate(SummitOrderExtraQuestionType $question, array $data):SummitOrderExtraQuestionType{ - - if(isset($data['name'])) - $question->setName(trim($data['name'])); - - if(isset($data['label'])) - $question->setLabel(trim($data['label'])); - - if(isset($data['type'])) - $question->setType(trim($data['type'])); + $question = parent::populate($question, $data); if(isset($data['usage'])) $question->setUsage(trim($data['usage'])); @@ -48,13 +36,11 @@ final class SummitOrderExtraQuestionTypeFactory if(isset($data['printable'])) $question->setPrintable(boolval($data['printable'])); - if(isset($data['placeholder'])) - $question->setPlaceholder(trim($data['placeholder'])); - - if(isset($data['mandatory'])) - $question->setMandatory(boolval($data['mandatory'])); - - return $question; } + + protected static function getNewEntity(): ExtraQuestionType + { + return new SummitOrderExtraQuestionType; + } } \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Factories/SummitOrderExtraQuestionValueFactory.php b/app/Models/Foundation/Summit/Factories/SummitOrderExtraQuestionValueFactory.php index 71e5c6b3..13bc5c2d 100644 --- a/app/Models/Foundation/Summit/Factories/SummitOrderExtraQuestionValueFactory.php +++ b/app/Models/Foundation/Summit/Factories/SummitOrderExtraQuestionValueFactory.php @@ -1,4 +1,4 @@ -setLabel(trim($data['label'])); diff --git a/app/Models/Foundation/Summit/Factories/SummitSelectionPlanExtraQuestionTypeFactory.php b/app/Models/Foundation/Summit/Factories/SummitSelectionPlanExtraQuestionTypeFactory.php new file mode 100644 index 00000000..04e63072 --- /dev/null +++ b/app/Models/Foundation/Summit/Factories/SummitSelectionPlanExtraQuestionTypeFactory.php @@ -0,0 +1,29 @@ +usage; + } + + /** + * @param string $usage + * @throws ValidationException + */ + public function setUsage(string $usage): void + { + if(!in_array($usage, SummitOrderExtraQuestionTypeConstants::ValidQuestionUsages)) + throw new ValidationException(sprintf("%s usage is not valid", $usage)); + $this->usage = $usage; + } + + /** + * @return bool + */ + public function isPrintable(): bool + { + return $this->printable; + } + + /** + * @param bool $printable + */ + public function setPrintable(bool $printable): void + { + $this->printable = $printable; + } + + public function __construct() + { + parent::__construct(); + $this->printable = false; + } + +} \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Registration/ExtraQuestions/SummitOrderExtraQuestionTypeConstants.php b/app/Models/Foundation/Summit/Registration/ExtraQuestions/SummitOrderExtraQuestionTypeConstants.php new file mode 100644 index 00000000..19fbcb11 --- /dev/null +++ b/app/Models/Foundation/Summit/Registration/ExtraQuestions/SummitOrderExtraQuestionTypeConstants.php @@ -0,0 +1,32 @@ +attendee = $attendee; } - /** - * @return SummitOrderExtraQuestionType - */ - public function getQuestion(): ?SummitOrderExtraQuestionType - { - return $this->question; - } - - /** - * @param SummitOrderExtraQuestionType $question - */ - public function setQuestion(SummitOrderExtraQuestionType $question): void - { - $this->question = $question; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->value; - } - - /** - * @return bool - */ - public function hasValue():bool { - return !empty($this->value); - } - - /** - * @param string $value - */ - public function setValue(string $value): void - { - $this->value = $value; - } public function clearOrder(){ $this->order = null; diff --git a/app/Models/Foundation/Summit/Repositories/ISummitOrderExtraQuestionTypeRepository.php b/app/Models/Foundation/Summit/Repositories/ISummitOrderExtraQuestionTypeRepository.php index e63a53da..b6ef4468 100644 --- a/app/Models/Foundation/Summit/Repositories/ISummitOrderExtraQuestionTypeRepository.php +++ b/app/Models/Foundation/Summit/Repositories/ISummitOrderExtraQuestionTypeRepository.php @@ -11,32 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ -use models\summit\Summit; -use models\summit\SummitOrder; -use models\summit\SummitOrderExtraQuestionType; -use models\utils\IBaseRepository; +use App\Models\Foundation\ExtraQuestions\IExtraQuestionTypeRepository; /** * Interface ISummitOrderExtraQuestionTypeRepository * @package App\Models\Foundation\Summit\Repositories */ -interface ISummitOrderExtraQuestionTypeRepository extends IBaseRepository +interface ISummitOrderExtraQuestionTypeRepository extends IExtraQuestionTypeRepository { - /** - * @param Summit $summit - * @return array - */ - public function getQuestionsMetadata(Summit $summit); - - /** - * @param SummitOrderExtraQuestionType $questionType - * @return bool - */ - public function hasAnswers(SummitOrderExtraQuestionType $questionType):bool; - - /** - * @param SummitOrderExtraQuestionType $questionType - * @return void - */ - public function deleteAnswersFrom(SummitOrderExtraQuestionType $questionType):void; - } \ No newline at end of file diff --git a/app/Models/Foundation/Summit/Repositories/ISummitSelectionPlanExtraQuestionTypeRepository.php b/app/Models/Foundation/Summit/Repositories/ISummitSelectionPlanExtraQuestionTypeRepository.php new file mode 100644 index 00000000..15f50103 --- /dev/null +++ b/app/Models/Foundation/Summit/Repositories/ISummitSelectionPlanExtraQuestionTypeRepository.php @@ -0,0 +1,23 @@ +allow_new_presentations = true; $this->category_groups = new ArrayCollection; $this->presentations = new ArrayCollection; + $this->extra_questions = new ArrayCollection; $this->max_submission_allowed_per_user = Summit::DefaultMaxSubmissionAllowedPerUser; } @@ -448,4 +458,105 @@ class SelectionPlan extends SilverstripeBaseModel $presentation = $this->presentations->matching($criteria)->first(); return $presentation === false ? null : $presentation; } + + /** + * Extra Questions + */ + + + /** + * @param int $question_id + * @return SummitSelectionPlanExtraQuestionType|null + */ + public function getExtraQuestionById(int $question_id):?SummitSelectionPlanExtraQuestionType{ + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('id', $question_id)); + $question = $this->extra_questions->matching($criteria)->first(); + return $question === false ? null : $question; + } + + /** + * @param string $name + * @return SummitSelectionPlanExtraQuestionType|null + */ + public function getExtraQuestionByName(string $name):?SummitSelectionPlanExtraQuestionType{ + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('name', trim($name))); + $question = $this->extra_questions->matching($criteria)->first(); + return $question === false ? null : $question; + } + + /** + * @param string $label + * @return SummitSelectionPlanExtraQuestionType|null + */ + public function getExtraQuestionByLabel(string $label):?SummitSelectionPlanExtraQuestionType{ + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('label', trim($label))); + $question = $this->extra_questions->matching($criteria)->first(); + return $question === false ? null : $question; + } + + /** + * @return int + */ + private function getExtraQuestionMaxOrder():int{ + $criteria = Criteria::create(); + $criteria->orderBy(['order' => 'DESC']); + $question = $this->extra_questions->matching($criteria)->first(); + return $question === false ? 0 : $question->getOrder(); + } + + /** + * @param SummitSelectionPlanExtraQuestionType $question + * @throws ValidationException + */ + public function addExtraQuestion(SummitSelectionPlanExtraQuestionType $question){ + if($this->extra_questions->contains($question)) return; + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('name', $question->getName())); + $formerExtraQuestion = $this->extra_questions->matching($criteria)->first(); + if($formerExtraQuestion){ + throw new ValidationException(sprintf("Question Name %s already exists.", $question->getName())); + }; + $question->setOrder($this->getExtraQuestionMaxOrder()+1); + $this->extra_questions->add($question); + $question->setSelectionPlan($this); + } + + public function removeExtraQuestion(SummitSelectionPlanExtraQuestionType $question){ + if(!$this->extra_questions->contains($question)) return; + $this->extra_questions->removeElement($question); + $question->clearSelectionPlan(); + } + + use OrderableChilds; + + /** + * @param SummitSelectionPlanExtraQuestionType $question + * @param int $new_order + * @throws ValidationException + */ + public function recalculateQuestionOrder(SummitSelectionPlanExtraQuestionType $question, $new_order){ + self::recalculateOrderForSelectable($this->extra_questions, $question, $new_order); + } + + /** + * @return ArrayCollection|\Doctrine\Common\Collections\Collection + */ + public function getExtraQuestions(){ + $criteria = Criteria::create(); + $criteria->orderBy(['order' => 'ASC']); + return $this->extra_questions->matching($criteria); + } + + /** + * @return ArrayCollection|\Doctrine\Common\Collections\Collection + */ + public function getMandatoryExtraQuestions(){ + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('mandatory', true)); + return $this->extra_questions->matching($criteria); + } + } \ No newline at end of file diff --git a/app/Repositories/Main/DoctrineExtraQuestionTypeRepository.php b/app/Repositories/Main/DoctrineExtraQuestionTypeRepository.php new file mode 100644 index 00000000..faed9d48 --- /dev/null +++ b/app/Repositories/Main/DoctrineExtraQuestionTypeRepository.php @@ -0,0 +1,124 @@ + 'e.name:json_string', + 'type' => 'e.type:json_string', + 'label' => 'e.label:json_string', + ]; + } + + /** + * @return array + */ + protected function getOrderMappings() + { + return [ + 'id' => 'e.id', + 'name' => 'e.name', + 'label' => 'e.label', + 'order' => 'e.order', + ]; + } + + /** + * @return array + */ + public function getQuestionsMetadata() + { + return [ + [ + 'type' => 'TextArea', + ], + [ + 'type' => 'Text', + ], + [ + 'type' => 'CheckBox', + ], + [ + 'type' => 'ComboBox', + 'values' => 'array', + ], + [ + 'type' => 'CheckBoxList', + 'values' => 'array', + ], + [ + 'type' => 'RadioButtonList', + 'values' => 'array', + ], + + ]; + } + + /** + * @param ExtraQuestionType $questionType + * @return bool + */ + public function hasAnswers(ExtraQuestionType $questionType): bool + { + try { + $query = $this->getEntityManager() + ->createQueryBuilder() + ->select("count(e.id)") + ->from($this->getBaseEntity(), "e")->join("e.question", "q") + ->where("q = :question")->setParameter("question", $questionType); + + return $query->getQuery()->getSingleScalarResult() > 0; + } + catch (\Exception $ex){ + Log::error($ex); + return false; + } + } + + /** + * @param ExtraQuestionType $questionType + */ + public function deleteAnswersFrom(ExtraQuestionType $questionType):void{ + try { + $query = $this->getEntityManager() + ->createQueryBuilder() + ->delete($this->getBaseEntity(), "e") + ->where("e.question = :question") + ->setParameter("question", $questionType); + + $query->getQuery()->execute(); + } + catch (\Exception $ex){ + Log::error($ex); + } + } +} \ No newline at end of file diff --git a/app/Repositories/RepositoriesProvider.php b/app/Repositories/RepositoriesProvider.php index 5caefbd6..a1573866 100644 --- a/app/Repositories/RepositoriesProvider.php +++ b/app/Repositories/RepositoriesProvider.php @@ -24,6 +24,7 @@ use App\Models\Foundation\Summit\DefaultTrackTagGroup; use App\Models\Foundation\Summit\EmailFlows\SummitEmailEventFlow; use App\Models\Foundation\Summit\Events\Presentations\TrackQuestions\TrackQuestionTemplate; use App\Models\Foundation\Summit\Events\RSVP\RSVPTemplate; +use App\Models\Foundation\Summit\ExtraQuestions\SummitSelectionPlanExtraQuestionType; use App\Models\Foundation\Summit\Locations\Banners\SummitLocationBanner; use App\Models\Foundation\Summit\Repositories\IDefaultSummitEventTypeRepository; use App\Models\Foundation\Summit\Repositories\IDefaultTrackTagGroupRepository; @@ -59,6 +60,7 @@ use App\Models\Foundation\Summit\Repositories\ISummitOrderRepository; use App\Models\Foundation\Summit\Repositories\ISummitRefundPolicyTypeRepository; use App\Models\Foundation\Summit\Repositories\ISummitRegistrationInvitationRepository; use App\Models\Foundation\Summit\Repositories\ISummitRoomReservationRepository; +use App\Models\Foundation\Summit\Repositories\ISummitSelectionPlanExtraQuestionTypeRepository; use App\Models\Foundation\Summit\Repositories\ISummitTaxTypeRepository; use App\Models\Foundation\Summit\Repositories\ISummitTrackChairRepository; use App\Models\Foundation\Summit\Repositories\ISummitTrackRepository; @@ -120,6 +122,7 @@ use models\summit\SummitTaxType; use models\summit\SummitTicketType; use models\summit\SummitTrackChair; use repositories\main\DoctrineLegalDocumentRepository; + /** * Class RepositoriesProvider * @package repositories @@ -669,5 +672,12 @@ final class RepositoriesProvider extends ServiceProvider return EntityManager::getRepository(PresentationActionType::class); } ); + + App::singleton( + ISummitSelectionPlanExtraQuestionTypeRepository::class, + function(){ + return EntityManager::getRepository(SummitSelectionPlanExtraQuestionType::class); + } + ); } } \ No newline at end of file diff --git a/app/Repositories/Summit/DoctrineSummitOrderExtraQuestionTypeRepository.php b/app/Repositories/Summit/DoctrineSummitOrderExtraQuestionTypeRepository.php index ed0f9f12..d0b26831 100644 --- a/app/Repositories/Summit/DoctrineSummitOrderExtraQuestionTypeRepository.php +++ b/app/Repositories/Summit/DoctrineSummitOrderExtraQuestionTypeRepository.php @@ -12,11 +12,7 @@ * limitations under the License. **/ use App\Models\Foundation\Summit\Repositories\ISummitOrderExtraQuestionTypeRepository; -use App\Repositories\SilverStripeDoctrineRepository; -use Illuminate\Support\Facades\Log; -use models\summit\Summit; -use models\summit\SummitOrder; -use models\summit\SummitOrderExtraQuestionAnswer; +use App\Repositories\Main\DoctrineExtraQuestionTypeRepository; use models\summit\SummitOrderExtraQuestionType; use utils\DoctrineLeftJoinFilterMapping; /** @@ -24,7 +20,7 @@ use utils\DoctrineLeftJoinFilterMapping; * @package App\Repositories\Summit */ final class DoctrineSummitOrderExtraQuestionTypeRepository - extends SilverStripeDoctrineRepository + extends DoctrineExtraQuestionTypeRepository implements ISummitOrderExtraQuestionTypeRepository { @@ -33,13 +29,11 @@ final class DoctrineSummitOrderExtraQuestionTypeRepository */ protected function getFilterMappings() { - return [ - 'name' => 'e.name:json_string', - 'type' => 'e.type:json_string', - 'usage;' => 'e.$usage;:json_string', - 'label' => 'e.label:json_string', + return array_merge(parent::getFilterMappings() , [ + 'printable' => 'e.printable;:json_boolean', + 'usage' => 'e.usage;:json_string', 'summit_id' => new DoctrineLeftJoinFilterMapping("e.summit", "s" ,"s.id :operator :value") - ]; + ]); } /** @@ -47,12 +41,7 @@ final class DoctrineSummitOrderExtraQuestionTypeRepository */ protected function getOrderMappings() { - return [ - 'id' => 'e.id', - 'name' => 'e.name', - 'label' => 'e.label', - 'order' => 'e.order', - ]; + return parent::getOrderMappings(); } /** @@ -63,75 +52,4 @@ final class DoctrineSummitOrderExtraQuestionTypeRepository { return SummitOrderExtraQuestionType::class; } - - /** - * @param Summit $summit - * @return array - */ - public function getQuestionsMetadata(Summit $summit) - { - return [ - [ - 'type' => 'TextArea', - ], - [ - 'type' => 'Text', - ], - [ - 'type' => 'CheckBox', - ], - [ - 'type' => 'ComboBox', - 'values' => 'array', - ], - [ - 'type' => 'CheckBoxList', - 'values' => 'array', - ], - [ - 'type' => 'RadioButtonList', - 'values' => 'array', - ], - - ]; - } - - /** - * @param SummitOrderExtraQuestionType $questionType - * @return bool - */ - public function hasAnswers(SummitOrderExtraQuestionType $questionType): bool - { - try { - $query = $this->getEntityManager() - ->createQueryBuilder() - ->select("count(e.id)") - ->from(SummitOrderExtraQuestionAnswer::class, "e")->join("e.question", "q") - ->where("q = :question")->setParameter("question", $questionType); - - return $query->getQuery()->getSingleScalarResult() > 0; - } - catch (\Exception $ex){ - Log::error($ex); - return false; - } - } - - /** - * @param SummitOrderExtraQuestionType $questionType - */ - public function deleteAnswersFrom(SummitOrderExtraQuestionType $questionType):void{ - try { - $query = $this->getEntityManager() - ->createQueryBuilder() - ->delete(SummitOrderExtraQuestionAnswer::class, "e") - ->where("e.question = :question") - ->setParameter("question", $questionType); - - $query->getQuery()->execute(); - } - catch (\Exception $ex){ - Log::error($ex); - } - } } \ No newline at end of file diff --git a/app/Repositories/Summit/DoctrineSummitSelectionPlanExtraQuestionTypeRepository.php b/app/Repositories/Summit/DoctrineSummitSelectionPlanExtraQuestionTypeRepository.php new file mode 100644 index 00000000..02214b53 --- /dev/null +++ b/app/Repositories/Summit/DoctrineSummitSelectionPlanExtraQuestionTypeRepository.php @@ -0,0 +1,59 @@ + new DoctrineLeftJoinFilterMapping + ( + "e.selection_plan", + "s" , + "s.id :operator :value" + ) + ]); + } + + /** + * @return array + */ + protected function getOrderMappings() + { + return parent::getOrderMappings(); + } + + /** + * + * @return string + */ + protected function getBaseEntity() + { + return SummitSelectionPlanExtraQuestionType::class; + } +} \ No newline at end of file diff --git a/app/Services/Model/IExtraQuestionTypeService.php b/app/Services/Model/IExtraQuestionTypeService.php new file mode 100644 index 00000000..63231c01 --- /dev/null +++ b/app/Services/Model/IExtraQuestionTypeService.php @@ -0,0 +1,23 @@ +tx_service->transaction(function () use ($question, $payload) { + + $name = trim($payload['value']); + $former_value = $question->getValueByName($name); + if(!is_null($former_value)) + throw new ValidationException("Value already exists."); + + if(isset($payload['label'])) { + $label = trim($payload['label']); + $former_value = $question->getValueByLabel($label); + if (!is_null($former_value)) + throw new ValidationException("Value already exists."); + } + + $value = ExtraQuestionTypeValueFactory::build($payload); + + $question->addValue($value); + + return $value; + + }); + } + + + /** + * @param ExtraQuestionType $question + * @param int $value_id + * @param array $payload + * @return ExtraQuestionTypeValue + * @throws \Exception + */ + protected function _updateOrderExtraQuestionValue(ExtraQuestionType $question, int $value_id, array $payload): ExtraQuestionTypeValue + { + return $this->tx_service->transaction(function () use ($question, $value_id, $payload) { + + $value = $question->getValueById($value_id); + if(is_null($value)) + throw new EntityNotFoundException("Value not found."); + + if(isset($payload['value'])) { + $name = trim($payload['value']); + $former_value = $question->getValueByName($name); + if (!is_null($former_value) && $former_value->getId() != $value_id) + throw new ValidationException("value already exists."); + } + + if(isset($payload['label'])) { + $label = trim($payload['label']); + $former_value = $question->getValueByLabel($label); + if (!is_null($former_value) && $former_value->getId() != $value_id) + throw new ValidationException("value already exists."); + } + + + if (isset($payload['order']) && intval($payload['order']) != $value->getOrder()) { + // request to update order + $question->recalculateValueOrder($value, intval($payload['order']) ); + } + + return ExtraQuestionTypeValueFactory::populate($value, $payload); + }); + } + + + /** + * @param ExtraQuestionType $question + * @param int $value_id + * @throws \Exception + */ + protected function _deleteOrderExtraQuestionValue(ExtraQuestionType $question, int $value_id): void + { + $this->tx_service->transaction(function () use ($question, $value_id) { + + $value = $question->getValueById($value_id); + + if(is_null($value)) + throw new EntityNotFoundException("value not found"); + + // check if question has answers + + if($this->repository->hasAnswers($question)){ + throw new ValidationException(sprintf("You can not delete question value %s bc already has answers from attendees.", $value_id)); + } + + $question->removeValue($value); + }); + } +} \ No newline at end of file diff --git a/app/Services/Model/Imp/PresentationService.php b/app/Services/Model/Imp/PresentationService.php index 67190828..db6224f3 100644 --- a/app/Services/Model/Imp/PresentationService.php +++ b/app/Services/Model/Imp/PresentationService.php @@ -19,6 +19,7 @@ use App\Http\Utils\FileUploadInfo; use App\Http\Utils\IFileUploader; use App\Jobs\Emails\PresentationSubmissions\PresentationCreatorNotificationEmail; use App\Jobs\Emails\PresentationSubmissions\PresentationSpeakerNotificationEmail; +use App\Models\Foundation\Summit\ExtraQuestions\SummitSelectionPlanExtraQuestionType; use App\Models\Foundation\Summit\Factories\PresentationLinkFactory; use App\Models\Foundation\Summit\Factories\PresentationMediaUploadFactory; use App\Models\Foundation\Summit\Factories\PresentationSlideFactory; @@ -41,6 +42,7 @@ use models\main\Member; use models\summit\ISpeakerRepository; use models\summit\ISummitEventRepository; use models\summit\Presentation; +use models\summit\PresentationExtraQuestionAnswer; use models\summit\PresentationLink; use models\summit\PresentationMediaUpload; use models\summit\PresentationSlide; @@ -51,6 +53,7 @@ use libs\utils\ITransactionService; use models\summit\Summit; use Illuminate\Http\Request as LaravelRequest; use App\Services\Model\IFolderService; +use models\summit\SummitOrderExtraQuestionTypeConstants; use Symfony\Component\HttpFoundation\File\UploadedFile; /** @@ -526,39 +529,40 @@ final class PresentationService } } + $extra_questions = $payload['extra_questions'] ?? []; // extra questions values - if (isset($data['extra_questions'])) { - foreach ($data['extra_questions'] as $extra_question) { - if (!isset($extra_question['id'])) continue; - if (!isset($extra_question['value'])) continue; + $mandatory_questions = $selection_plan->getMandatoryExtraQuestions(); + if (count($extra_questions) < $mandatory_questions->count()) { + throw new ValidationException("You neglected to fill in all mandatory questions for the presentation."); + } + if (count($extra_questions)) { - $extra_question_id = $extra_question['id']; - $extra_question_value = $extra_question['value']; + $questions = $selection_plan->getExtraQuestions(); + if ($questions->count() > 0) { + $presentation->clearExtraQuestionAnswers(); + foreach ($questions as $question) { + if (!$question instanceof SummitSelectionPlanExtraQuestionType) continue; + foreach ($extra_questions as $question_answer) { + if (intval($question_answer['question_id']) == $question->getId()) { + $value = trim($question_answer['answer']); - $track_question = $track->getExtraQuestionById($extra_question_id); - if (is_null($track_question)) { - throw new EntityNotFoundException( - trans( - 'not_found_errors.PresentationService.saveOrUpdatePresentation.trackQuestionNotFound', - ['question_id' => $extra_question_id] - ) - ); + if (empty($value) && $question->isMandatory()) + throw new ValidationException(sprintf('Question "%s" is mandatory', $question->getLabel())); + + if ($question->allowsValues() && !$question->allowValue($value)) { + Log::warning(sprintf("value %s is not allowed for question %s", $value, $question->getName())); + throw new ValidationException("The answer you provided is invalid"); + } + + $answer = new PresentationExtraQuestionAnswer(); + $answer->setQuestion($question); + $answer->setValue($value); + $presentation->addExtraQuestionAnswer($answer); + break; + } + } } - $answer = $presentation->getTrackExtraQuestionAnswer($track_question); - - if (is_null($answer)) { - $answer = new TrackAnswer(); - $presentation->addAnswer($answer); - $track_question->addAnswer($answer); - } - - if (is_array($extra_question_value)) { - $extra_question_value = str_replace('{comma}', ',', $extra_question_value); - $extra_question_value = implode(',', $extra_question_value); - } - - $answer->setValue($extra_question_value); } } return $presentation; diff --git a/app/Services/Model/Imp/SelectionPlanOrderExtraQuestionTypeService.php b/app/Services/Model/Imp/SelectionPlanOrderExtraQuestionTypeService.php new file mode 100644 index 00000000..91db2747 --- /dev/null +++ b/app/Services/Model/Imp/SelectionPlanOrderExtraQuestionTypeService.php @@ -0,0 +1,171 @@ +repository = $repository; + } + + /** + * @inheritDoc + */ + public function addExtraQuestion(SelectionPlan $selectionPlan, array $payload): SummitSelectionPlanExtraQuestionType + { + return $this->tx_service->transaction(function () use ($selectionPlan, $payload) { + $name = trim($payload['name']); + $former_question = $selectionPlan->getExtraQuestionByName($name); + if (!is_null($former_question)) + throw new ValidationException("Question Name already exists for Selection Plan."); + + $label = trim($payload['label']); + $former_question = $selectionPlan->getExtraQuestionByName($label); + if (!is_null($former_question)) + throw new ValidationException("Question Label already exists for Selection Plan."); + + $question = SummitSelectionPlanExtraQuestionTypeFactory::build($payload); + + $selectionPlan->addExtraQuestion($question); + + return $question; + }); + } + + /** + * @inheritDoc + */ + public function updateExtraQuestion(SelectionPlan $selectionPlan, int $question_id, array $payload): SummitSelectionPlanExtraQuestionType + { + return $this->tx_service->transaction(function () use ($selectionPlan, $question_id, $payload) { + + $question = $selectionPlan->getOrderExtraQuestionById($question_id); + if (is_null($question)) + throw new EntityNotFoundException("question not found"); + + if (isset($payload['name'])) { + $name = trim($payload['name']); + $former_question = $selectionPlan->getExtraQuestionByName($name); + if (!is_null($former_question) && $former_question->getId() != $question_id) + throw new ValidationException("Question Name already exists for Selection Plan."); + } + + if (isset($payload['label'])) { + $label = trim($payload['label']); + $former_question = $selectionPlan->getExtraQuestionByLabel($label); + if (!is_null($former_question) && $former_question->getId() != $question_id) + throw new ValidationException("Question Label already exists for Selection Plan."); + } + + if (isset($payload['order']) && intval($payload['order']) != $question->getOrder()) { + // request to update order + $selectionPlan->recalculateQuestionOrder($question, intval($payload['order'])); + } + + return SummitSelectionPlanExtraQuestionTypeFactory::populate($question, $payload); + }); + } + + /** + * @inheritDoc + */ + public function deleteExtraQuestion(SelectionPlan $selectionPlan, int $question_id): void + { + $this->tx_service->transaction(function () use ($selectionPlan, $question_id) { + + $question = $selectionPlan->getOrderExtraQuestionById($question_id); + if (is_null($question)) + throw new EntityNotFoundException("Question not found."); + + // check if question has answers + + if ($this->repository->hasAnswers($question)) { + //throw new ValidationException(sprintf("you can not delete question %s bc already has answers from attendees", $question_id)); + $this->repository->deleteAnswersFrom($question); + } + + $selectionPlan->removeExtraQuestion($question); + }); + } + + /** + * @inheritDoc + */ + public function addExtraQuestionValue(SelectionPlan $selectionPlan, int $question_id, array $payload): ExtraQuestionTypeValue + { + return $this->tx_service->transaction(function () use ($selectionPlan, $question_id, $payload) { + + $question = $selectionPlan->getExtraQuestionById($question_id); + if (is_null($question)) + throw new EntityNotFoundException("Question not found."); + + return parent::_addOrderExtraQuestionValue($question, $payload); + }); + } + + /** + * @inheritDoc + */ + public function updateExtraQuestionValue(SelectionPlan $selectionPlan, int $question_id, int $value_id, array $payload): ExtraQuestionTypeValue + { + return $this->tx_service->transaction(function () use ($selectionPlan, $question_id, $value_id, $payload) { + $question = $selectionPlan->getExtraQuestionById($question_id); + if (is_null($question)) + throw new EntityNotFoundException("Question not found."); + + return parent::_updateOrderExtraQuestionValue($question, $value_id, $payload); + }); + } + + /** + * @inheritDoc + */ + public function deleteExtraQuestionValue(SelectionPlan $selectionPlan, int $question_id, int $value_id): void + { + $this->tx_service->transaction(function () use ($selectionPlan, $question_id, $value_id) { + $question = $selectionPlan->getExtraQuestionById($question_id); + if (is_null($question)) + throw new EntityNotFoundException("Question not found."); + + parent::_deleteOrderExtraQuestionValue($question, $value_id); + }); + } +} \ No newline at end of file diff --git a/app/Services/Model/Imp/SummitOrderExtraQuestionTypeService.php b/app/Services/Model/Imp/SummitOrderExtraQuestionTypeService.php index b982a4ee..d70f6b97 100644 --- a/app/Services/Model/Imp/SummitOrderExtraQuestionTypeService.php +++ b/app/Services/Model/Imp/SummitOrderExtraQuestionTypeService.php @@ -11,31 +11,25 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +use App\Models\Foundation\ExtraQuestions\ExtraQuestionTypeValue; use App\Models\Foundation\Summit\Factories\SummitOrderExtraQuestionTypeFactory; -use App\Models\Foundation\Summit\Factories\SummitOrderExtraQuestionValueFactory; use App\Models\Foundation\Summit\Repositories\ISummitOrderExtraQuestionTypeRepository; -use App\Services\Model\AbstractService; +use App\Services\Model\Imp\ExtraQuestionTypeService; use App\Services\Model\ISummitOrderExtraQuestionTypeService; use libs\utils\ITransactionService; use models\exceptions\EntityNotFoundException; use models\exceptions\ValidationException; use models\summit\Summit; use models\summit\SummitOrderExtraQuestionType; -use models\summit\SummitOrderExtraQuestionValue; /** * Class SummitOrderExtraQuestionTypeService * @package App\Services */ final class SummitOrderExtraQuestionTypeService - extends AbstractService + extends ExtraQuestionTypeService implements ISummitOrderExtraQuestionTypeService { - /** - * @var ISummitOrderExtraQuestionTypeRepository - */ - private $repository; - /** * SummitOrderExtraQuestionTypeService constructor. * @param ISummitOrderExtraQuestionTypeRepository $repository @@ -63,13 +57,13 @@ final class SummitOrderExtraQuestionTypeService return $this->tx_service->transaction(function () use ($summit, $payload) { $name = trim($payload['name']); $former_question = $summit->getOrderExtraQuestionByName($name); - if(!is_null($former_question)) - throw new ValidationException("question name already exists for summit"); + if (!is_null($former_question)) + throw new ValidationException("Question Name already exists for Summit."); $label = trim($payload['label']); $former_question = $summit->getOrderExtraQuestionByLabel($label); - if(!is_null($former_question)) - throw new ValidationException("question label already exists for summit"); + if (!is_null($former_question)) + throw new ValidationException("Question Label already exists for Summit."); $question = SummitOrderExtraQuestionTypeFactory::build($payload); @@ -92,26 +86,26 @@ final class SummitOrderExtraQuestionTypeService return $this->tx_service->transaction(function () use ($summit, $question_id, $payload) { $question = $summit->getOrderExtraQuestionById($question_id); - if(is_null($question)) - throw new EntityNotFoundException("question not found"); + if (is_null($question)) + throw new EntityNotFoundException("Question not Found."); - if(isset($payload['name'])) { + if (isset($payload['name'])) { $name = trim($payload['name']); $former_question = $summit->getOrderExtraQuestionByName($name); if (!is_null($former_question) && $former_question->getId() != $question_id) - throw new ValidationException("question name already exists for summit"); + throw new ValidationException("Question Name already exists for Summit."); } - if(isset($payload['label'])) { + if (isset($payload['label'])) { $label = trim($payload['label']); $former_question = $summit->getOrderExtraQuestionByLabel($label); if (!is_null($former_question) && $former_question->getId() != $question_id) - throw new ValidationException("question label already exists for summit"); + throw new ValidationException("Question Label already exists for Summit."); } if (isset($payload['order']) && intval($payload['order']) != $question->getOrder()) { // request to update order - $summit->recalculateQuestionOrder($question, intval($payload['order']) ); + $summit->recalculateQuestionOrder($question, intval($payload['order'])); } return SummitOrderExtraQuestionTypeFactory::populate($question, $payload); @@ -129,12 +123,12 @@ final class SummitOrderExtraQuestionTypeService $this->tx_service->transaction(function () use ($summit, $question_id) { $question = $summit->getOrderExtraQuestionById($question_id); - if(is_null($question)) - throw new EntityNotFoundException("question not found"); + if (is_null($question)) + throw new EntityNotFoundException("Question not found."); // check if question has answers - if($this->repository->hasAnswers($question)){ + if ($this->repository->hasAnswers($question)) { //throw new ValidationException(sprintf("you can not delete question %s bc already has answers from attendees", $question_id)); $this->repository->deleteAnswersFrom($question); } @@ -147,35 +141,19 @@ final class SummitOrderExtraQuestionTypeService * @param Summit $summit * @param int $question_id * @param array $payload - * @return SummitOrderExtraQuestionValue + * @return ExtraQuestionTypeValue * @throws ValidationException * @throws EntityNotFoundException */ - public function addOrderExtraQuestionValue(Summit $summit, int $question_id, array $payload): SummitOrderExtraQuestionValue + public function addOrderExtraQuestionValue(Summit $summit, int $question_id, array $payload): ExtraQuestionTypeValue { return $this->tx_service->transaction(function () use ($summit, $question_id, $payload) { + $question = $summit->getOrderExtraQuestionById($question_id); - if(is_null($question)) - throw new EntityNotFoundException("question not found"); - - $name = trim($payload['value']); - $former_value = $question->getValueByName($name); - if(!is_null($former_value)) - throw new ValidationException("value already exists"); - - if(isset($payload['label'])) { - $label = trim($payload['label']); - $former_value = $question->getValueByLabel($label); - if (!is_null($former_value)) - throw new ValidationException("value already exists"); - } - - $value = SummitOrderExtraQuestionValueFactory::build($payload); - - $question->addValue($value); - - return $value; + if (is_null($question)) + throw new EntityNotFoundException("Question not found."); + return parent::_addOrderExtraQuestionValue($question, $payload); }); } @@ -184,42 +162,18 @@ final class SummitOrderExtraQuestionTypeService * @param int $question_id * @param int $value_id * @param array $payload - * @return SummitOrderExtraQuestionValue + * @return ExtraQuestionTypeValue * @throws ValidationException * @throws EntityNotFoundException */ - public function updateOrderExtraQuestionValue(Summit $summit, int $question_id, int $value_id, array $payload): SummitOrderExtraQuestionValue + public function updateOrderExtraQuestionValue(Summit $summit, int $question_id, int $value_id, array $payload): ExtraQuestionTypeValue { return $this->tx_service->transaction(function () use ($summit, $question_id, $value_id, $payload) { $question = $summit->getOrderExtraQuestionById($question_id); - if(is_null($question)) - throw new EntityNotFoundException("question not found"); + if (is_null($question)) + throw new EntityNotFoundException("Question not found."); - $value = $question->getValueById($value_id); - if(is_null($value)) - throw new EntityNotFoundException("value not found"); - - if(isset($payload['value'])) { - $name = trim($payload['value']); - $former_value = $question->getValueByName($name); - if (!is_null($former_value) && $former_value->getId() != $value_id) - throw new ValidationException("value already exists"); - } - - if(isset($payload['label'])) { - $label = trim($payload['label']); - $former_value = $question->getValueByLabel($label); - if (!is_null($former_value) && $former_value->getId() != $value_id) - throw new ValidationException("value already exists"); - } - - - if (isset($payload['order']) && intval($payload['order']) != $value->getOrder()) { - // request to update order - $question->recalculateValueOrder($value, intval($payload['order']) ); - } - - return SummitOrderExtraQuestionValueFactory::populate($value, $payload); + return parent::_updateOrderExtraQuestionValue($question, $value_id, $payload); }); } @@ -234,21 +188,10 @@ final class SummitOrderExtraQuestionTypeService { $this->tx_service->transaction(function () use ($summit, $question_id, $value_id) { $question = $summit->getOrderExtraQuestionById($question_id); - if(is_null($question)) - throw new EntityNotFoundException("question not found"); + if (is_null($question)) + throw new EntityNotFoundException("Question not found."); - $value = $question->getValueById($value_id); - - if(is_null($value)) - throw new EntityNotFoundException("value not found"); - - // check if question has answers - - if($this->repository->hasAnswers($question)){ - throw new ValidationException(sprintf("you can not delete question value %s bc already has answers from attendees", $value_id)); - } - - $question->removeValue($value); + parent::_deleteOrderExtraQuestionValue($question, $value_id); }); } } \ No newline at end of file diff --git a/app/Services/ModelServicesProvider.php b/app/Services/ModelServicesProvider.php index a814b67a..f5adadfd 100644 --- a/app/Services/ModelServicesProvider.php +++ b/app/Services/ModelServicesProvider.php @@ -35,6 +35,7 @@ use App\Services\Model\Imp\CompanyService; use App\Services\Model\Imp\PaymentGatewayProfileService; use App\Services\Model\Imp\PresentationVideoMediaUploadProcessor; use App\Services\Model\Imp\RegistrationIngestionService; +use App\Services\Model\Imp\SelectionPlanOrderExtraQuestionTypeService; use App\Services\Model\Imp\SponsoredProjectService; use App\Services\Model\Imp\SponsorUserInfoGrantService; use App\Services\Model\Imp\SummitAdministratorPermissionGroupService; @@ -55,6 +56,7 @@ use App\Services\Model\IPresentationVideoMediaUploadProcessor; use App\Services\Model\IRegistrationIngestionService; use App\Services\Model\IRSVPTemplateService; use App\Services\Model\IScheduleIngestionService; +use App\Services\Model\ISelectionPlanExtraQuestionTypeService; use App\Services\Model\ISponsoredProjectService; use App\Services\Model\ISponsorshipTypeService; use App\Services\Model\ISponsorUserInfoGrantService; @@ -434,6 +436,11 @@ final class ModelServicesProvider extends ServiceProvider ISummitPresentationActionService::class, SummitPresentationActionService::class ); + + App::singleton( + ISelectionPlanExtraQuestionTypeService::class, + SelectionPlanOrderExtraQuestionTypeService::class + ); } /** @@ -498,6 +505,7 @@ final class ModelServicesProvider extends ServiceProvider ITrackChairService::class, ISummitPresentationActionTypeService::class, ISummitPresentationActionService::class, + ISelectionPlanExtraQuestionTypeService::class, ]; } } \ No newline at end of file diff --git a/database/migrations/model/Version20210521135639.php b/database/migrations/model/Version20210521135639.php new file mode 100644 index 00000000..ed919fcc --- /dev/null +++ b/database/migrations/model/Version20210521135639.php @@ -0,0 +1,134 @@ +hasTable("ExtraQuestionType")) { + $builder->create('ExtraQuestionType', function (Table $table) { + + $table->integer("ID", true, false); + $table->primary("ID"); + + $table->timestamp('Created'); + $table->timestamp('LastEdited'); + $table->string('ClassName')->setNotnull(true); + + $table->string('Name')->setNotnull(true); + $table->string('Type')->setNotnull(true); + $table->string('Label')->setNotnull(true); + $table->integer('Order')->setNotnull(true)->setDefault(1); + $table->boolean('Mandatory')->setNotnull(true)->setDefault(false); + $table->string('Placeholder')->setNotnull(false)->setDefault(''); + }); + } + + if(!$schema->hasTable("SummitSelectionPlanExtraQuestionType")) { + $builder->create('SummitSelectionPlanExtraQuestionType', function (Table $table) { + + $table->integer("ID", true, false); + $table->primary("ID"); + + // FK + + $table->integer("SelectionPlanID", false, false)->setNotnull(false)->setDefault('NULL'); + $table->index("SelectionPlanID", "SelectionPlanID"); + $table->foreign("SelectionPlan", "SelectionPlanID", "ID", ["onDelete" => "CASCADE"]); + + }); + } + + + if(!$schema->hasTable("ExtraQuestionTypeValue")) { + $builder->create('ExtraQuestionTypeValue', function (Table $table) { + + $table->integer("ID", true, false); + $table->primary("ID"); + + $table->timestamp('Created'); + $table->timestamp('LastEdited'); + $table->string('ClassName')->setNotnull(true); + + $table->string('Label')->setNotnull(true); + $table->string('Value')->setNotnull(true); + $table->integer('Order')->setNotnull(true)->setDefault(1); + + // FK + + $table->integer("QuestionID", false, false)->setNotnull(false)->setDefault('NULL'); + $table->index("QuestionID", "QuestionID"); + $table->foreign("ExtraQuestionType", "QuestionID", "ID", ["onDelete" => "CASCADE"]); + + }); + } + + if(!$schema->hasTable("ExtraQuestionAnswer")) { + $builder->create('ExtraQuestionAnswer', function (Table $table) { + + $table->integer("ID", true, false); + $table->primary("ID"); + + $table->timestamp('Created'); + $table->timestamp('LastEdited'); + $table->string('ClassName')->setNotnull(true); + + $table->string('Value')->setNotnull(true); + + // FK + + $table->integer("QuestionID", false, false)->setNotnull(false)->setDefault('NULL'); + $table->index("QuestionID", "QuestionID"); + $table->foreign("ExtraQuestionType", "QuestionID", "ID", ["onDelete" => "CASCADE"]); + + }); + } + + if(!$schema->hasTable("PresentationExtraQuestionAnswer")) { + $builder->create('PresentationExtraQuestionAnswer', function (Table $table) { + + $table->integer("ID", true, false); + $table->primary("ID"); + + // FK + + $table->integer("PresentationID", false, false)->setNotnull(false)->setDefault('NULL'); + $table->index("PresentationID", "PresentationID"); + $table->foreign("Presentation", "PresentationID", "ID", ["onDelete" => "CASCADE"]); + + }); + } + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema):void + { + + } +} diff --git a/database/migrations/model/Version20210521135642.php b/database/migrations/model/Version20210521135642.php new file mode 100644 index 00000000..ca1aa588 --- /dev/null +++ b/database/migrations/model/Version20210521135642.php @@ -0,0 +1,56 @@ +addSql($sql); + + $sql = <<addSql($sql); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema):void + { + + } +} diff --git a/database/migrations/model/Version20210521170713.php b/database/migrations/model/Version20210521170713.php new file mode 100644 index 00000000..eb72e10c --- /dev/null +++ b/database/migrations/model/Version20210521170713.php @@ -0,0 +1,182 @@ +addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + $sql = <<addSql($sql); + + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema):void + { + + } + +} diff --git a/database/seeds/ApiEndpointsSeeder.php b/database/seeds/ApiEndpointsSeeder.php index 932aa489..e6a82fee 100644 --- a/database/seeds/ApiEndpointsSeeder.php +++ b/database/seeds/ApiEndpointsSeeder.php @@ -5178,6 +5178,113 @@ class ApiEndpointsSeeder extends Seeder IGroup::SummitAdministrators, ] ], + // selection plans extra questions + [ + 'name' => 'get-selection-plan-extra-questions', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions', + 'http_method' => 'GET', + 'scopes' => [ + sprintf(SummitScopes::ReadAllSummitData, $current_realm), + sprintf(SummitScopes::ReadSummitData, $current_realm) + ], + ], + [ + 'name' => 'get-selection-plan-extra-questions-metadata', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/metadata', + 'http_method' => 'GET', + 'scopes' => [ + sprintf(SummitScopes::ReadAllSummitData, $current_realm), + sprintf(SummitScopes::ReadSummitData, $current_realm) + ], + ], + [ + 'name' => 'add-selection-plan-extra-question', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions', + 'http_method' => 'POST', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm) + ], + 'authz_groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + [ + 'name' => 'get-selection-plan-extra-question', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}', + 'http_method' => 'GET', + 'scopes' => [ + sprintf(SummitScopes::ReadAllSummitData, $current_realm), + sprintf(SummitScopes::ReadSummitData, $current_realm) + ], + ], + [ + 'name' => 'update-selection-plan-extra-question', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}', + 'http_method' => 'PUT', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm) + ], + 'authz_groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + [ + 'name' => 'delete-selection-plan-extra-question', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}', + 'http_method' => 'DELETE', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm) + ], + 'authz_groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + [ + 'name' => 'add-selection-plan-extra-question_value', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}/values', + 'http_method' => 'POST', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm) + ], + 'authz_groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + [ + 'name' => 'update-selection-plan-extra-question_value', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}/values/{value_id}', + 'http_method' => 'PUT', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm) + ], + 'authz_groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + [ + 'name' => 'delete-selection-plan-extra-question_value', + 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}/values/{value_id}', + 'http_method' => 'DELETE', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm) + ], + 'authz_groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + // selection plan presentations [ 'name' => 'get-selection-plan-presentations', 'route' => '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations', diff --git a/database/seeds/TestSeeder.php b/database/seeds/TestSeeder.php index 7bfd82f0..d4344b1c 100644 --- a/database/seeds/TestSeeder.php +++ b/database/seeds/TestSeeder.php @@ -22,13 +22,6 @@ final class TestSeeder extends Seeder public function run() { Model::unguard(); - DB::setDefaultConnection("model"); - DB::table('Summit')->delete(); - DB::table('SummitEventType')->delete(); - DB::table('PresentationType')->delete(); - DB::table('SummitAbstractLocation')->delete(); - DB::table('SummitGeoLocatedLocation')->delete(); - DB::table('SummitVenue')->delete(); DB::setDefaultConnection("config"); $this->call('ApiSeeder'); $this->call('ApiScopesSeeder'); diff --git a/tests/BrowserKitTestCase.php b/tests/BrowserKitTestCase.php index 9240b3e1..31f11fe5 100644 --- a/tests/BrowserKitTestCase.php +++ b/tests/BrowserKitTestCase.php @@ -14,6 +14,8 @@ use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Redis; use Laravel\BrowserKitTesting\TestCase as BaseTestCase; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\DB; /** * Class TestCase * @package Tests @@ -46,6 +48,20 @@ abstract class BrowserKitTestCase extends BaseTestCase */ protected function prepareForTests() { + Model::unguard(); + DB::setDefaultConnection("model"); + DB::table('Group_Members')->delete(); + DB::table('Member')->delete(); + DB::table('Group')->delete(); + + DB::table('Summit')->delete(); + DB::table('SummitEventType')->delete(); + DB::table('PresentationType')->delete(); + DB::table('SummitAbstractLocation')->delete(); + DB::table('SummitGeoLocatedLocation')->delete(); + DB::table('SummitVenue')->delete(); + DB::table('PresentationTrackChairView')->delete(); + Artisan::call('doctrine:migrations:migrate', ["--connection" => 'config']); Artisan::call('doctrine:migrations:migrate', ["--connection" => 'model']); //Mail::pretend(true); diff --git a/tests/ExtraQuestionsModelTest.php b/tests/ExtraQuestionsModelTest.php new file mode 100644 index 00000000..abcf587e --- /dev/null +++ b/tests/ExtraQuestionsModelTest.php @@ -0,0 +1,65 @@ +addMember(self::$member); + self::$em->persist(self::$summit); + self::$em->persist(self::$summit_permission_group); + self::$em->flush(); + } + + protected function tearDown() + { + self::clearMemberTestData(); + self::clearTestData(); + parent::tearDown(); + } + + public function testAddSelectionPlanQuestion(){ + + $newQuestion = SummitSelectionPlanExtraQuestionTypeFactory::build([ + 'name' => 'Test Question', + 'label' => 'Test Question', + 'type' => ExtraQuestionTypeConstants::TextQuestionType, + 'placeholder' => 'This is a placeholder', + 'mandatory' => true, + ]); + + self::$default_selection_plan->addExtraQuestion($newQuestion); + self::$em->persist(self::$default_selection_plan); + self::$em->flush(); + + $this->assertFalse($newQuestion->getId() > 0); + } + +} \ No newline at end of file diff --git a/tests/InsertMemberTestData.php b/tests/InsertMemberTestData.php index 0c700533..48960198 100644 --- a/tests/InsertMemberTestData.php +++ b/tests/InsertMemberTestData.php @@ -160,11 +160,16 @@ trait InsertMemberTestData self::$member2 = self::$member_repository->find(self::$member2->getId()); self::$group2 = self::$group_repository->find(self::$group2->getId()); - self::$em->remove(self::$member); - self::$em->remove(self::$group); + if(!is_null(self::$member)) + self::$em->remove(self::$member); + if(!is_null(self::$group)) + self::$em->remove(self::$group); + + if(!is_null(self::$member2)) + self::$em->remove(self::$member2); + if(!is_null(self::$group2)) + self::$em->remove(self::$group2); - self::$em->remove(self::$member2); - self::$em->remove(self::$group2); self::$em->flush(); } } \ No newline at end of file diff --git a/tests/OAuth2SummitOrderExtraQuestionTypeApiTest.php b/tests/OAuth2SummitOrderExtraQuestionTypeApiTest.php index 073b3648..daef1922 100644 --- a/tests/OAuth2SummitOrderExtraQuestionTypeApiTest.php +++ b/tests/OAuth2SummitOrderExtraQuestionTypeApiTest.php @@ -11,21 +11,41 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +use App\Models\Foundation\Main\IGroup; use models\summit\SummitOrderExtraQuestionTypeConstants; /** * Class OAuth2SummitOrderExtraQuestionTypeApiTest */ final class OAuth2SummitOrderExtraQuestionTypeApiTest extends ProtectedApiTest { - /** - * @param int $summit_id - * @param int $company_id - * @return mixed - */ - public function testAddExtraOrderQuestion($summit_id=27){ + + use \InsertSummitTestData; + + use \InsertMemberTestData; + + protected function setUp() + { + parent::setUp(); + self::insertTestData(); + self::insertMemberTestData(IGroup::TrackChairs); + self::$summit_permission_group->addMember(self::$member); + self::$em->persist(self::$summit); + self::$em->persist(self::$summit_permission_group); + self::$em->flush(); + } + + protected function tearDown() + { + self::clearMemberTestData(); + self::clearTestData(); + parent::tearDown(); + } + + + public function testAddExtraOrderQuestion(){ $params = [ - 'id' => $summit_id + 'id' => self::$summit->getId() ]; $name = str_random(16).'_question'; @@ -37,7 +57,6 @@ final class OAuth2SummitOrderExtraQuestionTypeApiTest extends ProtectedApiTest 'usage' => SummitOrderExtraQuestionTypeConstants::BothQuestionUsage, 'mandatory' => true, 'printable' => true, - 'placeholder' => $name, ]; $headers = [ @@ -63,10 +82,45 @@ final class OAuth2SummitOrderExtraQuestionTypeApiTest extends ProtectedApiTest return $question; } - public function testAddQuestionValue($summit_id=27){ - $question = $this->testAddExtraOrderQuestion($summit_id); + public function testAddQuestionValue(){ $params = [ - 'id' => $summit_id, + 'id' => self::$summit->getId() + ]; + + $name = str_random(16).'_question'; + + $data = [ + 'name' => $name, + 'type' => SummitOrderExtraQuestionTypeConstants::ComboBoxQuestionType, + 'label' => $name, + 'usage' => SummitOrderExtraQuestionTypeConstants::BothQuestionUsage, + 'mandatory' => true, + 'printable' => true, + ]; + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $response = $this->action( + "POST", + "OAuth2SummitOrderExtraQuestionTypeApiController@add", + $params, + [], + [], + [], + $headers, + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(201); + $question = json_decode($content); + $this->assertTrue(!is_null($question)); + + $params = [ + 'id' => self::$summit->getId(), 'question_id' => $question->id ]; diff --git a/tests/OAuth2SummitSelectionPlanExtraQuestionTypeApiTest.php b/tests/OAuth2SummitSelectionPlanExtraQuestionTypeApiTest.php new file mode 100644 index 00000000..a3af26f2 --- /dev/null +++ b/tests/OAuth2SummitSelectionPlanExtraQuestionTypeApiTest.php @@ -0,0 +1,204 @@ +addMember(self::$member); + self::$em->persist(self::$summit); + self::$em->persist(self::$summit_permission_group); + self::$em->flush(); + } + + protected function tearDown() + { + self::clearMemberTestData(); + self::clearTestData(); + parent::tearDown(); + } + + public function testAddExtraQuestion(){ + + $params = [ + 'id' => self::$summit->getId(), + 'selection_plan_id' => self::$default_selection_plan->getId(), + ]; + + $name = str_random(16).'_question'; + + $data = [ + 'name' => $name, + 'type' => SummitOrderExtraQuestionTypeConstants::ComboBoxQuestionType, + 'label' => $name, + 'mandatory' => true, + ]; + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $response = $this->action( + "POST", + "OAuth2SummitSelectionPlansApiController@addExtraQuestion", + $params, + [], + [], + [], + $headers, + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(201); + $question = json_decode($content); + $this->assertTrue(!is_null($question)); + return $question; + } + + public function testAddQuestionValue(){ + $params = [ + 'id' => self::$summit->getId(), + 'selection_plan_id' => self::$default_selection_plan->getId(), + ]; + + $name = str_random(16).'_question'; + + $data = [ + 'name' => $name, + 'type' => SummitOrderExtraQuestionTypeConstants::ComboBoxQuestionType, + 'label' => $name, + 'usage' => SummitOrderExtraQuestionTypeConstants::BothQuestionUsage, + 'mandatory' => true, + 'printable' => true, + ]; + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $response = $this->action( + "POST", + "OAuth2SummitSelectionPlansApiController@addExtraQuestion", + $params, + [], + [], + [], + $headers, + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(201); + $question = json_decode($content); + $this->assertTrue(!is_null($question)); + + $params = [ + 'id' => self::$summit->getId(), + 'selection_plan_id' => self::$default_selection_plan->getId(), + 'question_id' => $question->id + ]; + + $name = str_random(16).'_question'; + + $data = [ + 'value' => $name, + 'label' => $name, + ]; + + $response = $this->action( + "POST", + "OAuth2SummitSelectionPlansApiController@addExtraQuestionValue", + $params, + [], + [], + [], + $headers, + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(201); + $value = json_decode($content); + $this->assertTrue(!is_null($value)); + + // get all values + + $params = [ + 'id' => self::$summit->getId(), + 'selection_plan_id' => self::$default_selection_plan->getId(), + 'question_id' => $question->id, + 'expand' => 'values', + ]; + + $response = $this->action( + "GET", + "OAuth2SummitSelectionPlansApiController@getExtraQuestions", + $params, + [], + [], + [], + $headers + ); + + $content = $response->getContent(); + $this->assertResponseStatus(200); + $page = json_decode($content); + $this->assertTrue(!is_null($page)); + $this->assertTrue($page->total == 1); + return $value; + } + + public function testGetMetadata(){ + + $headers = [ + "HTTP_Authorization" => " Bearer " . $this->access_token, + "CONTENT_TYPE" => "application/json" + ]; + + $params = [ + 'id' => self::$summit->getId(), + 'selection_plan_id' => self::$default_selection_plan->getId(), + ]; + + $response = $this->action( + "GET", + "OAuth2SummitSelectionPlansApiController@getExtraQuestionsMetadata", + $params, + [], + [], + [], + $headers + ); + + $content = $response->getContent(); + $this->assertResponseStatus(200); + $metadata = json_decode($content); + $this->assertTrue(!empty($metadata)); + } +} \ No newline at end of file