Merge "Company CRUDS"

This commit is contained in:
Zuul 2020-10-01 14:08:24 +00:00 committed by Gerrit Code Review
commit 730806c6a0
13 changed files with 912 additions and 48 deletions

View File

@ -0,0 +1,74 @@
<?php namespace App\Http\Controllers;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class CompanyValidationRulesFactory
* @package App\Http\Controllers
*/
final class CompanyValidationRulesFactory
{
/**
* @param array $data
* @param bool $update
* @return array
*/
public static function build(array $data, $update = false)
{
if ($update) {
return [
'name' => 'sometimes|string',
'url' => 'nullable|url',
'display_on_site' => 'nullable|boolean',
'featured' => 'nullable|boolean',
'city' => 'nullable|string',
'state' => 'nullable|string',
'country' => 'nullable|string',
'description' => 'nullable|string',
'industry' => 'nullable|string',
'products' => 'nullable|string',
'contributions' => 'nullable|string',
'contact_email' => 'nullable|email',
'member_level' => 'nullable|string',
'admin_email' => 'nullable|email',
'color' => 'nullable|hex_color',
'overview' => 'nullable|string',
'commitment' => 'nullable|string',
'commitment_author' => 'nullable|string',
];
}
return [
'name' => 'required|string',
'url' => 'nullable|url',
'display_on_site' => 'nullable|boolean',
'featured' => 'nullable|boolean',
'city' => 'nullable|string',
'state' => 'nullable|string',
'country' => 'nullable|string',
'description' => 'nullable|string',
'industry' => 'nullable|string',
'products' => 'nullable|string',
'contributions' => 'nullable|string',
'contact_email' => 'nullable|email',
'member_level' => 'nullable|string',
'admin_email' => 'nullable|email',
'color' => 'nullable|hex_color',
'overview' => 'nullable|string',
'commitment' => 'nullable|string',
'commitment_author' => 'nullable|string',
];
}
}

View File

@ -12,11 +12,15 @@
* limitations under the License. * limitations under the License.
**/ **/
use App\Services\Model\ICompanyService; use App\Services\Model\ICompanyService;
use Illuminate\Support\Facades\Log;
use models\exceptions\EntityNotFoundException;
use models\main\ICompanyRepository; use models\main\ICompanyRepository;
use models\oauth2\IResourceServerContext; use models\oauth2\IResourceServerContext;
use models\utils\IEntity; use models\utils\IEntity;
use ModelSerializers\SerializerRegistry; use ModelSerializers\SerializerRegistry;
use models\exceptions\ValidationException; use models\exceptions\ValidationException;
use Illuminate\Http\Request as LaravelRequest;
use Exception;
/** /**
* Class OAuth2CompaniesApiController * Class OAuth2CompaniesApiController
* @package App\Http\Controllers * @package App\Http\Controllers
@ -24,6 +28,16 @@ use models\exceptions\ValidationException;
final class OAuth2CompaniesApiController extends OAuth2ProtectedController final class OAuth2CompaniesApiController extends OAuth2ProtectedController
{ {
use ParametrizedGetAll;
use AddEntity;
use UpdateEntity;
use DeleteEntity;
use GetEntity;
/** /**
* @var ICompanyService * @var ICompanyService
*/ */
@ -47,8 +61,6 @@ final class OAuth2CompaniesApiController extends OAuth2ProtectedController
$this->service = $service; $this->service = $service;
} }
use ParametrizedGetAll;
/** /**
* @return mixed * @return mixed
*/ */
@ -81,23 +93,13 @@ final class OAuth2CompaniesApiController extends OAuth2ProtectedController
); );
} }
use AddEntity;
/** /**
* @param array $payload * @param array $payload
* @return array * @return array
*/ */
function getAddValidationRules(array $payload): array function getAddValidationRules(array $payload): array
{ {
return [ return CompanyValidationRulesFactory::build($payload);
'name' => 'required|string',
'description' => 'nullable|string',
'url' => 'nullable|url',
'industry' => 'nullable|string',
'city' => 'nullable|string',
'state' => 'nullable|string',
'country' => 'nullable|string',
];
} }
/** /**
@ -109,4 +111,98 @@ final class OAuth2CompaniesApiController extends OAuth2ProtectedController
{ {
return $this->service->addCompany($payload); return $this->service->addCompany($payload);
} }
/**
* @inheritDoc
*/
protected function deleteEntity(int $id): void
{
$this->service->deleteCompany($id);
}
/**
* @inheritDoc
*/
protected function getEntity(int $id): IEntity
{
return $this->repository->getById($id);
}
/**
* @inheritDoc
*/
function getUpdateValidationRules(array $payload): array
{
return CompanyValidationRulesFactory::build($payload, true);
}
/**
* @inheritDoc
*/
protected function updateEntity($id, array $payload): IEntity
{
return $this->service->updateCompany($id, $payload);
}
// Logos
/**
* @param LaravelRequest $request
* @param $speaker_id
* @return mixed
*/
public function addCompanyLogo(LaravelRequest $request, $company_id)
{
try {
$file = $request->file('file');
if (is_null($file)) {
return $this->error412(array('file param not set!'));
}
$logo = $this->service->addCompanyLogo($company_id, $file);
return $this->created(SerializerRegistry::getInstance()->getSerializer($logo)->serialize());
} catch (EntityNotFoundException $ex1) {
Log::warning($ex1);
return $this->error404();
} catch (ValidationException $ex2) {
Log::warning($ex2);
return $this->error412(array($ex2->getMessage()));
} catch (\HTTP401UnauthorizedException $ex3) {
Log::warning($ex3);
return $this->error401();
} catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
/**
* @param $company_id
* @return \Illuminate\Http\JsonResponse|mixed
*/
public function deleteCompanyLogo($company_id){
try {
$this->service->deleteCompanyLogo($company_id);
return $this->deleted();
} catch (EntityNotFoundException $ex1) {
Log::warning($ex1);
return $this->error404();
} catch (ValidationException $ex2) {
Log::warning($ex2);
return $this->error412(array($ex2->getMessage()));
} catch (\HTTP401UnauthorizedException $ex3) {
Log::warning($ex3);
return $this->error401();
} catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
} }

