diff --git a/marketplace/code/application/assemblers/CompanyServiceAssembler.php b/marketplace/code/application/assemblers/CompanyServiceAssembler.php index 2f82a4d..4f045f7 100644 --- a/marketplace/code/application/assemblers/CompanyServiceAssembler.php +++ b/marketplace/code/application/assemblers/CompanyServiceAssembler.php @@ -36,6 +36,11 @@ final class CompanyServiceAssembler { array_push($videos,MarketPlaceAssembler::convertVideo2Array($video)); } $res['videos'] = $videos; + //draft + if($company_service->isDraft()) { + $res['live_service_id'] = $company_service->getLiveServiceId(); + } + return $res; } diff --git a/marketplace/code/application/assemblers/OpenStackImplementationAssembler.php b/marketplace/code/application/assemblers/OpenStackImplementationAssembler.php index f78411c..1be0ba4 100644 --- a/marketplace/code/application/assemblers/OpenStackImplementationAssembler.php +++ b/marketplace/code/application/assemblers/OpenStackImplementationAssembler.php @@ -40,6 +40,8 @@ final class OpenStackImplementationAssembler { array_push($guest_os,$guest->getIdentifier()); } $res['guest_os'] = $guest_os; + //draft + if ($res) return $res; } diff --git a/marketplace/code/infrastructure/active_records/CompanyService.php b/marketplace/code/infrastructure/active_records/CompanyService.php index a458653..d746669 100644 --- a/marketplace/code/infrastructure/active_records/CompanyService.php +++ b/marketplace/code/infrastructure/active_records/CompanyService.php @@ -61,6 +61,11 @@ class CompanyService return null; } + public function isDraft() + { + return false; + } + public function setCompany(ICompany $company) { AssociationFactory::getInstance()->getMany2OneAssociation($this,'Company')->setTarget($company); diff --git a/marketplace/code/infrastructure/active_records/CompanyServiceDraft.php b/marketplace/code/infrastructure/active_records/CompanyServiceDraft.php index c8d9101..9f61a3e 100644 --- a/marketplace/code/infrastructure/active_records/CompanyServiceDraft.php +++ b/marketplace/code/infrastructure/active_records/CompanyServiceDraft.php @@ -30,8 +30,8 @@ class CompanyServiceDraft ); static $has_many = array( - 'Resources' => 'CompanyServiceResource', - 'Videos' => 'MarketPlaceVideo', + 'Resources' => 'CompanyServiceResourceDraft', + 'Videos' => 'MarketPlaceVideoDraft', ); protected function onBeforeWrite() { @@ -51,6 +51,11 @@ class CompanyServiceDraft return null; } + public function isDraft() + { + return true; + } + public function setCompany(ICompany $company) { AssociationFactory::getInstance()->getMany2OneAssociation($this,'Company')->setTarget($company); @@ -75,6 +80,14 @@ class CompanyServiceDraft $this->setField('LiveServiceID',$company_service_id); } + /** + * @return int + */ + public function getLiveServiceId() + { + return (int)$this->getField('LiveServiceID'); + } + /** * @return int */ diff --git a/marketplace/code/infrastructure/active_records/CompanyServiceResourceDraft.php b/marketplace/code/infrastructure/active_records/CompanyServiceResourceDraft.php new file mode 100644 index 0000000..7071e1b --- /dev/null +++ b/marketplace/code/infrastructure/active_records/CompanyServiceResourceDraft.php @@ -0,0 +1,81 @@ + 'ENGINE=InnoDB'); + + static $db = array( + 'Name' => 'Varchar', + 'Uri' => 'Text', + 'Order' => 'Int', + ); + + + static $has_one = array( + 'Owner' => 'CompanyServiceDraft', + ); + + static $indexes = array( + 'Owner_Name' => array('type'=>'unique', 'value'=>'Name, OwnerID') + ); + + public function getName() + { + return $this->getField('Name'); + } + + public function setName($name) + { + return $this->setField('Name', substr(trim($name),0,250)); + } + + public function getUri() + { + return $this->getField('Uri'); + } + + public function setUri($uri) + { + return $this->setField('Uri', trim($uri)); + } + + /** + * @return ICompanyService + */ + public function getOwner() + { + $query = new QueryObject($this); + $query->addOrder(QueryOrder::asc('Order')); + return AssociationFactory::getInstance()->getMany2OneAssociation($this,'Owner','Resources',$query)->getTarget(); + } + + /** + * @param ICompanyService $new_owner + */ + public function setOwner(ICompanyService $new_owner) + { + $query = new QueryObject($this); + $query->addOrder(QueryOrder::asc('Order')); + AssociationFactory::getInstance()->getMany2OneAssociation($this,'Owner','Resources',$query)->setTarget($new_owner); + } + /** + * @return int + */ + public function getIdentifier() + { + return (int)$this->getField('ID'); + } + + public function getOrder() + { + return (int)$this->getField('Order'); + } + + public function setOrder($order) + { + return $this->setField('Order', (int)$order); + } +} \ No newline at end of file diff --git a/marketplace/code/infrastructure/active_records/MarketPlaceVideoDraft.php b/marketplace/code/infrastructure/active_records/MarketPlaceVideoDraft.php new file mode 100644 index 0000000..d550ab9 --- /dev/null +++ b/marketplace/code/infrastructure/active_records/MarketPlaceVideoDraft.php @@ -0,0 +1,109 @@ + 'ENGINE=InnoDB'); + + static $db = array( + 'Name' => 'Text', + 'Description' => 'Text', + 'YouTubeID' => 'Text', + //seconds + 'Length' => 'int', + ); + + static $has_one = array( + 'Type' => 'MarketPlaceVideoType', + 'Owner' => 'CompanyServiceDraft', + ); + + /** + * @return int + */ + public function getIdentifier() + { + return (int)$this->getField('ID'); + } + + /** + * @param IMarketPlaceVideoType $type + * @return void + */ + public function setType(IMarketPlaceVideoType $type) + { + AssociationFactory::getInstance()->getMany2OneAssociation($this,'Type')->setTarget($type); + } + + /** + * @return IMarketPlaceVideoType + */ + public function getType() + { + return AssociationFactory::getInstance()->getMany2OneAssociation($this,'Type')->getTarget(); + } + + public function getName() + { + return $this->getField('Name'); + } + + public function setName($name) + { + $this->setField('Name',$name); + } + + public function getDescription() + { + return $this->getField('Description'); + } + + public function setDescription($description) + { + $this->setField('Description',$description); + } + + public function getLength() + { + return (int)$this->getField('Length'); + } + + public function setLength($length) + { + $this->setField('Length',$length); + } + + public function setYouTubeId($you_tube_id) + { + $this->setField('YouTubeID',$you_tube_id); + } + + public function getYouTubeId() + { + return $this->getField('YouTubeID'); + } + + /** + * @return ICompanyService + */ + public function getOwner() + { + return AssociationFactory::getInstance()->getMany2OneAssociation($this,'Owner','Videos')->getTarget(); + } + + /** + * @param ICompanyService $owner + * @return void + */ + public function setOwner(ICompanyService $owner) + { + AssociationFactory::getInstance()->getMany2OneAssociation($this,'Owner','Videos')->setTarget($owner); + } + + public function getFormattedLength() + { + $len = $this->getLength(); + return sprintf('%02d', floor($len / 60)).sprintf(':%02d', (int) $len % 60); + } +} \ No newline at end of file diff --git a/marketplace/code/infrastructure/active_records/OpenStackImplementation.php b/marketplace/code/infrastructure/active_records/OpenStackImplementation.php index b3ef1ea..93232dc 100644 --- a/marketplace/code/infrastructure/active_records/OpenStackImplementation.php +++ b/marketplace/code/infrastructure/active_records/OpenStackImplementation.php @@ -24,7 +24,6 @@ class OpenStackImplementation ); static $has_many = array( - 'RegionalSupports' => 'RegionalSupport', 'Capabilities' => 'OpenStackImplementationApiCoverage' ); diff --git a/marketplace/code/infrastructure/active_records/OpenStackImplementationApiCoverageDraft.php b/marketplace/code/infrastructure/active_records/OpenStackImplementationApiCoverageDraft.php new file mode 100644 index 0000000..01a5d50 --- /dev/null +++ b/marketplace/code/infrastructure/active_records/OpenStackImplementationApiCoverageDraft.php @@ -0,0 +1,91 @@ + 'ENGINE=InnoDB'); + + static $db = array( + 'CoveragePercent' => 'Int', + ); + + static $has_one = array( + 'Implementation' => 'OpenStackImplementationDraft', + 'ReleaseSupportedApiVersion' => 'OpenStackReleaseSupportedApiVersion', + ); + + /** + * @return int + */ + public function getIdentifier() + { + return (int)$this->getField('ID'); + } + + /** + * @return int + */ + public function getCoveragePercent() + { + return (int)$this->getField('CoveragePercent'); + } + + /** + * @param int $coverage + * @return void + */ + public function setCoveragePercent($coverage) + { + $this->setField('CoveragePercent',$coverage); + } + + /** + * @return IOpenStackImplementation + */ + public function getImplementation() + { + return AssociationFactory::getInstance()->getMany2OneAssociation($this,'Implementation','Capabilities')->getTarget(); + } + + /** + * @param IOpenStackImplementation $implementation + * @return void + */ + public function setImplementation(IOpenStackImplementation $implementation) + { + AssociationFactory::getInstance()->getMany2OneAssociation($this,'Implementation','Capabilities')->setTarget($implementation); + } + + /** + * @return IReleaseSupportedApiVersion + */ + public function getReleaseSupportedApiVersion() + { + return AssociationFactory::getInstance()->getMany2OneAssociation($this,'ReleaseSupportedApiVersion')->getTarget(); + } + + /** + * @param IReleaseSupportedApiVersion $release_supported_api_version + * @return void + */ + public function setReleaseSupportedApiVersion(IReleaseSupportedApiVersion $release_supported_api_version) + { + AssociationFactory::getInstance()->getMany2OneAssociation($this,'ReleaseSupportedApiVersion')->setTarget($release_supported_api_version); + } + + /** + * @return bool + */ + public function SupportsVersioning() + { + $supported_version = $this->getReleaseSupportedApiVersion(); + if(!$supported_version) return false; + $component = $supported_version->getOpenStackComponent(); + if(!$component) return false; + return $component->getSupportsVersioning(); + } +} \ No newline at end of file diff --git a/marketplace/code/infrastructure/active_records/OpenStackImplementationDraft.php b/marketplace/code/infrastructure/active_records/OpenStackImplementationDraft.php index f6833e0..31ec6c6 100644 --- a/marketplace/code/infrastructure/active_records/OpenStackImplementationDraft.php +++ b/marketplace/code/infrastructure/active_records/OpenStackImplementationDraft.php @@ -13,8 +13,7 @@ class OpenStackImplementationDraft ); static $has_many = array( - 'RegionalSupports' => 'RegionalSupport', - 'Capabilities' => 'OpenStackImplementationApiCoverage' + 'Capabilities' => 'OpenStackImplementationApiCoverageDraft' ); /** diff --git a/marketplace/code/infrastructure/factories/DistributionDraftFactory.php b/marketplace/code/infrastructure/factories/DistributionDraftFactory.php index 8b3b969..adf353b 100644 --- a/marketplace/code/infrastructure/factories/DistributionDraftFactory.php +++ b/marketplace/code/infrastructure/factories/DistributionDraftFactory.php @@ -52,4 +52,19 @@ final class DistributionDraftFactory extends OpenStackImplementationFactory { $regional_support->setCompanyService($service); return $regional_support; } + + /** + * @param int $coverage_percent + * @param IReleaseSupportedApiVersion $release_supported_api_version + * @param IOpenStackImplementation $implementation + * @return IOpenStackImplementationApiCoverage + */ + public function buildCapability($coverage_percent, IReleaseSupportedApiVersion $release_supported_api_version, IOpenStackImplementation $implementation) + { + $capability = new OpenStackImplementationApiCoverageDraft; + $capability->setCoveragePercent($coverage_percent); + $capability->setReleaseSupportedApiVersion($release_supported_api_version); + $capability->setImplementation($implementation); + return $capability; + } } \ No newline at end of file diff --git a/marketplace/code/interfaces/restfull_api/marketplace/CompanyServiceCrudApi.php b/marketplace/code/interfaces/restfull_api/marketplace/CompanyServiceCrudApi.php index 20e5404..169c8e2 100644 --- a/marketplace/code/interfaces/restfull_api/marketplace/CompanyServiceCrudApi.php +++ b/marketplace/code/interfaces/restfull_api/marketplace/CompanyServiceCrudApi.php @@ -195,9 +195,14 @@ abstract class CompanyServiceCrudApi */ public function publishCompanyService(){ try { + $company_service_id = intval($this->request->param('COMPANY_SERVICE_ID')); $data = $this->getJsonRequest(); if (!$data) return $this->serverError(); - $this->manager->publishCompanyService($data); + //save the draft + $this->draft_manager->updateCompanyService($data); + //save the live version + $data['id'] = $data['live_service_id']; + $this->manager->updateCompanyService($data); return $this->published(); } catch (EntityAlreadyExistsException $ex1) { diff --git a/marketplace/code/interfaces/restfull_api/marketplace/DistributionCrudApi.php b/marketplace/code/interfaces/restfull_api/marketplace/DistributionCrudApi.php index a48a0ec..dc2a013 100644 --- a/marketplace/code/interfaces/restfull_api/marketplace/DistributionCrudApi.php +++ b/marketplace/code/interfaces/restfull_api/marketplace/DistributionCrudApi.php @@ -113,7 +113,7 @@ final class DistributionCrudApi extends CompanyServiceCrudApi { 'DELETE $COMPANY_SERVICE_ID!' => 'deleteCompanyService', 'POST ' => 'addCompanyService', 'PUT ' => 'updateCompanyService', - 'PUBLISH ' => 'publishCompanyService', + 'PUT $COMPANY_SERVICE_ID!' => 'publishCompanyService', ); /** @@ -145,8 +145,7 @@ final class DistributionCrudApi extends CompanyServiceCrudApi { public function addCompanyService(){ try { - return parent::addCompanyService(); - //return parent::addCompanyServiceDraft(); + return parent::addCompanyServiceDraft(); } catch (Exception $ex) { SS_Log::log($ex,SS_Log::ERR); @@ -174,4 +173,15 @@ final class DistributionCrudApi extends CompanyServiceCrudApi { } } + public function deleteCompanyService(){ + try { + parent::deleteCompanyService(); + return parent::deleteCompanyServiceDraft(); + } + catch (Exception $ex) { + SS_Log::log($ex,SS_Log::ERR); + return $this->serverError(); + } + } + } \ No newline at end of file diff --git a/marketplace/code/model/base_entities/CompanyServiceManager.php b/marketplace/code/model/base_entities/CompanyServiceManager.php index 47684a3..d4af9cf 100644 --- a/marketplace/code/model/base_entities/CompanyServiceManager.php +++ b/marketplace/code/model/base_entities/CompanyServiceManager.php @@ -380,15 +380,4 @@ abstract class CompanyServiceManager { return $services; } - /** - * @param int $version_id - * @return IEntity|void - * @throws EntityAlreadyExistsException - * @throws NotFoundEntityException - */ - public function publishCompanyService(array $data){ - - - } - } diff --git a/marketplace/code/model/base_entities/ICompanyService.php b/marketplace/code/model/base_entities/ICompanyService.php index a74df24..63fa9d1 100644 --- a/marketplace/code/model/base_entities/ICompanyService.php +++ b/marketplace/code/model/base_entities/ICompanyService.php @@ -15,6 +15,8 @@ * Interface ICompanyService */ interface ICompanyService extends IManipulableEntity { + + public function isDraft(); /** * @param ICompany $company * @return void diff --git a/marketplace/code/ui/admin/MarketPlaceAdminPage.php b/marketplace/code/ui/admin/MarketPlaceAdminPage.php index d1ddd4d..6dee9a8 100644 --- a/marketplace/code/ui/admin/MarketPlaceAdminPage.php +++ b/marketplace/code/ui/admin/MarketPlaceAdminPage.php @@ -192,6 +192,7 @@ class MarketPlaceAdminPage_Controller extends Page_Controller 'consultants', 'consultant', 'preview', + 'draft_preview', 'pdf', ); @@ -201,6 +202,7 @@ class MarketPlaceAdminPage_Controller extends Page_Controller */ static $url_handlers = array( 'GET $MARKETPLACETYPE/$ID/preview' => 'preview', + 'GET $MARKETPLACETYPE/$ID/draft_preview' => 'draft_preview', 'GET $MARKETPLACETYPE/$ID/pdf' => 'pdf', ); @@ -993,6 +995,64 @@ class MarketPlaceAdminPage_Controller extends Page_Controller } } + public function draft_preview() + { + + $marketplace_type = $this->request->param('MARKETPLACETYPE'); + $instance_id = intval($this->request->param('ID')); + + $query = new QueryObject(); + $query->addAddCondition(QueryCriteria::equal('ID', $instance_id)); + Requirements::block("marketplace/code/ui/admin/css/marketplace.admin.css"); + + Requirements::block(Director::protocol() . "code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"); + + switch (strtolower($marketplace_type)) { + case 'distribution': { + $distribution = $this->distribution_draft_repository->getBy($query); + if (!$distribution) throw new NotFoundEntityException('', ''); + $render = new DistributionSapphireRender($distribution); + $distribution ->IsPreview = true; + return $render->draw(); + } + break; + case 'appliance': { + $appliance = $this->appliance_repository->getBy($query); + $appliance->IsPreview = true; + $render = new ApplianceSapphireRender($appliance); + return $render->draw(); + } + break; + case 'public_cloud': { + $public_cloud = $this->public_clouds_repository->getBy($query); + $public_cloud->IsPreview = true; + if (!$public_cloud) throw new NotFoundEntityException('', ''); + $render = new PublicCloudSapphireRender($public_cloud); + return $render->draw(); + } + break; + case 'private_cloud': { + $private_cloud = $this->private_clouds_repository->getBy($query); + $private_cloud->IsPreview = true; + $render = new PrivateCloudSapphireRender($private_cloud); + return $render->draw(); + + } + break; + case 'consultant': { + $consultant = $this->consultant_repository->getBy($query); + if (!$consultant) throw new NotFoundEntityException('', ''); + $consultant->IsPreview = true; + $render = new ConsultantSapphireRender($consultant); + return $render->draw(); + } + break; + default: + $this->httpError(404); + break; + } + } + public function getCurrentDataCenterLocationsJson() { $instance_id = intval($this->request->param('ID')); diff --git a/marketplace/code/ui/admin/js/distribution.js b/marketplace/code/ui/admin/js/distribution.js index eac85a8..d7fa332 100644 --- a/marketplace/code/ui/admin/js/distribution.js +++ b/marketplace/code/ui/admin/js/distribution.js @@ -46,6 +46,7 @@ jQuery(document).ready(function($){ $("#live_id",form).val(distribution.live_service_id); } else { //its not a draft is the live version, so we remove the id and set the live_service_id $("#live_id",form).val(distribution.id); + $('.publish-distribution').prop('disabled',true); } //reload widgets @@ -109,7 +110,9 @@ jQuery(document).ready(function($){ contentType: "application/json; charset=utf-8", dataType: "json", success: function (data,textStatus,jqXHR) { - window.location = listing_url; + //window.location = listing_url; + $('.publish-distribution').prop('disabled',false); + $('.save-distribution').prop('disabled',false); }, error: function (jqXHR, textStatus, errorThrown) { $('.save-distribution').prop('disabled',false); @@ -149,6 +152,7 @@ jQuery(document).ready(function($){ //create distribution object and POST it var distribution = {}; distribution.id = parseInt($("#id",form).val()); + distribution.live_service_id = parseInt($("#live_id",form).val()); distribution.company_id = parseInt($("#company_id",form).val()); distribution.name = $("#name",form).val(); distribution.overview = $("#overview",form).val(); @@ -161,12 +165,13 @@ jQuery(document).ready(function($){ distribution.regional_support = regional_support; distribution.additional_resources = additional_resources; - var type = 'PUBLISH'; + var url = 'api/v1/marketplace/distributions/'+distribution.live_service_id; + + $('.publish-distribution').prop('disabled',true); - $('.save-distribution').prop('disabled',true); $.ajax({ - type: type, - url: 'api/v1/marketplace/distributions', + type: 'PUT', + url: url, data: JSON.stringify(distribution), contentType: "application/json; charset=utf-8", dataType: "json", @@ -174,7 +179,7 @@ jQuery(document).ready(function($){ window.location = listing_url; }, error: function (jqXHR, textStatus, errorThrown) { - $('.save-distribution').prop('disabled',false); + $('.publish-distribution').prop('disabled',false); ajaxError(jqXHR, textStatus, errorThrown); } }); diff --git a/marketplace/templates/Layout/MarketPlaceAdminPage_distribution.ss b/marketplace/templates/Layout/MarketPlaceAdminPage_distribution.ss index 7126c18..64c73dd 100644 --- a/marketplace/templates/Layout/MarketPlaceAdminPage_distribution.ss +++ b/marketplace/templates/Layout/MarketPlaceAdminPage_distribution.ss @@ -3,9 +3,9 @@

Distribution - Product Details

Save - Publish + Publish <% if CurrentDistribution %> - Preview + Preview <% end_if %> <% if CurrentDistribution %> Download PDF