diff --git a/app/Http/Controllers/apis/protected/main/OAuth2MembersApiController.php b/app/Http/Controllers/apis/protected/main/OAuth2MembersApiController.php index 6dcbcde5..6e29cdbb 100644 --- a/app/Http/Controllers/apis/protected/main/OAuth2MembersApiController.php +++ b/app/Http/Controllers/apis/protected/main/OAuth2MembersApiController.php @@ -81,6 +81,7 @@ final class OAuth2MembersApiController extends OAuth2ProtectedController 'twitter' => ['=@', '=='], 'first_name' => ['=@', '=='], 'last_name' => ['=@', '=='], + 'email' => ['=@', '=='], )); } diff --git a/app/Http/Utils/Filters/Filter.php b/app/Http/Utils/Filters/Filter.php index efd7bd72..50cb4d89 100644 --- a/app/Http/Utils/Filters/Filter.php +++ b/app/Http/Utils/Filters/Filter.php @@ -157,19 +157,36 @@ final class Filter foreach ($this->filters as $filter) { if ($filter instanceof FilterElement && isset($mappings[$filter->getField()])) { $mapping = $mappings[$filter->getField()]; + if ($mapping instanceof DoctrineJoinFilterMapping) { $query = $mapping->apply($query, $filter); continue; } + else if(is_array($mapping)){ + $condition = ''; + foreach ($mapping as $mapping_or){ + $mapping_or = explode(':', $mapping_or); + $value = $filter->getValue(); + if (count($mapping_or) > 1) { + $value = $this->convertValue($value, $mapping_or[1]); + } - $mapping = explode(':', $mapping); - $value = $filter->getValue(); + if(!empty($condition)) $condition .= ' OR '; + $condition .= sprintf("%s %s %s", $mapping_or[0], $filter->getOperator(), $value); + } - if (count($mapping) > 1) { - $value = $this->convertValue($value, $mapping[1]); + $query->andWhere($condition); } + else { + $mapping = explode(':', $mapping); + $value = $filter->getValue(); - $query = $query->andWhere(sprintf("%s %s %s",$mapping[0], $filter->getOperator(), $value)); + if (count($mapping) > 1) { + $value = $this->convertValue($value, $mapping[1]); + } + + $query = $query->andWhere(sprintf("%s %s %s", $mapping[0], $filter->getOperator(), $value)); + } } else if (is_array($filter)) { // OR diff --git a/app/ModelSerializers/AffiliationSerializer.php b/app/ModelSerializers/AffiliationSerializer.php new file mode 100644 index 00000000..ff888e76 --- /dev/null +++ b/app/ModelSerializers/AffiliationSerializer.php @@ -0,0 +1,53 @@ + 'start_date:datetime_epoch', + 'EndDate' => 'end_date:datetime_epoch', + 'OwnerId' => 'owner_id:json_int', + 'IsCurrent' => 'is_current:json_boolean', + 'OrganizationId' => 'organization_id:json_int' + ]; + + public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array()) + { + $affiliation = $this->object; + if (!$affiliation instanceof Affiliation) return []; + $values = parent::serialize($expand, $fields, $relations, $params); + if (!empty($expand)) { + $exp_expand = explode(',', $expand); + foreach ($exp_expand as $relation) { + switch (trim($relation)) { + case 'organization': + { + unset($values['organization_id']); + $values['organization'] = SerializerRegistry::getInstance()->getSerializer($affiliation->getOrganization())->serialize($expand,[],['none']); + } + break; + } + } + } + return $values; + } +} \ No newline at end of file diff --git a/app/ModelSerializers/MemberSerializer.php b/app/ModelSerializers/MemberSerializer.php index 25513be2..ca50df77 100644 --- a/app/ModelSerializers/MemberSerializer.php +++ b/app/ModelSerializers/MemberSerializer.php @@ -36,7 +36,8 @@ final class MemberSerializer extends SilverStripeSerializer 'groups', 'groups_events', - 'feedback' + 'feedback', + 'affiliations', ]; private static $expand_group_events = [ @@ -89,6 +90,16 @@ final class MemberSerializer extends SilverStripeSerializer $values['groups_events'] = $res; } + if(in_array('affiliations', $relations)){ + $res = []; + foreach ($member->getAffiliations() as $affiliation){ + $res[] = SerializerRegistry::getInstance() + ->getSerializer($affiliation) + ->serialize('organization'); + } + $values['affiliations'] = $res; + } + if (!empty($expand)) { $exp_expand = explode(',', $expand); foreach ($exp_expand as $relation) { @@ -112,6 +123,7 @@ final class MemberSerializer extends SilverStripeSerializer break; case 'feedback': { if(!in_array('feedback', $relations)) break; + if(is_null($summit)) break; $feedback = array(); foreach ($member->getFeedbackBySummit($summit) as $f) { $feedback[] = SerializerRegistry::getInstance()->getSerializer($f)->serialize(); diff --git a/app/ModelSerializers/OrganizationSerializer.php b/app/ModelSerializers/OrganizationSerializer.php new file mode 100644 index 00000000..13df3c15 --- /dev/null +++ b/app/ModelSerializers/OrganizationSerializer.php @@ -0,0 +1,24 @@ + 'name:json_string', + ]; +} \ No newline at end of file diff --git a/app/ModelSerializers/SerializerRegistry.php b/app/ModelSerializers/SerializerRegistry.php index 2196ae7f..1efb993d 100644 --- a/app/ModelSerializers/SerializerRegistry.php +++ b/app/ModelSerializers/SerializerRegistry.php @@ -88,8 +88,9 @@ final class SerializerRegistry // member $this->registry['Member'] = MemberSerializer::class; - $this->registry['Group'] = GroupSerializer::class; + $this->registry['Affiliation'] = AffiliationSerializer::class; + $this->registry['Organization'] = OrganizationSerializer::class; // push notification $this->registry['SummitPushNotification'] = SummitPushNotificationSerializer::class; diff --git a/app/Models/Foundation/Main/Affiliation.php b/app/Models/Foundation/Main/Affiliation.php new file mode 100644 index 00000000..8ae0f674 --- /dev/null +++ b/app/Models/Foundation/Main/Affiliation.php @@ -0,0 +1,167 @@ +start_date; + } + + /** + * @param \DateTime $start_date + */ + public function setStartDate($start_date) + { + $this->start_date = $start_date; + } + + /** + * @return \DateTime + */ + public function getEndDate() + { + return $this->end_date; + } + + /** + * @param \DateTime $end_date + */ + public function setEndDate($end_date) + { + $this->end_date = $end_date; + } + + /** + * @return bool + */ + public function isCurrent() + { + return $this->is_current; + } + + public function getIsCurrent(){ + return $this->isCurrent(); + } + + /** + * @param bool $is_current + */ + public function setIsCurrent($is_current) + { + $this->is_current = $is_current; + } + + /** + * @return Organization + */ + public function getOrganization() + { + return $this->organization; + } + + /** + * @param Organization $organization + */ + public function setOrganization($organization) + { + $this->organization = $organization; + } + + /** + * @ORM\Column(name="EndDate", type="datetime") + * @var \DateTime + */ + private $end_date; + + /** + * @ORM\Column(name="Current", type="boolean") + * @var bool + */ + private $is_current; + + /** + * @ORM\ManyToOne(targetEntity="models\main\Member") + * @ORM\JoinColumn(name="MemberID", referencedColumnName="ID") + * @var Member + */ + protected $owner; + + /** + * @ORM\ManyToOne(targetEntity="models\main\Organization") + * @ORM\JoinColumn(name="OrganizationID", referencedColumnName="ID") + * @var Organization + */ + protected $organization; + + + /** + * @return Member + */ + public function getOwner() + { + return $this->owner; + } + + /** + * @param Member $owner + */ + public function setOwner($owner) + { + $this->owner = $owner; + } + + /** + * @return int + */ + public function getOwnerId(){ + try { + return $this->owner->getId(); + } + catch(\Exception $ex){ + return 0; + } + } + + /** + * @return int + */ + public function getOrganizationId(){ + try { + return $this->organization->getId(); + } + catch(\Exception $ex){ + return 0; + } + } + +} \ No newline at end of file diff --git a/app/Models/Foundation/Main/Member.php b/app/Models/Foundation/Main/Member.php index df2ea3f9..cf33dd98 100644 --- a/app/Models/Foundation/Main/Member.php +++ b/app/Models/Foundation/Main/Member.php @@ -13,12 +13,11 @@ **/ use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\Common\Collections\Criteria; +use Doctrine\ORM\Mapping as ORM; use models\summit\Summit; use models\summit\SummitEvent; use models\summit\SummitEventFeedback; use models\utils\SilverstripeBaseModel; -use Doctrine\ORM\Mapping AS ORM; /** * @ORM\Entity @@ -29,6 +28,20 @@ use Doctrine\ORM\Mapping AS ORM; */ class Member extends SilverstripeBaseModel { + public function __construct(){ + parent::__construct(); + $this->feedback = new ArrayCollection(); + $this->groups = new ArrayCollection(); + $this->affiliations = new ArrayCollection(); + } + + /** + * @return Affiliation[] + */ + public function getAffiliations(){ + return $this->affiliations; + } + /** * @return Group[] */ @@ -45,12 +58,6 @@ class Member extends SilverstripeBaseModel $this->groups = $groups; } - public function __construct(){ - parent::__construct(); - $this->feedback = new ArrayCollection(); - $this->groups = new ArrayCollection(); - } - /** * @ORM\ManyToMany(targetEntity="models\main\Group", inversedBy="members") * @ORM\JoinTable(name="Group_Members", @@ -111,6 +118,106 @@ class Member extends SilverstripeBaseModel */ private $bio; + /** + * @ORM\Column(name="Email", type="string") + * @var string + */ + private $email; + + /** + * @ORM\Column(name="SecondEmail", type="string") + * @var string + */ + private $second_email; + + /** + * @ORM\Column(name="ThirdEmail", type="string") + * @var string + */ + private $third_email; + + /** + * @ORM\Column(name="EmailVerified", type="boolean") + * @var bool + */ + private $email_verified; + + /** + * @ORM\Column(name="EmailVerifiedDate", type="datetime") + * @var \DateTime + */ + private $email_verified_date; + + /** + * @return string + */ + public function getEmail() + { + return $this->email; + } + + /** + * @param string $email + */ + public function setEmail($email) + { + $this->email = $email; + } + + /** + * @return bool + */ + public function isEmailVerified() + { + return $this->email_verified; + } + + /** + * @param bool $email_verified + */ + public function setEmailVerified($email_verified) + { + $this->email_verified = $email_verified; + } + + /** + * @return \DateTime + */ + public function getEmailVerifiedDate() + { + return $this->email_verified_date; + } + + /** + * @param \DateTime $email_verified_date + */ + public function setEmailVerifiedDate($email_verified_date) + { + $this->email_verified_date = $email_verified_date; + } + + /** + * @return bool + */ + public function isActive() + { + return $this->active; + } + + /** + * @param bool $active + */ + public function setActive($active) + { + $this->active = $active; + } + + /** + * @ORM\Column(name="Active", type="boolean") + * @var bool + */ + private $active; + /** * @ORM\Column(name="LinkedInProfile", type="string") * @var string @@ -129,7 +236,6 @@ class Member extends SilverstripeBaseModel */ private $twitter_handle; - /** * @ORM\Column(name="Gender", type="string") * @var string @@ -171,6 +277,12 @@ class Member extends SilverstripeBaseModel */ private $feedback; + + /** + * @ORM\OneToMany(targetEntity="Affiliation", mappedBy="owner", cascade={"persist"}) + */ + private $affiliations; + /** * @return File */ diff --git a/app/Models/Foundation/Main/Organization.php b/app/Models/Foundation/Main/Organization.php new file mode 100644 index 00000000..044607b0 --- /dev/null +++ b/app/Models/Foundation/Main/Organization.php @@ -0,0 +1,46 @@ +name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + /** + * @ORM\Column(name="Name", type="string") + * @var string + */ + private $name; +} \ No newline at end of file diff --git a/app/Repositories/Summit/Doctrine/DoctrineMemberRepository.php b/app/Repositories/Summit/Doctrine/DoctrineMemberRepository.php index e47b57f0..68941045 100644 --- a/app/Repositories/Summit/Doctrine/DoctrineMemberRepository.php +++ b/app/Repositories/Summit/Doctrine/DoctrineMemberRepository.php @@ -45,19 +45,24 @@ final class DoctrineMemberRepository extends SilverStripeDoctrineRepository impl */ public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Order $order = null) { - $query = $this->getEntityManager()->createQueryBuilder() - ->select("m") - ->from(\models\main\Member::class, "m"); + $query = $this->getEntityManager() + ->createQueryBuilder() + ->select("m") + ->from(\models\main\Member::class, "m") + ->where("m.active = 1") + ->andWhere("m.first_name is not null") + ->andWhere("m.last_name is not null") + ->andWhere("m.email_verified = 1"); if(!is_null($filter)){ - $filter->apply2Query($query, array - ( + $filter->apply2Query($query, [ 'irc' => 'm.irc_handle:json_string', 'twitter' => 'm.twitter_handle:json_string', 'first_name' => 'm.first_name:json_string', 'last_name' => 'm.last_name:json_string', - )); + 'email' => ['m.email:json_string', 'm.second_email:json_string', 'm.third_email:json_string'], + ]); } if (!is_null($order)) { @@ -74,7 +79,7 @@ final class DoctrineMemberRepository extends SilverStripeDoctrineRepository impl $query = $query->addOrderBy("m.last_name", 'ASC'); } - $query= $query + $query = $query ->setFirstResult($paging_info->getOffset()) ->setMaxResults($paging_info->getPerPage()); diff --git a/tests/OAuth2MembersApiTest.php b/tests/OAuth2MembersApiTest.php index 29298aac..82565998 100644 --- a/tests/OAuth2MembersApiTest.php +++ b/tests/OAuth2MembersApiTest.php @@ -42,4 +42,29 @@ final class OAuth2MembersApiTest extends ProtectedApiTest $this->assertResponseStatus(200); } + public function testGetMembersByEmail() + { + $params = [ + 'filter' => 'email=@sebastian@tipit.net', + 'order' => '+first_name,-last_name', + 'expand' => 'groups' + ]; + + $headers = array("HTTP_Authorization" => " Bearer " . $this->access_token); + $response = $this->action( + "GET", + "OAuth2MembersApiController@getMembers", + $params, + array(), + array(), + array(), + $headers + ); + + $content = $response->getContent(); + $members = json_decode($content); + $this->assertTrue(!is_null($members)); + $this->assertResponseStatus(200); + } + } \ No newline at end of file