View File

@ -68,9 +68,23 @@ Route::group([
}); });
// companies // companies
Route::group(['prefix'=>'companies'], function(){ Route::group(['prefix'=>'companies'], function(){
Route::get('', 'OAuth2CompaniesApiController@getAllCompanies'); Route::get('', 'OAuth2CompaniesApiController@getAllCompanies');
Route::post('', 'OAuth2CompaniesApiController@add'); Route::post('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2CompaniesApiController@add']);
Route::group(['prefix'=>'{id}'], function(){
Route::get('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2CompaniesApiController@get']);
Route::put('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2CompaniesApiController@update']);
Route::delete('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2CompaniesApiController@delete']);
Route::group(['prefix'=>'logo'], function(){
Route::post('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2CompaniesApiController@addCompanyLogo']);
Route::delete('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2CompaniesApiController@deleteCompanyLogo']);
Route::group(['prefix'=>'big'], function(){
Route::post('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2CompaniesApiController@addCompanyBigLogo']);
Route::delete('', [ 'middleware' => 'auth.user', 'uses' => 'OAuth2CompaniesApiController@deleteCompanyBigLogo']);
});
});
});
}); });
// organizations // organizations

View File

@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
use models\main\Company;
/** /**
* Class CompanySerializer * Class CompanySerializer
* @package ModelSerializers * @package ModelSerializers
@ -20,10 +20,47 @@ final class CompanySerializer extends SilverStripeSerializer
{ {
protected static $array_mappings = [ protected static $array_mappings = [
'Name' => 'name:json_string', 'Name' => 'name:json_string',
'LogoUrl' => 'logo:json_url', 'Url' => 'url:json_string',
'BigLogoUrl' => 'big_logo:json_url', 'DisplayOnSite' => 'display_on_site:json_boolean',
'Featured' => 'featured:json_boolean',
'City' => 'city:json_string',
'State' => 'state:json_string',
'Country' => 'country:json_string',
'Description' => 'description:json_string', 'Description' => 'description:json_string',
'Industry' => 'industry:json_string', 'Industry' => 'industry:json_string',
'Url' => 'url:json_string', 'Contributions' => 'contributions:json_string',
'ContactEmail' => 'contact_email:json_string',
'MemberLevel' => 'member_level:json_string',
'AdminEmail' => 'admin_email:json_string',
'Overview' => 'overview:json_string',
'Products' => 'products:json_string',
'Commitment' => 'commitment:json_string',
'CommitmentAuthor' => 'commitment_author:json_string',
'LogoUrl' => 'logo:json_url',
'BigLogoUrl' => 'big_logo:json_url',
]; ];
/**
* @param null $expand
* @param array $fields
* @param array $relations
* @param array $params
* @return array
*/
public function serialize($expand = null, array $fields = [], array $relations = [], array $params = [] )
{
$values = parent::serialize($expand, $fields, $relations, $params);
$company = $this->object;
if(!$company instanceof Company) return $values;
$color = isset($values['color']) ? $values['color']:'';
if(empty($color))
$color = 'f0f0ee';
if (strpos($color,'#') === false) {
$color = '#'.$color;
}
$values['color'] = $color;
return $values;
}
} }

View File

@ -12,7 +12,10 @@
* limitations under the License. * limitations under the License.
**/ **/
use App\Models\Foundation\Main\ICompanyMemberLevel;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Illuminate\Support\Facades\Log;
use models\exceptions\ValidationException;
use models\utils\SilverstripeBaseModel; use models\utils\SilverstripeBaseModel;
use Doctrine\ORM\Mapping AS ORM; use Doctrine\ORM\Mapping AS ORM;
@ -27,38 +30,119 @@ class Company extends SilverstripeBaseModel
{ {
/** /**
* @ORM\Column(name="Name", type="string") * @ORM\Column(name="Name", type="string")
* @var string
*/ */
private $name; private $name;
/** /**
* @ORM\Column(name="Description", type="string") * @ORM\Column(name="URL", type="string")
* @var string
*/ */
private $description; private $url;
/** /**
* @ORM\Column(name="Industry", type="string") * @ORM\Column(name="DisplayOnSite", type="boolean")
* @var bool
*/ */
private $industry; private $display_on_site;
/**
* @ORM\Column(name="Featured", type="boolean")
* @var bool
*/
private $featured;
/** /**
* @ORM\Column(name="City", type="string") * @ORM\Column(name="City", type="string")
* @var string
*/ */
private $city; private $city;
/** /**
* @ORM\Column(name="State", type="string") * @ORM\Column(name="State", type="string")
* @var string
*/ */
private $state; private $state;
/** /**
* @ORM\Column(name="Country", type="string") * @ORM\Column(name="Country", type="string")
* @var string
*/ */
private $country; private $country;
/** /**
* @ORM\Column(name="URL", type="string") * @ORM\Column(name="Description", type="string")
* @var string
*/ */
private $url; private $description;
/**
* @ORM\Column(name="Industry", type="string")
* @var string
*/
private $industry;
/**
* @ORM\Column(name="Products", type="string")
* @var string
*/
private $products;
/**
* @ORM\Column(name="Contributions", type="string")
* @var string
*/
private $contributions;
/**
* @ORM\Column(name="ContactEmail", type="string")
* @var string
*/
private $contact_email;
/**
* @ORM\Column(name="MemberLevel", type="string")
* @var string
*/
private $member_level;
/**
* @ORM\Column(name="AdminEmail", type="string")
* @var string
*/
private $admin_email;
/**
* @ORM\Column(name="Color", type="string")
* @var string
*/
private $color;
/**
* @ORM\Column(name="Overview", type="string")
* @var string
*/
private $overview;
/**
* @ORM\Column(name="Commitment", type="string")
* @var string
*/
private $commitment;
/**
* @ORM\Column(name="CommitmentAuthor", type="string")
* @var string
*/
private $commitment_author;
/**
* @ORM\Column(name="isDeleted", type="string")
* @var bool
*/
private $is_deleted;
// relations
/** /**
* @ORM\ManyToMany(targetEntity="models\summit\SummitEvent", mappedBy="sponsors") * @ORM\ManyToMany(targetEntity="models\summit\SummitEvent", mappedBy="sponsors")
@ -66,14 +150,14 @@ class Company extends SilverstripeBaseModel
private $sponsorships; private $sponsorships;
/** /**
* @ORM\ManyToOne(targetEntity="models\main\File") * @ORM\ManyToOne(targetEntity="models\main\File", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="LogoID", referencedColumnName="ID") * @ORM\JoinColumn(name="LogoID", referencedColumnName="ID")
* @var File * @var File
*/ */
private $logo; private $logo;
/** /**
* @ORM\ManyToOne(targetEntity="models\main\File") * @ORM\ManyToOne(targetEntity="models\main\File", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="BigLogoID", referencedColumnName="ID") * @ORM\JoinColumn(name="BigLogoID", referencedColumnName="ID")
* @var File * @var File
*/ */
@ -86,6 +170,9 @@ class Company extends SilverstripeBaseModel
{ {
parent::__construct(); parent::__construct();
$this->sponsorships = new ArrayCollection(); $this->sponsorships = new ArrayCollection();
$this->featured = false;
$this->display_on_site = false;
$this->is_deleted = false;
} }
/** /**
@ -216,6 +303,10 @@ class Company extends SilverstripeBaseModel
$this->logo = $logo; $this->logo = $logo;
} }
public function clearLogo():void{
$this->logo = null;
}
/** /**
* @return File * @return File
*/ */
@ -232,6 +323,10 @@ class Company extends SilverstripeBaseModel
$this->big_logo = $big_logo; $this->big_logo = $big_logo;
} }
public function clearBigLogo():void{
$this->big_logo = null;
}
/** /**
* @return bool * @return bool
*/ */
@ -279,9 +374,15 @@ class Company extends SilverstripeBaseModel
*/ */
public function getLogoUrl(): ?string public function getLogoUrl(): ?string
{ {
$logoUrl = null; $logoUrl = null;
if ($this->hasLogo() && $logo = $this->getLogo()) { try {
$logoUrl = $logo->getUrl(); if ($this->hasLogo() && $logo = $this->getLogo()) {
$logoUrl = $logo->getUrl();
}
}
catch(\Exception $ex){
Log::warning($ex);
} }
return $logoUrl; return $logoUrl;
} }
@ -292,9 +393,212 @@ class Company extends SilverstripeBaseModel
public function getBigLogoUrl(): ?string public function getBigLogoUrl(): ?string
{ {
$logoUrl = null; $logoUrl = null;
if ($this->hasBigLogo() && $logo = $this->getBigLogo()) { try {
$logoUrl = $logo->getUrl(); if ($this->hasBigLogo() && $logo = $this->getBigLogo()) {
$logoUrl = $logo->getUrl();
}
}
catch(\Exception $ex){
Log::warning($ex);
} }
return $logoUrl; return $logoUrl;
} }
/**
* @return bool
*/
public function isDisplayOnSite(): bool
{
return $this->display_on_site;
}
/**
* @param bool $display_on_site
*/
public function setDisplayOnSite(bool $display_on_site): void
{
$this->display_on_site = $display_on_site;
}
/**
* @return bool
*/
public function isFeatured(): bool
{
return $this->featured;
}
/**
* @param bool $featured
*/
public function setFeatured(bool $featured): void
{
$this->featured = $featured;
}
/**
* @return string
*/
public function getProducts(): ?string
{
return $this->products;
}
/**
* @param string $products
*/
public function setProducts(string $products): void
{
$this->products = $products;
}
/**
* @return string
*/
public function getContributions(): ?string
{
return $this->contributions;
}
/**
* @param string $contributions
*/
public function setContributions(string $contributions): void
{
$this->contributions = $contributions;
}
/**
* @return string
*/
public function getContactEmail(): ?string
{
return $this->contact_email;
}
/**
* @param string $contact_email
*/
public function setContactEmail(string $contact_email): void
{
$this->contact_email = $contact_email;
}
/**
* @return string
*/
public function getMemberLevel(): ?string
{
return $this->member_level;
}
/**
* @param string $member_level
* @throws ValidationException
*/
public function setMemberLevel(string $member_level): void
{
if(!in_array($member_level, ICompanyMemberLevel::ValidLevels))
throw new ValidationException(sprintf("level %s is not valid", $member_level));
$this->member_level = $member_level;
}
/**
* @return string
*/
public function getAdminEmail(): ?string
{
return $this->admin_email;
}
/**
* @param string $admin_email
*/
public function setAdminEmail(string $admin_email): void
{
$this->admin_email = $admin_email;
}
/**
* @return string
*/
public function getColor(): ?string
{
return $this->color;
}
/**
* @param string $color
*/
public function setColor(string $color): void
{
$this->color = $color;
}
/**
* @return string
*/
public function getOverview(): ?string
{
return $this->overview;
}
/**
* @param string $overview
*/
public function setOverview(string $overview): void
{
$this->overview = $overview;
}
/**
* @return string
*/
public function getCommitment(): ?string
{
return $this->commitment;
}
/**
* @param string $commitment
*/
public function setCommitment(string $commitment): void
{
$this->commitment = $commitment;
}
/**
* @return string
*/
public function getCommitmentAuthor(): ?string
{
return $this->commitment_author;
}
/**
* @param string $commitment_author
*/
public function setCommitmentAuthor(string $commitment_author): void
{
$this->commitment_author = $commitment_author;
}
/**
* @return bool
*/
public function isIsDeleted(): bool
{
return $this->is_deleted;
}
/**
* @param bool $is_deleted
*/
public function setIsDeleted(bool $is_deleted): void
{
$this->is_deleted = $is_deleted;
}
} }

View File

@ -1,6 +1,4 @@
<?php namespace App\Models\Foundation\Main\Factories; <?php namespace App\Models\Foundation\Main\Factories;
use models\main\Company;
/** /**
* Copyright 2020 OpenStack Foundation * Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -13,7 +11,7 @@ use models\main\Company;
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
use models\main\Company;
/** /**
* Class CompanyFactory * Class CompanyFactory
* @package App\Models\Foundation\Main\Factories * @package App\Models\Foundation\Main\Factories
@ -40,14 +38,14 @@ final class CompanyFactory
if (isset($data['name'])) if (isset($data['name']))
$company->setName(trim($data['name'])); $company->setName(trim($data['name']));
if (isset($data['description']))
$company->setDescription(trim($data['description']));
if (isset($data['url'])) if (isset($data['url']))
$company->setUrl(trim($data['url'])); $company->setUrl(trim($data['url']));
if (isset($data['industry'])) if (isset($data['display_on_site']))
$company->setIndustry(trim($data['industry'])); $company->setDisplayOnSite(boolval($data['display_on_site']));
if (isset($data['featured']))
$company->setFeatured(boolval($data['featured']));
if (isset($data['city'])) if (isset($data['city']))
$company->setCity(trim($data['city'])); $company->setCity(trim($data['city']));
@ -58,6 +56,42 @@ final class CompanyFactory
if (isset($data['country'])) if (isset($data['country']))
$company->setCountry(trim($data['country'])); $company->setCountry(trim($data['country']));
if (isset($data['description']))
$company->setDescription(trim($data['description']));
if (isset($data['industry']))
$company->setIndustry(trim($data['industry']));
if (isset($data['products']))
$company->setProducts(trim($data['products']));
if (isset($data['contributions']))
$company->setContributions(trim($data['contributions']));
if (isset($data['contact_email']))
$company->setContactEmail(trim($data['contact_email']));
if (isset($data['member_level']))
$company->setMemberLevel(trim($data['member_level']));
if (isset($data['admin_email']))
$company->setAdminEmail(trim($data['admin_email']));
if (isset($data['color']))
$company->setColor(trim($data['color']));
if (isset($data['overview']))
$company->setOverview(trim($data['overview']));
if (isset($data['commitment']))
$company->setCommitment(trim($data['commitment']));
if (isset($data['commitment_author']))
$company->setCommitmentAuthor(trim($data['commitment_author']));
if (isset($data['is_deleted']))
$company->setIsDeleted(boolval($data['is_deleted']));
return $company; return $company;
} }
} }

View File

@ -0,0 +1,37 @@
<?php namespace App\Models\Foundation\Main;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Interface ICompanyMemberLevel
* @package App\Models\Foundation\Main
*/
interface ICompanyMemberLevel
{
const Platinum = 'Platinum';
const Gold = 'Gold';
const StartUp = 'StartUp';
const Corporate = 'Corporate';
const Mention = 'Mention';
const None = 'None';
const ValidLevels = [
self::Platinum,
self::Gold,
self::StartUp,
self::Corporate,
self::Mention,
self::None
];
}

View File

@ -0,0 +1,23 @@
<?php namespace App\Security;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class CompanyScopes
* @package App\Security
*/
final class CompanyScopes
{
const Read = '%s/companies/read';
const Write = '%s/companies/write';
}

View File

@ -11,9 +11,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
use Illuminate\Http\UploadedFile;
use models\exceptions\EntityNotFoundException; use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException; use models\exceptions\ValidationException;
use models\main\Company; use models\main\Company;
use models\main\File;
/** /**
* Interface ICompanyService * Interface ICompanyService
* @package App\Services\Model * @package App\Services\Model
@ -42,4 +44,36 @@ interface ICompanyService
* @throws EntityNotFoundException * @throws EntityNotFoundException
*/ */
public function deleteCompany(int $company_id):void; public function deleteCompany(int $company_id):void;
/**
* @param int $company_id
* @param UploadedFile $file
* @param int $max_file_size
* @throws EntityNotFoundException
* @throws ValidationException
* @return File
*/
public function addCompanyLogo(int $company_id, UploadedFile $file, $max_file_size = 10485760):File;
/**
* @throws EntityNotFoundException
* @param int $company_id
*/
public function deleteCompanyLogo(int $company_id):void;
/**
* @param int $company_id
* @param UploadedFile $file
* @param int $max_file_size
* @throws EntityNotFoundException
* @throws ValidationException
* @return File
*/
public function addCompanyBigLogo(int $company_id, UploadedFile $file, $max_file_size = 10485760):File;
/**
* @throws EntityNotFoundException
* @param int $company_id
*/
public function deleteCompanyBigLogo(int $company_id):void;
} }

View File

@ -11,14 +11,16 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
use App\Http\Utils\IFileUploader;
use App\Models\Foundation\Main\Factories\CompanyFactory; use App\Models\Foundation\Main\Factories\CompanyFactory;
use App\Services\Model\AbstractService; use App\Services\Model\AbstractService;
use App\Services\Model\ICompanyService; use App\Services\Model\ICompanyService;
use Illuminate\Http\UploadedFile;
use libs\utils\ITransactionService; use libs\utils\ITransactionService;
use models\exceptions\EntityNotFoundException; use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException; use models\exceptions\ValidationException;
use models\main\Company; use models\main\Company;
use models\main\File;
use models\main\ICompanyRepository; use models\main\ICompanyRepository;
/** /**
* Class CompanyService * Class CompanyService
@ -34,6 +36,11 @@ final class CompanyService
*/ */
private $repository; private $repository;
/**
* @var IFileUploader
*/
private $file_uploader;
/** /**
* CompanyService constructor. * CompanyService constructor.
* @param ICompanyRepository $repository * @param ICompanyRepository $repository
@ -42,11 +49,13 @@ final class CompanyService
public function __construct public function __construct
( (
ICompanyRepository $repository, ICompanyRepository $repository,
IFileUploader $file_uploader,
ITransactionService $tx_service ITransactionService $tx_service
) )
{ {
parent::__construct($tx_service); parent::__construct($tx_service);
$this->repository = $repository; $this->repository = $repository;
$this->file_uploader = $file_uploader;
} }
/** /**
@ -77,7 +86,20 @@ final class CompanyService
*/ */
public function updateCompany(int $company_id, array $payload): Company public function updateCompany(int $company_id, array $payload): Company
{ {
// TODO: Implement updateCompany() method. return $this->tx_service->transaction(function() use($company_id, $payload){
$company = $this->repository->getById($company_id);
if(is_null($company) || !$company instanceof Company)
throw new EntityNotFoundException(sprintf("company %s not found.", $company_id));
if(isset($payload['name'])){
$former_company = $this->repository->getByName(trim($payload['name']));
if(!is_null($former_company) && $company_id !== $former_company->getId()){
throw new ValidationException(sprintf("company %s already exists", $payload['name']));
}
}
return CompanyFactory::populate($company, $payload);
});
} }
/** /**
@ -87,6 +109,106 @@ final class CompanyService
*/ */
public function deleteCompany(int $company_id): void public function deleteCompany(int $company_id): void
{ {
// TODO: Implement deleteCompany() method. $this->tx_service->transaction(function() use($company_id){
$company = $this->repository->getById($company_id);
if(is_null($company))
throw new EntityNotFoundException(sprintf("company %s not found.", $company_id));
$this->repository->delete($company);
});
}
/**
* @inheritDoc
*/
public function addCompanyLogo(int $company_id, UploadedFile $file, $max_file_size = 10485760): File
{
return $this->tx_service->transaction(function () use ($company_id, $file, $max_file_size) {
$allowed_extensions = ['png', 'jpg', 'jpeg', 'svg'];
$company = $this->repository->getById($company_id);
if (is_null($company) || !$company instanceof Company) {
throw new EntityNotFoundException('company not found!');
}
if (!in_array($file->extension(), $allowed_extensions)) {
throw new ValidationException("file does not has a valid extension ('png', 'jpg', 'jpeg', 'svg').");
}
if ($file->getSize() > $max_file_size) {
throw new ValidationException(sprintf("file exceeds max_file_size (%s MB).", ($max_file_size / 1024) / 1024));
}
$logo = $this->file_uploader->build($file, sprintf('companies/%s/logos', $company->getId()), true);
$company->setLogo($logo);
return $logo;
});
}
/**
* @inheritDoc
*/
public function deleteCompanyLogo(int $company_id): void
{
$this->tx_service->transaction(function () use ($company_id) {
$company = $this->repository->getById($company_id);
if (is_null($company) || !$company instanceof Company) {
throw new EntityNotFoundException('company not found!');
}
$company->clearLogo();
});
}
/**
* @inheritDoc
*/
public function addCompanyBigLogo(int $company_id, UploadedFile $file, $max_file_size = 10485760): File
{
return $this->tx_service->transaction(function () use ($company_id, $file, $max_file_size) {
$allowed_extensions = ['png', 'jpg', 'jpeg', 'svg'];
$company = $this->repository->getById($company_id);
if (is_null($company) || !$company instanceof Company) {
throw new EntityNotFoundException('company not found!');
}
if (!in_array($file->extension(), $allowed_extensions)) {
throw new ValidationException("file does not has a valid extension ('png', 'jpg', 'jpeg', 'svg').");
}
if ($file->getSize() > $max_file_size) {
throw new ValidationException(sprintf("file exceeds max_file_size (%s MB).", ($max_file_size / 1024) / 1024));
}
$logo = $this->file_uploader->build($file, sprintf('companies/%s/logos', $company->getId()), true);
$company->setBigLogo($logo);
return $logo;
});
}
/**
* @inheritDoc
*/
public function deleteCompanyBigLogo(int $company_id): void
{
$this->tx_service->transaction(function () use ($company_id) {
$company = $this->repository->getById($company_id);
if (is_null($company) || !$company instanceof Company) {
throw new EntityNotFoundException('company not found!');
}
$company->clearBigLogo();
});
} }
} }

View File

@ -19,6 +19,7 @@ use App\Security\SummitScopes;
use App\Security\OrganizationScopes; use App\Security\OrganizationScopes;
use App\Security\MemberScopes; use App\Security\MemberScopes;
use App\Models\Foundation\Main\IGroup; use App\Models\Foundation\Main\IGroup;
use App\Security\CompanyScopes;
/** /**
* Class ApiEndpointsSeeder * Class ApiEndpointsSeeder
*/ */
@ -5493,7 +5494,6 @@ class ApiEndpointsSeeder extends Seeder
private function seedCompaniesEndpoints(){ private function seedCompaniesEndpoints(){
$current_realm = Config::get('app.scope_base_realm'); $current_realm = Config::get('app.scope_base_realm');
$this->seedApiEndpoints('companies', [ $this->seedApiEndpoints('companies', [
[ [
'name' => 'get-companies', 'name' => 'get-companies',
@ -5502,23 +5502,102 @@ class ApiEndpointsSeeder extends Seeder
'scopes' => [ 'scopes' => [
sprintf(SummitScopes::ReadAllSummitData, $current_realm), sprintf(SummitScopes::ReadAllSummitData, $current_realm),
sprintf(SummitScopes::ReadSummitData, $current_realm), sprintf(SummitScopes::ReadSummitData, $current_realm),
sprintf('%s/companies/read', $current_realm) sprintf(CompanyScopes::Read, $current_realm)
], ],
], ],
[ [
'name' => 'add-companies', 'name' => 'add-company',
'route' => '/api/v1/companies', 'route' => '/api/v1/companies',
'http_method' => 'POST', 'http_method' => 'POST',
'scopes' => [ 'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm), sprintf(CompanyScopes::Write, $current_realm)
sprintf('%s/companies/write', $current_realm)
], ],
'authz_groups' => [ 'authz_groups' => [
IGroup::SuperAdmins, IGroup::SuperAdmins,
IGroup::Administrators, IGroup::Administrators,
IGroup::SummitAdministrators,
] ]
] ],
[
'name' => 'update-company',
'route' => '/api/v1/companies/{id}',
'http_method' => 'PUT',
'scopes' => [
sprintf(CompanyScopes::Write, $current_realm)
],
'authz_groups' => [
IGroup::SuperAdmins,
IGroup::Administrators,
]
],
[
'name' => 'delete-company',
'route' => '/api/v1/companies/{id}',
'http_method' => 'DELETE',
'scopes' => [
sprintf(CompanyScopes::Write, $current_realm)
],
'authz_groups' => [
IGroup::SuperAdmins,
IGroup::Administrators,
]
],
[
'name' => 'get-company',
'route' => '/api/v1/companies/{id}',
'http_method' => 'GET',
'scopes' => [
sprintf(CompanyScopes::Read, $current_realm)
]
],
[
'name' => 'add-company-logo',
'route' => '/api/v1/companies/{id}/logo',
'http_method' => 'POST',
'scopes' => [
sprintf(CompanyScopes::Write, $current_realm)
],
'authz_groups' => [
IGroup::SuperAdmins,
IGroup::Administrators,
]
],
[
'name' => 'delete-company-logo',
'route' => '/api/v1/companies/{id}/logo',
'http_method' => 'DELETE',
'scopes' => [
sprintf(CompanyScopes::Write, $current_realm)
],
'authz_groups' => [
IGroup::SuperAdmins,
IGroup::Administrators,
]
],
[
'name' => 'add-company-big-logo',
'route' => '/api/v1/companies/{id}/logo/big',
'http_method' => 'POST',
'scopes' => [
sprintf(CompanyScopes::Write, $current_realm)
],
'authz_groups' => [
IGroup::SuperAdmins,
IGroup::Administrators,
]
],
[
'name' => 'delete-company-big-logo',
'route' => '/api/v1/companies/{id}/logo/big',
'http_method' => 'DELETE',
'scopes' => [
sprintf(CompanyScopes::Write, $current_realm)
],
'authz_groups' => [
IGroup::SuperAdmins,
IGroup::Administrators,
]
],
] ]
); );
} }

View File

@ -42,6 +42,7 @@ class OAuth2CompaniesApiTest extends ProtectedApiTest
} }
public function testAddCompany(){ public function testAddCompany(){
$data = [ $data = [
'name' => str_random(16).'_company', 'name' => str_random(16).'_company',
'description' => str_random(16).'_description', 'description' => str_random(16).'_description',
@ -70,4 +71,8 @@ class OAuth2CompaniesApiTest extends ProtectedApiTest
return $company; return $company;
} }
public function testAddCompanyBigLogo(){
}
} }

View File

@ -19,6 +19,7 @@ use App\Security\SummitScopes;
use App\Security\OrganizationScopes; use App\Security\OrganizationScopes;
use App\Security\MemberScopes; use App\Security\MemberScopes;
use App\Models\Foundation\Main\IGroup; use App\Models\Foundation\Main\IGroup;
use App\Security\CompanyScopes;
/** /**
* Class AccessTokenServiceStub * Class AccessTokenServiceStub
*/ */
@ -106,6 +107,8 @@ class AccessTokenServiceStub implements IAccessTokenService
sprintf(SummitScopes::LeaveEvent, $url), sprintf(SummitScopes::LeaveEvent, $url),
sprintf(SummitScopes::ReadSummitMediaFileTypes, $url), sprintf(SummitScopes::ReadSummitMediaFileTypes, $url),
sprintf(SummitScopes::WriteSummitMediaFileTypes, $url), sprintf(SummitScopes::WriteSummitMediaFileTypes, $url),
sprintf(CompanyScopes::Write, $url),
sprintf(CompanyScopes::Read, $url),
); );
return AccessToken::createFromParams( return AccessToken::createFromParams(
@ -199,6 +202,8 @@ class AccessTokenServiceStub2 implements IAccessTokenService
sprintf(SummitScopes::LeaveEvent, $url), sprintf(SummitScopes::LeaveEvent, $url),
sprintf(SummitScopes::ReadSummitMediaFileTypes, $url), sprintf(SummitScopes::ReadSummitMediaFileTypes, $url),
sprintf(SummitScopes::WriteSummitMediaFileTypes, $url), sprintf(SummitScopes::WriteSummitMediaFileTypes, $url),
sprintf(CompanyScopes::Write, $url),
sprintf(CompanyScopes::Read, $url),
); );
return AccessToken::createFromParams( return AccessToken::createFromParams(