How to use is method of name class

Best Prophecy code snippet using name.is

ModelJoinBuilder.php

Source:ModelJoinBuilder.php Github

copy

Full Screen

1<?php2 /*********************************************************************************3 * Zurmo is a customer relationship management program developed by4 * Zurmo, Inc. Copyright (C) 2014 Zurmo Inc.5 *6 * Zurmo is free software; you can redistribute it and/or modify it under7 * the terms of the GNU Affero General Public License version 3 as published by the8 * Free Software Foundation with the addition of the following permission added9 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK10 * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY11 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.12 *13 * Zurmo is distributed in the hope that it will be useful, but WITHOUT14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS15 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more16 * details.17 *18 * You should have received a copy of the GNU Affero General Public License along with19 * this program; if not, see http://www.gnu.org/licenses or write to the Free20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA21 * 02110-1301 USA.22 *23 * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive24 * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.25 *26 * The interactive user interfaces in original and modified versions27 * of this program must display Appropriate Legal Notices, as required under28 * Section 5 of the GNU Affero General Public License version 3.29 *30 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,31 * these Appropriate Legal Notices must retain the display of the Zurmo32 * logo and Zurmo copyright notice. If the display of the logo is not reasonably33 * feasible for technical reasons, the Appropriate Legal Notices must display the words34 * "Copyright Zurmo Inc. 2014. All rights reserved".35 ********************************************************************************/36 /**37 * Base Builder for creating joins.38 */39 class ModelJoinBuilder40 {41 /**42 * @var RedBeanModelAttributeToDataProviderAdapter43 */44 protected $modelAttributeToDataProviderAdapter;45 /**46 * @var RedBeanModelJoinTablesQueryAdapter47 */48 protected $joinTablesAdapter;49 /**50 * @var bool51 */52 protected $setDistinct;53 /**54 * @var string55 */56 protected $resolvedOnTableAliasName;57 /**58 * This is set during resolveJoins as the tableAliasName for the base model class. This can then be accessed59 * outside this class for querying purposes.60 * Base model class is represented by $modelAttributeToDataProviderAdapter->getModelClassName();61 * @var string62 */63 protected $tableAliasNameForBaseModel;64 /**65 * This is set during resolveJoins as the tableAliasName for the related model class. This can then be accessed66 * outside this class for querying purposes.67 * Related model class is represented by $modelAttributeToDataProviderAdapter->getRelatedModelClassName();68 * @var string69 */70 protected $tableAliasNameForRelatedModel;71 /**72 * @param string $tableAliasName73 * @param string $columnName74 * @return string75 */76 public static function makeColumnNameWithTableAlias($tableAliasName, $columnName)77 {78 assert('is_string($tableAliasName)');79 assert('is_string($columnName)');80 $quote = DatabaseCompatibilityUtil::getQuote();81 return $quote . $tableAliasName . $quote . '.' . $quote . $columnName . $quote;82 }83 /**84 * @param string $idName85 * @return string86 */87 protected static function resolveForeignKey($idName)88 {89 assert('is_string($idName)');90 return $idName . '_id';91 }92 /**93 * @param RedBeanModelAttributeToDataProviderAdapter $modelAttributeToDataProviderAdapter94 * @param RedBeanModelJoinTablesQueryAdapter $joinTablesAdapter95 * @param boolean $setDistinct96 */97 public function __construct(RedBeanModelAttributeToDataProviderAdapter98 $modelAttributeToDataProviderAdapter,99 RedBeanModelJoinTablesQueryAdapter100 $joinTablesAdapter,101 $setDistinct = false)102 {103 $this->modelAttributeToDataProviderAdapter = $modelAttributeToDataProviderAdapter;104 $this->joinTablesAdapter = $joinTablesAdapter;105 $this->setDistinct = $setDistinct;106 }107 /**108 * @return string109 */110 public function getTableAliasNameForBaseModel()111 {112 return $this->tableAliasNameForBaseModel;113 }114 /**115 * @return string116 * @throws NotSupportedException117 */118 public function getTableAliasNameForRelatedModel()119 {120 if (!$this->modelAttributeToDataProviderAdapter->hasRelatedAttribute())121 {122 throw new NotSupportedException();123 }124 return $this->tableAliasNameForRelatedModel;125 }126 /**127 * @param null $onTableAliasName128 * @param bool $canUseFromJoins129 * @return null|string130 */131 public function resolveJoins($onTableAliasName = null, $canUseFromJoins = true)132 {133 assert('is_string($onTableAliasName) || $onTableAliasName == null');134 assert('is_bool($canUseFromJoins)');135 $onTableAliasName = $this->resolveOnTableAliasName($onTableAliasName);136 $this->tableAliasNameForBaseModel = $onTableAliasName;137 $onTableAliasName = $this->resolveJoinsForAttribute($onTableAliasName, $canUseFromJoins);138 $this->resolvedOnTableAliasName = $onTableAliasName;139 if ($this->modelAttributeToDataProviderAdapter->hasRelatedAttribute())140 {141 $modelAttributeToDataProviderAdapter = new RedBeanModelAttributeToDataProviderAdapter(142 $this->modelAttributeToDataProviderAdapter->143 getRelationModelClassNameThatCanHaveATable(),144 $this->modelAttributeToDataProviderAdapter->145 getRelatedAttribute());146 $builderClassName = get_class($this);147 $builder = new $builderClassName($modelAttributeToDataProviderAdapter,148 $this->joinTablesAdapter);149 $this->tableAliasNameForRelatedModel = $onTableAliasName;150 $onTableAliasName = $builder->resolveJoinsForAttribute($onTableAliasName, false);151 }152 return $onTableAliasName;153 }154 /**155 * @param null $onTableAliasName156 * @param bool $canUseFromJoins157 * @return null|string158 */159 public function resolveOnlyAttributeJoins($onTableAliasName = null, $canUseFromJoins = true)160 {161 assert('is_string($onTableAliasName) || $onTableAliasName == null');162 assert('is_bool($canUseFromJoins)');163 $onTableAliasName = $this->resolveOnTableAliasName($onTableAliasName);164 $onTableAliasName = $this->resolveJoinsForAttribute($onTableAliasName, $canUseFromJoins);165 $this->resolvedOnTableAliasName = $onTableAliasName;166 return $onTableAliasName;167 }168 /**169 * @param null $onTableAliasName170 * @return null | string171 */172 public function resolveOnTableAliasName($onTableAliasName = null)173 {174 if ($onTableAliasName == null)175 {176 $onTableAliasName = $this->resolveOnTableAliasNameForDerivedRelationViaCastedUpModel();177 }178 return $onTableAliasName;179 }180 /**181 * @param $onTableAliasName182 * @param bool $canUseFromJoins183 * @return null|string184 */185 protected function resolveJoinsForAttribute($onTableAliasName, $canUseFromJoins = true)186 {187 assert('is_string($onTableAliasName)');188 assert('is_bool($canUseFromJoins)');189 if ($this->modelAttributeToDataProviderAdapter->isAttributeDerivedRelationViaCastedUpModel())190 {191 return $this->resolveJoinsForDerivedRelationViaCastedUpModel($onTableAliasName, $canUseFromJoins);192 }193 elseif ($this->modelAttributeToDataProviderAdapter->isInferredRelation())194 {195 return $this->resolveJoinsForInferredRelation($onTableAliasName, $canUseFromJoins);196 }197 elseif ($this->modelAttributeToDataProviderAdapter->isAttributeOnDifferentModel())198 {199 return $this->resolveJoinsForAttributeOnDifferentModel($onTableAliasName, $canUseFromJoins);200 }201 elseif ($this->modelAttributeToDataProviderAdapter->isRelation())202 {203 return $this->resolveJoinsForAttributeOnSameModelThatIsARelation($onTableAliasName);204 }205 else206 {207 return $this->resolveJoinsForAttributeOnSameModelThatIsNotARelation($onTableAliasName);208 }209 }210 /**211 * @param $onTableAliasName212 * @param bool $canUseFromJoins213 * @return null|string214 */215 protected function resolveJoinsForDerivedRelationViaCastedUpModel($onTableAliasName, $canUseFromJoins = true)216 {217 assert('is_string($onTableAliasName)');218 assert('is_bool($canUseFromJoins)');219 //First cast up220 $onTableAliasName = $this->resolveJoinsForDerivedRelationViaCastedUpModelThatIsCastedUp(221 $onTableAliasName, $canUseFromJoins);222 //Second build relation across to the opposing model223 $onTableAliasName = $this->resolveJoinsForDerivedRelationViaCastedUpModelThatIsManyToMany(224 $onTableAliasName);225 //Third cast down if necessary226 if ($this->modelAttributeToDataProviderAdapter->isDerivedRelationViaCastedUpModelDifferentThanOpposingModelClassName())227 {228 $opposingRelationModelClassName = $this->modelAttributeToDataProviderAdapter->229 getOpposingRelationModelClassName();230 $derivedRelationModelClassName = $this->modelAttributeToDataProviderAdapter->231 getDerivedRelationViaCastedUpModelClassName();232 $onTableAliasName = $this->resolveAndProcessLeftJoinsForAttributeThatIsCastedDownOrUp(233 $opposingRelationModelClassName,234 $derivedRelationModelClassName, $onTableAliasName);235 }236 return $onTableAliasName;237 }238 /**239 * @param $onTableAliasName240 * @param bool $canUseFromJoins241 * @return null|string242 */243 protected function resolveJoinsForDerivedRelationViaCastedUpModelThatIsCastedUp($onTableAliasName, $canUseFromJoins = true)244 {245 $modelClassName = $this->modelAttributeToDataProviderAdapter->getModelClassName();246 $attributeModelClassName = $this->modelAttributeToDataProviderAdapter->247 getCastedUpModelClassNameForDerivedRelation();248 if ($canUseFromJoins)249 {250 return $this->processFromJoinsForAttributeThatIsCastedUp($modelClassName, $attributeModelClassName);251 }252 else253 {254 return $this->processLeftJoinsForAttributeThatIsCastedUp($onTableAliasName, $modelClassName, $attributeModelClassName);255 }256 }257 /**258 * @param $onTableAliasName259 * @return null|string260 */261 protected function resolveJoinsForDerivedRelationViaCastedUpModelThatIsManyToMany($onTableAliasName)262 {263 assert('is_string($onTableAliasName)');264 $opposingRelationTableName = $this->modelAttributeToDataProviderAdapter->getOpposingRelationTableName();265 $relationJoiningTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(266 $this->modelAttributeToDataProviderAdapter->getManyToManyTableNameForDerivedRelationViaCastedUpModel(),267 "id",268 $onTableAliasName,269 self::resolveForeignKey($onTableAliasName));270 $onTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(271 $opposingRelationTableName,272 self::resolveForeignKey($opposingRelationTableName),273 $relationJoiningTableAliasName,274 'id');275 return $onTableAliasName;276 }277 /**278 * @param $onTableAliasName279 * @param bool $canUseFromJoins280 * @return null|string281 * @throws NotImplementedException282 */283 protected function resolveJoinsForInferredRelation($onTableAliasName, $canUseFromJoins = true)284 {285 assert('is_string($onTableAliasName)');286 assert('is_bool($canUseFromJoins)');287 //First cast up288 $onTableAliasName = $this->resolveJoinsForInferredRelationThatIsCastedUp(289 $onTableAliasName, $canUseFromJoins);290 //Second build relation across to the opposing model291 $onTableAliasName = $this->resolveJoinsForForARelationAttributeThatIsManyToMany($onTableAliasName);292 //Casting down should always be necessary since that is the whole point of using a referred relation293 $opposingRelationModelClassName = $this->modelAttributeToDataProviderAdapter->getRelationModelClassName();294 if ($opposingRelationModelClassName != 'Item')295 {296 throw new NotImplementedException();297 }298 $inferredRelationModelClassName = $this->modelAttributeToDataProviderAdapter->getInferredRelationModelClassName();299 $onTableAliasName = $this->resolveAndProcessLeftJoinsForAttributeThatIsCastedDownOrUp(300 $opposingRelationModelClassName,301 $inferredRelationModelClassName, $onTableAliasName);302 return $onTableAliasName;303 }304 /**305 * @param $onTableAliasName306 * @param bool $canUseFromJoins307 * @return null|string308 */309 protected function resolveJoinsForInferredRelationThatIsCastedUp($onTableAliasName, $canUseFromJoins = true)310 {311 $modelClassName = $this->modelAttributeToDataProviderAdapter->getModelClassName();312 $attributeModelClassName = $this->modelAttributeToDataProviderAdapter->getAttributeModelClassName();313 if ($modelClassName == $attributeModelClassName)314 {315 return $onTableAliasName;316 }317 if ($canUseFromJoins)318 {319 return $this->processFromJoinsForAttributeThatIsCastedUp($modelClassName, $attributeModelClassName);320 }321 else322 {323 return $this->processLeftJoinsForAttributeThatIsCastedUp($onTableAliasName, $modelClassName, $attributeModelClassName);324 }325 }326 /**327 * @param $attributeModelClassName328 * @return string329 */330 protected function resolveAttributeModelClassNameWithCastingHintForCastingDown($attributeModelClassName)331 {332 assert('is_string($attributeModelClassName)');333 if ($this->modelAttributeToDataProviderAdapter->getCastingHintModelClassNameForAttribute() != null)334 {335 return $this->modelAttributeToDataProviderAdapter->getCastingHintModelClassNameForAttribute();336 }337 return $attributeModelClassName;338 }339 /**340 * @param $onTableAliasName341 * @param bool $canUseFromJoins342 * @return null|string343 */344 protected function resolveJoinsForAttributeOnDifferentModel($onTableAliasName, $canUseFromJoins = true)345 {346 assert('is_string($onTableAliasName)');347 assert('is_bool($canUseFromJoins)');348 if ($this->modelAttributeToDataProviderAdapter->isRelation())349 {350 return $this->resolveJoinsForAttributeOnDifferentModelThatIsARelation($onTableAliasName, $canUseFromJoins);351 }352 else353 {354 return $this->resolveJoinsForAttributeOnDifferentModelThatIsNotARelation($onTableAliasName,355 $canUseFromJoins);356 }357 }358 /**359 * @param $onTableAliasName360 * @return null|string361 */362 protected function resolveJoinsForAttributeOnSameModelThatIsARelation($onTableAliasName)363 {364 assert('is_string($onTableAliasName)');365 return $this->resolveLeftJoinsForARelationAttribute($onTableAliasName);366 }367 /**368 * @param $onTableAliasName369 * @return mixed370 */371 protected function resolveJoinsForAttributeOnSameModelThatIsNotARelation($onTableAliasName)372 {373 assert('is_string($onTableAliasName)');374 return $onTableAliasName;375 }376 /**377 * @param $onTableAliasName378 * @param bool $canUseFromJoins379 * @return null|string380 */381 protected function resolveJoinsForAttributeOnDifferentModelThatIsARelation($onTableAliasName, $canUseFromJoins = true)382 {383 assert('is_string($onTableAliasName)');384 assert('is_bool($canUseFromJoins)');385 if ($canUseFromJoins)386 {387 $onTableAliasName = $this->addMixedInOrCastedUpFromJoinsForAttribute($onTableAliasName);388 }389 else390 {391 $onTableAliasName = $this->addMixedInOrCastedUpLeftJoinsForAttribute($onTableAliasName);392 }393 return $this->resolveLeftJoinsForARelationAttribute($onTableAliasName);394 }395 /**396 * @param $onTableAliasName397 * @return null|string398 */399 protected function resolveLeftJoinsForARelationAttribute($onTableAliasName)400 {401 assert('is_string($onTableAliasName)');402 return $this->addLeftJoinsForARelationAttribute($onTableAliasName);403 }404 /**405 * @param $onTableAliasName406 * @param bool $canUseFromJoins407 * @return null|string408 */409 protected function410 resolveJoinsForAttributeOnDifferentModelThatIsNotARelation($onTableAliasName, $canUseFromJoins = true)411 {412 assert('is_string($onTableAliasName)');413 assert('is_bool($canUseFromJoins)');414 if ($canUseFromJoins)415 {416 return $this->addMixedInOrCastedUpFromJoinsForAttribute($onTableAliasName);417 }418 else419 {420 return $this->addMixedInOrCastedUpLeftJoinsForAttribute($onTableAliasName);421 }422 }423 /**424 * @param $onTableAliasName425 * @return string426 */427 protected function addMixedInOrCastedUpFromJoinsForAttribute($onTableAliasName)428 {429 assert('is_string($onTableAliasName)');430 if ($this->modelAttributeToDataProviderAdapter->isAttributeMixedIn())431 {432 return $this->addFromJoinsForAttributeThatIsMixedIn($onTableAliasName);433 }434 else435 {436 return $this->addFromJoinsForAttributeThatIsCastedUp();437 }438 }439 /**440 * @param $onTableAliasName441 * @return null|string442 */443 protected function addMixedInOrCastedUpLeftJoinsForAttribute($onTableAliasName)444 {445 assert('is_string($onTableAliasName)');446 if ($this->modelAttributeToDataProviderAdapter->isAttributeMixedIn())447 {448 return $this->addLeftJoinsForAttributeThatIsMixedIn($onTableAliasName);449 }450 else451 {452 return $this->addLeftJoinsForAttributeThatIsCastedUp($onTableAliasName);453 }454 }455 /**456 * @param $onTableAliasName457 * @return string458 */459 protected function addFromJoinsForAttributeThatIsMixedIn($onTableAliasName)460 {461 assert('is_string($onTableAliasName)');462 $modelClassName = $this->modelAttributeToDataProviderAdapter->getModelClassName();463 $attributeTableName = $this->modelAttributeToDataProviderAdapter->getAttributeTableName();464 if (!$this->joinTablesAdapter->isTableInFromTables($attributeTableName))465 {466 $onTableAliasName = $this->joinTablesAdapter->addFromTableAndGetAliasName(467 $attributeTableName,468 self::resolveForeignKey($attributeTableName),469 $modelClassName::getTableName());470 }471 return $onTableAliasName;472 }473 /**474 * @return string475 */476 protected function addFromJoinsForAttributeThatIsCastedUp()477 {478 $modelClassName = $this->modelAttributeToDataProviderAdapter->getModelClassName();479 $attributeModelClassName = $this->modelAttributeToDataProviderAdapter->getAttributeModelClassName();480 return $this->processFromJoinsForAttributeThatIsCastedUp($modelClassName, $attributeModelClassName);481 }482 /**483 * @param $onTableAliasName484 * @return null|string485 */486 protected function addLeftJoinsForAttributeThatIsMixedIn($onTableAliasName)487 {488 assert('is_string($onTableAliasName)');489 $attributeTableName = $this->modelAttributeToDataProviderAdapter->getAttributeTableName();490 return $this->addLeftJoinForMixedInAttribute($onTableAliasName, $attributeTableName);491 }492 /**493 * @param $onTableAliasName494 * @param $attributeTableName495 * @return null|string496 */497 protected function addLeftJoinForMixedInAttribute($onTableAliasName, $attributeTableName)498 {499 assert('is_string($onTableAliasName)');500 assert('is_string($attributeTableName)');501 $onTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(502 $attributeTableName,503 self::resolveForeignKey($attributeTableName),504 $onTableAliasName);505 return $onTableAliasName;506 }507 /**508 * @param $onTableAliasName509 * @return null|string510 */511 protected function addLeftJoinsForAttributeThatIsCastedUp($onTableAliasName)512 {513 $modelClassName = $this->modelAttributeToDataProviderAdapter->getResolvedModelClassName();514 $attributeModelClassName = $this->modelAttributeToDataProviderAdapter->getAttributeModelClassName();515 return $this->resolveAndProcessLeftJoinsForAttributeThatIsCastedUp($onTableAliasName, $modelClassName, $attributeModelClassName);516 }517 /**518 * @param $onTableAliasName519 * @return null|string520 * @throws NotSupportedException521 */522 protected function addLeftJoinsForARelationAttribute($onTableAliasName)523 {524 assert('is_string($onTableAliasName)');525 if ($this->modelAttributeToDataProviderAdapter->getRelationType() == RedBeanModel::MANY_MANY)526 {527 return $this->resolveJoinsForForARelationAttributeThatIsManyToMany($onTableAliasName);528 }529 elseif ($this->modelAttributeToDataProviderAdapter->isRelationTypeAHasManyVariant())530 {531 $onTableAliasName = $this->resolveJoinsForForARelationAttributeThatIsAHasManyVariant($onTableAliasName);532 $this->resolveSettingDistinctForARelationAttributeThatIsHasMany();533 return $onTableAliasName;534 }535 elseif ($this->modelAttributeToDataProviderAdapter->isRelationTypeAHasOneVariant())536 {537 return $this->resolveJoinsForForARelationAttributeThatIsAHasOne($onTableAliasName);538 }539 else540 {541 throw new NotSupportedException();542 }543 }544 protected function resolveSettingDistinctForARelationAttributeThatIsHasMany()545 {546 if ($this->modelAttributeToDataProviderAdapter->getRelationType() == RedBeanModel::HAS_MANY)547 {548 $this->resolveSetToDistinct();549 }550 }551 protected function resolveSetToDistinct()552 {553 if ($this->setDistinct)554 {555 $this->joinTablesAdapter->setSelectDistinctToTrue();556 }557 }558 /**559 * @param $onTableAliasName560 * @return null|string561 */562 protected function resolveJoinsForForARelationAttributeThatIsManyToMany($onTableAliasName)563 {564 assert('is_string($onTableAliasName)');565 $relationTableName = $this->modelAttributeToDataProviderAdapter->getRelationTableName();566 $attributeTableName = $this->modelAttributeToDataProviderAdapter->getAttributeTableName();567 $relationJoiningTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(568 $this->modelAttributeToDataProviderAdapter->getManyToManyTableName(),569 "id",570 $onTableAliasName,571 self::resolveForeignKey($attributeTableName));572 //if this is not the id column, then add an additional left join.573 if ($this->modelAttributeToDataProviderAdapter->getRelatedAttribute() != 'id')574 {575 $this->resolveSetToDistinct();576 return $this->joinTablesAdapter->addLeftTableAndGetAliasName(577 $relationTableName,578 self::resolveForeignKey($relationTableName),579 $relationJoiningTableAliasName,580 'id');581 }582 else583 {584 return $relationJoiningTableAliasName;585 }586 }587 /**588 * @param $onTableAliasName589 * @return null|string590 */591 protected function resolveJoinsForForARelationAttributeThatIsAHasManyVariant($onTableAliasName)592 {593 assert('is_string($onTableAliasName)');594 $onTableJoinIdName = 'id';595 $tableJoinIdName = $this->modelAttributeToDataProviderAdapter->getColumnName();596 $onTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(597 $this->modelAttributeToDataProviderAdapter->getRelationTableName(),598 $onTableJoinIdName,599 $onTableAliasName,600 $tableJoinIdName);601 return $onTableAliasName;602 }603 /**604 * @param $onTableAliasName605 * @return null|string606 */607 protected function resolveJoinsForForARelationAttributeThatIsAHasOne($onTableAliasName)608 {609 assert('is_string($onTableAliasName)');610 $tableJoinIdName = 'id';611 $onTableJoinIdName = $this->modelAttributeToDataProviderAdapter->getColumnName();612 $onTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(613 $this->modelAttributeToDataProviderAdapter->getRelationTableName(),614 $onTableJoinIdName,615 $onTableAliasName,616 $tableJoinIdName);617 return $onTableAliasName;618 }619 /**620 * @param $modelClassName621 * @param $castedDownModelClassName622 * @param $onTableAliasName623 * @return null|string624 */625 protected function resolveAndProcessLeftJoinsForAttributeThatIsCastedDownOrUp($modelClassName,626 $castedDownModelClassName,627 $onTableAliasName)628 {629 assert('is_string($modelClassName)');630 assert('is_string($castedDownModelClassName)');631 assert('is_string($onTableAliasName)');632 $resolvedCastedDownModelClassName = $this->resolveAttributeModelClassNameWithCastingHintForCastingDown(633 $castedDownModelClassName);634 if ($modelClassName != $resolvedCastedDownModelClassName)635 {636 //If the resolvedCastedDownModelClassName is actually casted up637 $modelDerivationPathToItem = $this->resolveModelDerivationPathToItemForCastingDown(638 $modelClassName, $resolvedCastedDownModelClassName);639 if (empty($modelDerivationPathToItem))640 {641 return $this->processLeftJoinsForAttributeThatIsCastedUp($onTableAliasName, $modelClassName,642 $resolvedCastedDownModelClassName);643 }644 else645 {646 return $this->processLeftJoinsForAttributeThatIsCastedDown($modelClassName,647 $resolvedCastedDownModelClassName,648 $onTableAliasName);649 }650 }651 return $onTableAliasName;652 }653 /**654 * @param $modelClassName655 * @param $castedDownModelClassName656 * @param $onTableAliasName657 * @return null|string658 */659 protected function processLeftJoinsForAttributeThatIsCastedDown($modelClassName, $castedDownModelClassName,660 $onTableAliasName)661 {662 assert('is_string($modelClassName)');663 assert('is_string($castedDownModelClassName)');664 assert('is_string($onTableAliasName)');665 $modelDerivationPathToItem = $this->resolveModelDerivationPathToItemForCastingDown($modelClassName, $castedDownModelClassName);666 foreach ($modelDerivationPathToItem as $modelClassNameToCastDownTo)667 {668 if ($modelClassNameToCastDownTo::getCanHaveBean())669 {670 $castedDownTableName = $modelClassNameToCastDownTo::getTableName();671 $onTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(672 $castedDownTableName,673 'id',674 $onTableAliasName,675 self::resolveForeignKey($modelClassName::getTableName()));676 $modelClassName = $modelClassNameToCastDownTo;677 }678 }679 return $onTableAliasName;680 }681 /**682 * @param $modelClassName683 * @param $castedDownModelClassName684 * @return array685 */686 protected function resolveModelDerivationPathToItemForCastingDown($modelClassName, $castedDownModelClassName)687 {688 assert('is_string($modelClassName)');689 assert('is_string($castedDownModelClassName)');690 $modelDerivationPathToItem = RuntimeUtil::getModelDerivationPathToItem($castedDownModelClassName);691 if ($modelClassName == 'Item')692 {693 return $modelDerivationPathToItem;694 }695 foreach ($modelDerivationPathToItem as $key => $modelClassNameToCastDown)696 {697 unset($modelDerivationPathToItem[$key]);698 if ($modelClassName == $modelClassNameToCastDown)699 {700 break;701 }702 }703 return $modelDerivationPathToItem;704 }705 /**706 * @param $modelClassName707 * @param $castedDownModelClassName708 * @return mixed709 * @throws NotSupportedException710 */711 protected static function resolveModelClassNameThatCanHaveTable($modelClassName, $castedDownModelClassName)712 {713 assert('is_string($modelClassName)');714 assert('is_string($castedDownModelClassName)');715 if (!$modelClassName::getCanHaveBean())716 {717 if (!$castedDownModelClassName::getCanHaveBean())718 {719 throw new NotSupportedException();720 }721 return $castedDownModelClassName;722 }723 else724 {725 return $modelClassName;726 }727 }728 /**729 * @param $modelClassName730 * @param $attributeModelClassName731 * @return string732 * @throws NotSupportedException733 */734 private function processFromJoinsForAttributeThatIsCastedUp($modelClassName, $attributeModelClassName)735 {736 assert('is_string($modelClassName)');737 assert('is_string($attributeModelClassName)');738 $attributeTableName = $attributeModelClassName::getTableName();739 $tableAliasName = $attributeTableName;740 $castedDownModelClassName = $modelClassName;741 $onTableAliasName = null;742 while (get_parent_class($modelClassName) != $attributeModelClassName &&743 get_parent_class($modelClassName) != 'RedBeanModel')744 {745 $castedDownFurtherModelClassName = $castedDownModelClassName;746 $castedDownModelClassName = $modelClassName;747 $modelClassName = get_parent_class($modelClassName);748 if ($modelClassName::getCanHaveBean())749 {750 $castedUpAttributeTableName = $modelClassName::getTableName();751 if (!$this->joinTablesAdapter->isTableInFromTables($castedUpAttributeTableName))752 {753 if ($onTableAliasName == null && $castedDownModelClassName::getCanHaveBean())754 {755 $onTableAliasName = $castedDownModelClassName::getTableName();756 }757 elseif ($onTableAliasName == null && $castedDownFurtherModelClassName::getCanHaveBean())758 {759 $onTableAliasName = $castedDownFurtherModelClassName::getTableName();760 }761 elseif ($onTableAliasName == null)762 {763 throw new NotSupportedException();764 }765 $onTableAliasName = $this->joinTablesAdapter->addFromTableAndGetAliasName(766 $castedUpAttributeTableName,767 self::resolveForeignKey($castedUpAttributeTableName),768 $onTableAliasName);769 }770 }771 }772 if (!$this->joinTablesAdapter->isTableInFromTables($attributeTableName))773 {774 if ($onTableAliasName == null)775 {776 $modelClassName = static::resolveModelClassNameThatCanHaveTable($modelClassName, $castedDownModelClassName);777 $onTableAliasName = $modelClassName::getTableName();778 }779 $tableAliasName = $this->joinTablesAdapter->addFromTableAndGetAliasName(780 $attributeTableName, self::resolveForeignKey($attributeTableName), $onTableAliasName);781 }782 else783 {784 $existingTableAliasName = $this->joinTablesAdapter->getAlreadyFromJoinedTableAliasName($attributeTableName);785 if ($existingTableAliasName != null)786 {787 $tableAliasName = $existingTableAliasName;788 }789 }790 return $tableAliasName;791 }792 /**793 * @param $onTableAliasName794 * @param $modelClassName795 * @param $attributeModelClassName796 * @return null|string797 */798 private function resolveAndProcessLeftJoinsForAttributeThatIsCastedUp($onTableAliasName, $modelClassName, $attributeModelClassName)799 {800 assert('is_string($onTableAliasName)');801 assert('is_string($modelClassName)');802 assert('is_string($attributeModelClassName)');803 if ($modelClassName == $attributeModelClassName)804 {805 return $onTableAliasName;806 }807 return $this->processLeftJoinsForAttributeThatIsCastedUp($onTableAliasName, $modelClassName, $attributeModelClassName);808 }809 /**810 * @param $onTableAliasName811 * @param $modelClassName812 * @param $attributeModelClassName813 * @return null|string814 * @throws NotSupportedException815 */816 private function processLeftJoinsForAttributeThatIsCastedUp($onTableAliasName, $modelClassName, $attributeModelClassName)817 {818 assert('is_string($onTableAliasName)');819 assert('is_string($modelClassName)');820 assert('is_string($attributeModelClassName)');821 $attributeTableName = $attributeModelClassName::getTableName();822 $castedDownModelClassName = $modelClassName;823 while (get_parent_class($modelClassName) != $attributeModelClassName &&824 get_parent_class($modelClassName) != 'RedBeanModel')825 {826 $castedDownFurtherModelClassName = $castedDownModelClassName;827 $castedDownModelClassName = $modelClassName;828 $modelClassName = get_parent_class($modelClassName);829 if ($modelClassName::getCanHaveBean())830 {831 $castedUpAttributeTableName = $modelClassName::getTableName();832 /**833 if ($castedDownModelClassName::getCanHaveBean())834 {835 $resolvedTableJoinIdName = $castedDownModelClassName::getTableName();836 }837 elseif ($castedDownFurtherModelClassName::getCanHaveBean())838 {839 $resolvedTableJoinIdName = $castedDownFurtherModelClassName::getTableName();840 }841 else842 {843 throw new NotSupportedException();844 }845 * */846 $onTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(847 $castedUpAttributeTableName,848 self::resolveForeignKey($castedUpAttributeTableName),849 $onTableAliasName);//,850 //$resolvedTableJoinIdName);851 }852 }853 //Add left table if it is not already added854 $modelClassName = static::resolveModelClassNameThatCanHaveTable($modelClassName, $castedDownModelClassName);855 $onTableAliasName = $this->joinTablesAdapter->addLeftTableAndGetAliasName(856 $attributeTableName,857 self::resolveForeignKey($attributeTableName),858 $onTableAliasName); //,859 //$modelClassName::getTableName());860 return $onTableAliasName;861 }862 /**863 * @return mixed864 */865 private function resolveOnTableAliasNameForDerivedRelationViaCastedUpModel()866 {867 if ($this->modelAttributeToDataProviderAdapter->isAttributeDerivedRelationViaCastedUpModel())868 {869 $onTableAliasName = $this->modelAttributeToDataProviderAdapter->getModelTableName();870 }871 else872 {873 $onTableAliasName = $this->modelAttributeToDataProviderAdapter->getAttributeTableName();874 }875 return $onTableAliasName;876 }877 }878?>...

Full Screen

Full Screen

ModelMetadataUtil.php

Source:ModelMetadataUtil.php Github

copy

Full Screen

1<?php2 /*********************************************************************************3 * Zurmo is a customer relationship management program developed by4 * Zurmo, Inc. Copyright (C) 2014 Zurmo Inc.5 *6 * Zurmo is free software; you can redistribute it and/or modify it under7 * the terms of the GNU Affero General Public License version 3 as published by the8 * Free Software Foundation with the addition of the following permission added9 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK10 * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY11 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.12 *13 * Zurmo is distributed in the hope that it will be useful, but WITHOUT14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS15 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more16 * details.17 *18 * You should have received a copy of the GNU Affero General Public License along with19 * this program; if not, see http://www.gnu.org/licenses or write to the Free20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA21 * 02110-1301 USA.22 *23 * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive24 * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.25 *26 * The interactive user interfaces in original and modified versions27 * of this program must display Appropriate Legal Notices, as required under28 * Section 5 of the GNU Affero General Public License version 3.29 *30 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,31 * these Appropriate Legal Notices must retain the display of the Zurmo32 * logo and Zurmo copyright notice. If the display of the logo is not reasonably33 * feasible for technical reasons, the Appropriate Legal Notices must display the words34 * "Copyright Zurmo Inc. 2014. All rights reserved".35 ********************************************************************************/36 /**37 * Helper functionality for use in manipulating model metadata.38 */39 class ModelMetadataUtil40 {41 /**42 * @param $name43 * @return string44 */45 public static function resolveName($name)46 {47 assert('is_string($name)');48 return $name . 'Cstm'; // . 'Custom';49 }50 /**51 * @param string $modelClassName52 * @param string $memberName53 * @param array $attributeLabels54 * @param $defaultValue55 * @param int $maxLength56 * @param int $minValue57 * @param int $maxValue58 * @param int $precision59 * @param bool $isRequired60 * @param bool $isAudited61 * @param string $elementType62 * @param array $partialTypeRule63 * @param array $mixedRule64 */65 public static function addOrUpdateMember($modelClassName,66 $memberName,67 $attributeLabels,68 $defaultValue,69 $maxLength,70 $minValue,71 $maxValue,72 $precision,73 $isRequired,74 $isAudited,75 $elementType,76 array $partialTypeRule,77 array $mixedRule = null)78 {79 assert('is_string($modelClassName) && $modelClassName != ""');80 assert('is_string($memberName) && $memberName != ""');81 assert('is_array($attributeLabels)');82 assert('$defaultValue === null || $defaultValue !== ""');83 assert('$maxLength === null || is_int($maxLength)');84 assert('$precision === null || is_int($precision)');85 assert('is_bool($isRequired)');86 assert('is_bool($isAudited)');87 assert('$mixedRule === null || is_array($mixedRule)');88 $metadata = $modelClassName::getMetadata();89 assert('isset($metadata[$modelClassName])');90 if (!isset($metadata[$modelClassName]['members']) ||91 !in_array($memberName, $metadata[$modelClassName]['members']))92 {93 $memberName = self::resolveName($memberName);94 $metadata[$modelClassName]['members'][] = $memberName;95 }96 if (!ArrayUtil::isArrayNotUnique($metadata[$modelClassName]['members']))97 {98 throw new NotSupportedException("Model metadata contains duplicate members");99 }100 static::resolveAddOrRemoveNoAuditInformation($isAudited, $metadata[$modelClassName], $memberName);101 $metadata[$modelClassName]['elements'][$memberName] = $elementType;102 self::resolveAttributeLabelsMetadata($attributeLabels, $metadata, $modelClassName, $memberName);103 self::addOrUpdateRules($modelClassName, $memberName, $defaultValue, $maxLength,104 $minValue, $maxValue, $precision, $isRequired, $partialTypeRule,105 $metadata, $mixedRule);106 $modelClassName::setMetadata($metadata);107 }108 /**109 * Updating existing relation attributes and add new has_one relations that are owned only.110 * Currently does not support setting the default value.111 * @param string $modelClassName112 * @param string $relationName113 * @param array $attributeLabels114 * @param string $elementType115 * @param bool $isRequired116 * @param bool $isAudited117 * @param string $relationModelClassName118 */119 public static function addOrUpdateRelation($modelClassName,120 $relationName,121 $attributeLabels,122 $elementType,123 $isRequired,124 $isAudited,125 $relationModelClassName)126 {127 assert('is_string($modelClassName) && $modelClassName != ""');128 assert('is_string($relationName) && $relationName != ""');129 assert('is_array($attributeLabels)');130 assert('is_string($elementType) && $elementType != ""');131 assert('is_bool($isRequired)');132 assert('is_bool($isAudited)');133 assert('is_string($relationModelClassName) && $relationModelClassName != ""');134 $metadata = $modelClassName::getMetadata();135 assert('isset($metadata[$modelClassName])');136 if (!isset ( $metadata[$modelClassName]['relations']) ||137 !array_key_exists($relationName, $metadata[$modelClassName]['relations']))138 {139 //assumes HAS_ONE for now and RedBeanModel::OWNED.140 $relationName = self::resolveName($relationName);141 $metadata[$modelClassName]['relations'][$relationName] = array(142 RedBeanModel::HAS_ONE,143 $relationModelClassName,144 RedBeanModel::OWNED,145 RedBeanModel::LINK_TYPE_SPECIFIC,146 $relationName);147 }148 static::resolveAddOrRemoveNoAuditInformation($isAudited, $metadata[$modelClassName], $relationName);149 $metadata[$modelClassName]['elements'][$relationName] = $elementType;150 self::resolveAttributeLabelsMetadata($attributeLabels, $metadata, $modelClassName, $relationName);151 self::addOrUpdateRules($modelClassName, $relationName, null, null, null,152 null, null, $isRequired, array(), $metadata);153 $modelClassName::setMetadata($metadata);154 }155 /**156 * @param string $modelClassName157 * @param string $relationName158 * @param array $attributeLabels159 * @param $defaultValue160 * @param bool $isRequired161 * @param bool $isAudited162 * @param string $elementType163 * @param string $customFieldDataName164 * @param null $customFieldDataData165 * @param null $customFieldDataLabels166 * @param string $relationModelClassName167 * @param bool $owned168 * @throws NotSupportedException169 */170 public static function addOrUpdateCustomFieldRelation($modelClassName,171 $relationName,172 $attributeLabels,173 $defaultValue,174 $isRequired,175 $isAudited,176 $elementType,177 $customFieldDataName,178 $customFieldDataData = null,179 $customFieldDataLabels = null,180 $relationModelClassName = 'OwnedCustomField',181 $owned = true)182 {183 assert('is_string($modelClassName) && $modelClassName != ""');184 assert('is_string($relationName) && $relationName != ""');185 assert('is_array($attributeLabels)');186 assert('is_bool($isRequired)');187 assert('is_bool($isAudited)');188 assert('is_string($customFieldDataName) && $customFieldDataName != ""');189 assert('is_array($customFieldDataLabels) || $customFieldDataLabels == null');190 assert('in_array($relationModelClassName, array("CustomField", "OwnedCustomField",191 "OwnedMultipleValuesCustomField", "MultipleValuesCustomField"))');192 $metadata = $modelClassName::getMetadata();193 assert('isset($metadata[$modelClassName])');194 if ($owned)195 {196 if (!in_array($relationModelClassName, array("OwnedCustomField", "OwnedMultipleValuesCustomField")))197 {198 throw new NotSupportedException();199 }200 }201 else202 {203 if (!in_array($relationModelClassName, array("CustomField", "MultipleValuesCustomField")))204 {205 throw new NotSupportedException();206 }207 }208 if (!isset ( $metadata[$modelClassName]['relations']) ||209 !array_key_exists($relationName, $metadata[$modelClassName]['relations']))210 {211 $relationName = self::resolveName($relationName);212 $metadata[$modelClassName]['relations'][$relationName] = array(RedBeanModel::HAS_ONE,213 $relationModelClassName);214 if ($owned)215 {216 $metadata[$modelClassName]['relations'][$relationName][2] = RedBeanModel::OWNED;217 }218 else219 {220 $metadata[$modelClassName]['relations'][$relationName][2] = RedBeanModel::NOT_OWNED;221 }222 $metadata[$modelClassName]['relations'][$relationName][3] = RedBeanModel::LINK_TYPE_SPECIFIC;223 $metadata[$modelClassName]['relations'][$relationName][4] = $relationName;224 }225 $metadata[$modelClassName]['elements'][$relationName] = $elementType;226 self::resolveAttributeLabelsMetadata($attributeLabels, $metadata, $modelClassName, $relationName);227 if (!isset ( $metadata[$modelClassName]['customFields']) ||228 !array_key_exists($relationName, $metadata[$modelClassName]['customFields']))229 {230 $metadata[$modelClassName]['customFields'][$relationName] = $customFieldDataName;231 }232 static::resolveAddOrRemoveNoAuditInformation($isAudited, $metadata[$modelClassName], $relationName);233 if ($customFieldDataData !== null)234 {235 $customFieldData = CustomFieldData::getByName($customFieldDataName);236 $customFieldData->serializedData = serialize($customFieldDataData);237 if ($customFieldDataLabels !== null)238 {239 $customFieldData->serializedLabels = serialize($customFieldDataLabels);240 }241 $saved = $customFieldData->save();242 assert('$saved');243 }244 elseif ($customFieldDataLabels !== null)245 {246 throw new NotSupportedException();247 }248 self::addOrUpdateRules($modelClassName, $relationName, $defaultValue, null, null,249 null, null, $isRequired, array(), $metadata);250 $modelClassName::setMetadata($metadata);251 }252 private static function addOrUpdateRules($modelClassName,253 $attributeName,254 $defaultValue,255 $maxLength,256 $minValue,257 $maxValue,258 $precision,259 $isRequired,260 array $partialTypeRule,261 &$metadata,262 array $mixedRule = null)263 {264 assert('is_string($modelClassName) && $modelClassName != ""');265 assert('is_string($attributeName) && $attributeName != ""');266 assert('$maxLength === null || is_int($maxLength)');267 assert('is_bool($isRequired)');268 assert('isset($metadata[$modelClassName])');269 assert('$mixedRule === null || is_array($mixedRule)');270 $defaultFound = false;271 $lengthFound = false;272 $numericalFound = false;273 $requiredFound = false;274 $typeRuleFound = false;275 $mixedRuleFound = false;276 if (isset($metadata[$modelClassName]['rules']))277 {278 $i = 0;279 while ($i < count($metadata[$modelClassName]['rules']))280 {281 $rule = $metadata[$modelClassName]['rules'][$i];282 if ($rule[0] == $attributeName)283 {284 switch ($rule[1])285 {286 case 'default':287 if ($defaultValue !== null)288 {289 $metadata[$modelClassName]['rules'][$i]['value'] = $defaultValue;290 }291 else292 {293 unset($metadata[$modelClassName]['rules'][$i]);294 }295 $defaultFound = true;296 break;297 case 'length':298 if ($maxLength !== null)299 {300 $metadata[$modelClassName]['rules'][$i]['max'] = $maxLength;301 }302 $lengthFound = true;303 break;304 case 'numerical':305 if ($minValue !== null)306 {307 $metadata[$modelClassName]['rules'][$i]['min'] = $minValue;308 }309 if ($maxValue !== null)310 {311 $metadata[$modelClassName]['rules'][$i]['max'] = $maxValue;312 }313 if ($precision !== null)314 {315 $metadata[$modelClassName]['rules'][$i]['precision'] = $precision;316 }317 $numericalFound = true;318 break;319 case 'required':320 if (!$isRequired)321 {322 unset($metadata[$modelClassName]['rules'][$i]);323 }324 $requiredFound = true;325 continue;326 }327 if (count($partialTypeRule) > 0 && $rule[1] == $partialTypeRule[0])328 {329 if (count($partialTypeRule) > 1)330 {331 $typeRule = $partialTypeRule;332 array_unshift($typeRule, $attributeName);333 $metadata[$modelClassName]['rules'][$i] = $typeRule;334 }335 $typeRuleFound = true;336 }337 if (count($mixedRule) > 0 && $rule[1] == $mixedRule[0])338 {339 $mixedRuleToUpdate = $mixedRule;340 array_unshift($mixedRuleToUpdate, $attributeName);341 $metadata[$modelClassName]['rules'][$i] = $mixedRuleToUpdate;342 $mixedRuleFound = true;343 }344 }345 $i++;346 }347 }348 if (!$defaultFound && $defaultValue !== null)349 {350 $metadata[$modelClassName]['rules'][] = array($attributeName, 'default', 'value' => $defaultValue);351 }352 if (!$lengthFound && $maxLength !== null)353 {354 $metadata[$modelClassName]['rules'][] = array($attributeName, 'length', 'max' => $maxLength);355 }356 if (!$numericalFound && ($minValue !== null || $maxValue !== null || $precision !== null))357 {358 $rule = array($attributeName, 'numerical');359 if ($minValue !== null)360 {361 $rule['min'] = $minValue;362 }363 if ($maxValue !== null)364 {365 $rule['max'] = $maxValue;366 }367 if ($precision !== null)368 {369 $rule['precision'] = $precision;370 }371 $metadata[$modelClassName]['rules'][] = $rule;372 }373 if (!$requiredFound && $isRequired)374 {375 $metadata[$modelClassName]['rules'][] = array($attributeName, 'required');376 }377 if (!$typeRuleFound && count($partialTypeRule) > 0)378 {379 $typeRule = $partialTypeRule;380 array_unshift($typeRule, $attributeName);381 $metadata[$modelClassName]['rules'][] = $typeRule;382 }383 if (!$mixedRuleFound && count($mixedRule) > 0)384 {385 $mixedRuleToAdd = $mixedRule;386 array_unshift($mixedRuleToAdd, $attributeName);387 $metadata[$modelClassName]['rules'][] = $mixedRuleToAdd;388 }389 // Fix indexes.390 $metadata[$modelClassName]['rules'] = array_values($metadata[$modelClassName]['rules']);391 }392 /**393 * @param $modelClassName394 * @param $attributeName395 */396 public static function removeAttribute($modelClassName,397 $attributeName)398 {399 $metadata = $modelClassName::getMetadata();400 if (isset($metadata[$modelClassName]['members']))401 {402 $i = array_search($attributeName, $metadata[$modelClassName]['members']);403 if ($i !== false)404 {405 unset($metadata[$modelClassName]['members'][$i]);406 // Fix indexes.407 $metadata[$modelClassName]['members'] =408 array_values($metadata[$modelClassName]['members']);409 }410 }411 if (isset($metadata[$modelClassName]['relations']))412 {413 unset($metadata[$modelClassName]['relations'][$attributeName]);414 }415 if (isset($metadata[$modelClassName]['noAudit']))416 {417 unset($metadata[$modelClassName]['noAudit'][$attributeName]);418 }419 $i = 0;420 while ($i < count($metadata[$modelClassName]['rules']))421 {422 $rule = $metadata[$modelClassName]['rules'][$i];423 if ($rule[0] == $attributeName)424 {425 unset($metadata[$modelClassName]['rules'][$i]);426 // Fix indexes.427 $metadata[$modelClassName]['rules'] = array_values($metadata[$modelClassName]['rules']);428 continue;429 }430 $i++;431 }432 $modelClassName::setMetadata($metadata);433 }434 protected static function resolveAddOrRemoveNoAuditInformation($isAudited, & $modelMetadata, $attributeName)435 {436 assert('is_bool($isAudited)');437 assert('is_array($modelMetadata)');438 assert('is_string($attributeName)');439 if (!$isAudited)440 {441 if (!isset($modelMetadata['noAudit']) || !in_array($attributeName, $modelMetadata['noAudit']))442 {443 $modelMetadata['noAudit'][] = $attributeName;444 }445 }446 else447 {448 if (isset($modelMetadata['noAudit']) && in_array($attributeName, $modelMetadata['noAudit']))449 {450 $key = array_search($attributeName, $modelMetadata['noAudit']);451 unset($modelMetadata['noAudit'][$key]);452 $modelMetadata['noAudit'] = array_values($modelMetadata['noAudit']);453 }454 }455 }456 /**457 * Given an array of attributeLabels, resolve that array into any existing attributeLabels in the metadata.458 * This is needed in case a language has been inactivated for example, we do not want to lose the translation.459 * @param array $attributeLabels460 * @param array $metadata461 * @param string $modelClassName462 * @param string $labelsAttributeName463 */464 protected static function resolveAttributeLabelsMetadata($attributeLabels, & $metadata,465 $modelClassName, $labelsAttributeName)466 {467 assert('is_array($attributeLabels)');468 assert('is_array($metadata)');469 assert('is_string($modelClassName)');470 assert('is_string($labelsAttributeName)');471 if (!isset($metadata[$modelClassName]['labels'][$labelsAttributeName]))472 {473 $metadata[$modelClassName]['labels'][$labelsAttributeName] = array();474 }475 $metadata[$modelClassName]['labels'][$labelsAttributeName] =476 array_merge($metadata[$modelClassName]['labels'][$labelsAttributeName], $attributeLabels);477 }478 }479?>...

Full Screen

Full Screen

RedBeanModelSelectQueryAdapter.php

Source:RedBeanModelSelectQueryAdapter.php Github

copy

Full Screen

1<?php2 /*********************************************************************************3 * Zurmo is a customer relationship management program developed by4 * Zurmo, Inc. Copyright (C) 2014 Zurmo Inc.5 *6 * Zurmo is free software; you can redistribute it and/or modify it under7 * the terms of the GNU Affero General Public License version 3 as published by the8 * Free Software Foundation with the addition of the following permission added9 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK10 * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY11 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.12 *13 * Zurmo is distributed in the hope that it will be useful, but WITHOUT14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS15 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more16 * details.17 *18 * You should have received a copy of the GNU Affero General Public License along with19 * this program; if not, see http://www.gnu.org/licenses or write to the Free20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA21 * 02110-1301 USA.22 *23 * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive24 * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.25 *26 * The interactive user interfaces in original and modified versions27 * of this program must display Appropriate Legal Notices, as required under28 * Section 5 of the GNU Affero General Public License version 3.29 *30 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,31 * these Appropriate Legal Notices must retain the display of the Zurmo32 * logo and Zurmo copyright notice. If the display of the logo is not reasonably33 * feasible for technical reasons, the Appropriate Legal Notices must display the words34 * "Copyright Zurmo Inc. 2014. All rights reserved".35 ********************************************************************************/36 /**37 * Adapts select information into query parts for a particular sql query. Automatically determines count,38 * distinct, sums, columns and aliases.39 */40 class RedBeanModelSelectQueryAdapter41 {42 /**43 * Array of select clauses44 * @var array45 */46 private $clauses;47 /**48 * Set to true if the select query needs to be distinct49 * with the same id.50 * @var boolean51 */52 private $distinct = false;53 /**54 * Count of select clauses55 * @var integer56 */57 private $clausesCount = 0;58 private $countClausePresent = false;59 private $idTableAliasesAndModelClassNames = array();60 public static function makeCountString($tableName, $columnName, $distinctPart = null)61 {62 assert('is_string($tableName)');63 assert('is_string($columnName)');64 assert('is_string($distinctPart) || $distinctPart == null');65 $quote = DatabaseCompatibilityUtil::getQuote();66 $queryString = "{$distinctPart}{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";67 return "count({$queryString})";68 }69 public static function makeSummationString($tableName, $columnName, $queryStringExtraPart = null)70 {71 assert('is_string($tableName)');72 assert('is_string($columnName)');73 assert('is_string($queryStringExtraPart) || $queryStringExtraPart == null');74 $quote = DatabaseCompatibilityUtil::getQuote();75 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}" . $queryStringExtraPart;76 return "sum({$queryString})";77 }78 public static function makeAverageString($tableName, $columnName, $queryStringExtraPart = null)79 {80 assert('is_string($tableName)');81 assert('is_string($columnName)');82 assert('is_string($queryStringExtraPart) || $queryStringExtraPart == null');83 $quote = DatabaseCompatibilityUtil::getQuote();84 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}" . $queryStringExtraPart;85 return "avg({$queryString})";86 }87 public static function makeMinimumString($tableName, $columnName, $queryStringExtraPart = null)88 {89 assert('is_string($tableName)');90 assert('is_string($columnName)');91 assert('is_string($queryStringExtraPart) || $queryStringExtraPart == null');92 $quote = DatabaseCompatibilityUtil::getQuote();93 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}" . $queryStringExtraPart;94 return "min({$queryString})";95 }96 public static function makeMaximumString($tableName, $columnName, $queryStringExtraPart = null)97 {98 assert('is_string($tableName)');99 assert('is_string($columnName)');100 assert('is_string($queryStringExtraPart) || $queryStringExtraPart == null');101 $quote = DatabaseCompatibilityUtil::getQuote();102 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}" . $queryStringExtraPart;103 return "max({$queryString})";104 }105 public static function makeDayModifierString($tableName, $columnName, $adjustForTimeZone = false)106 {107 assert('is_string($tableName)');108 assert('is_string($columnName)');109 assert('is_bool($adjustForTimeZone)');110 $quote = DatabaseCompatibilityUtil::getQuote();111 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";112 if ($adjustForTimeZone)113 {114 $queryString .= DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();115 }116 return "day({$queryString})";117 }118 public static function makeDayDateModifierString($tableName, $columnName, $adjustForTimeZone = false)119 {120 assert('is_string($tableName)');121 assert('is_string($columnName)');122 assert('is_bool($adjustForTimeZone)');123 $quote = DatabaseCompatibilityUtil::getQuote();124 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";125 if ($adjustForTimeZone)126 {127 $queryString .= DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();128 }129 return "DATE_FORMAT({$queryString}, '%Y-%m-%d')";130 }131 public static function makeWeekModifierString($tableName, $columnName, $adjustForTimeZone = false)132 {133 assert('is_string($tableName)');134 assert('is_string($columnName)');135 assert('is_bool($adjustForTimeZone)');136 $quote = DatabaseCompatibilityUtil::getQuote();137 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";138 if ($adjustForTimeZone)139 {140 $queryString .= DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();141 }142 return "week({$queryString})";143 }144 public static function makeFirstDayOfWeekDateModifierString($tableName, $columnName, $adjustForTimeZone = false)145 {146 assert('is_string($tableName)');147 assert('is_string($columnName)');148 assert('is_bool($adjustForTimeZone)');149 $quote = DatabaseCompatibilityUtil::getQuote();150 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";151 if ($adjustForTimeZone)152 {153 $queryString .= DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();154 }155 return "DATE_FORMAT(DATE_SUB({$queryString}, INTERVAL(WEEKDAY(" .156 "{$queryString})) day), '%Y-%m-%d')";157 }158 public static function makeMonthModifierString($tableName, $columnName, $adjustForTimeZone = false)159 {160 assert('is_string($tableName)');161 assert('is_string($columnName)');162 assert('is_bool($adjustForTimeZone)');163 $quote = DatabaseCompatibilityUtil::getQuote();164 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";165 if ($adjustForTimeZone)166 {167 $queryString .= DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();168 }169 return "month({$queryString})";170 }171 public static function makeFirstDayOfMonthDateModifierString($tableName, $columnName, $adjustForTimeZone = false)172 {173 assert('is_string($tableName)');174 assert('is_string($columnName)');175 assert('is_bool($adjustForTimeZone)');176 $quote = DatabaseCompatibilityUtil::getQuote();177 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";178 if ($adjustForTimeZone)179 {180 $queryString .= DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();181 }182 return $queryString = "DATE_FORMAT(DATE_ADD({$queryString}, INTERVAL(1-DAYOFMONTH(" .183 "{$queryString})) day), '%Y-%m-%d')";184 }185 public static function makeQuarterModifierString($tableName, $columnName, $adjustForTimeZone = false)186 {187 assert('is_string($tableName)');188 assert('is_string($columnName)');189 assert('is_bool($adjustForTimeZone)');190 $quote = DatabaseCompatibilityUtil::getQuote();191 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";192 if ($adjustForTimeZone)193 {194 $queryString .= DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();195 }196 return "quarter({$queryString})";197 }198 public static function makeYearModifierString($tableName, $columnName, $adjustForTimeZone = false)199 {200 assert('is_string($tableName)');201 assert('is_string($columnName)');202 assert('is_bool($adjustForTimeZone)');203 $quote = DatabaseCompatibilityUtil::getQuote();204 $queryString = "{$quote}$tableName{$quote}.{$quote}$columnName{$quote}";205 if ($adjustForTimeZone)206 {207 $queryString .= DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();208 }209 return "year({$queryString})";210 }211 public function __construct($distinct = false)212 {213 $this->distinct = $distinct;214 }215 protected function increaseClausesCountByOne()216 {217 $this->clausesCount++;218 }219 public function isDistinct()220 {221 return $this->distinct;222 }223 public function getClausesCount()224 {225 return $this->clausesCount;226 }227 public function getClauses()228 {229 return $this->clauses;230 }231 public function getIdTableAliasesAndModelClassNames()232 {233 return $this->idTableAliasesAndModelClassNames;234 }235 public function getIdColumNameByTableAlias($tableAliasName)236 {237 assert('is_string($tableAliasName)');238 return $tableAliasName . 'id';239 }240 public function getSelect()241 {242 if ($this->getClausesCount() == 0)243 {244 throw new NotSupportedException();245 }246 $selectQuery = 'select ';247 if ($this->distinct && !$this->countClausePresent)248 {249 $selectQuery .= 'distinct ';250 }251 foreach ($this->clauses as $clauseCount => $clause)252 {253 $selectQuery .= $clause;254 if ($this->getClausesCount() > 1 && ($clauseCount + 1) < $this->getClausesCount())255 {256 $selectQuery .= ','; // Not Coding Standard257 }258 $selectQuery .= ' ';259 }260 return $selectQuery;261 }262 public function addNonSpecificCountClause()263 {264 $this->clauses[] = "count(*)";265 $this->countClausePresent = true;266 $this->increaseClausesCountByOne();267 }268 public function addCountClause($tableName, $columnName = 'id', $aliasName = null)269 {270 assert('is_string($tableName)');271 assert('is_string($columnName)');272 assert('is_string($aliasName) || $aliasName == null');273 $quote = DatabaseCompatibilityUtil::getQuote();274 $distinctPart = null;275 if ($this->distinct)276 {277 $distinctPart = 'distinct ';278 }279 $queryString = self::makeCountString($tableName, $columnName, $distinctPart);280 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);281 $this->countClausePresent = true;282 $this->increaseClausesCountByOne();283 }284 public function addClause($tableName, $columnName, $aliasName = null)285 {286 assert('is_string($tableName)');287 assert('is_string($columnName)');288 assert('is_string($aliasName) || $aliasName == null');289 $quote = DatabaseCompatibilityUtil::getQuote();290 $this->clauses[] = self::resolveForAliasName("{$quote}$tableName{$quote}.{$quote}$columnName{$quote}", $aliasName);291 $this->increaseClausesCountByOne();292 }293 public function addClauseByQueryString($queryString, $aliasName = null)294 {295 assert('is_string($queryString)');296 assert('is_string($aliasName) || $aliasName == null');297 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);298 $this->increaseClausesCountByOne();299 }300 public function addClauseWithColumnNameOnlyAndNoEnclosure($columnName, $aliasName = null)301 {302 assert('is_string($columnName)');303 assert('is_string($aliasName) || $aliasName == null');304 $clause = "$columnName";305 if ($aliasName != null)306 {307 $clause .= " $aliasName";308 }309 $this->clauses[] = self::resolveForAliasName("$columnName", $aliasName);310 $this->increaseClausesCountByOne();311 }312 public function addSummationClause($tableName, $columnName, $aliasName = null, $queryStringExtraPart = null)313 {314 assert('is_string($tableName)');315 assert('is_string($columnName)');316 assert('is_string($aliasName) || $aliasName == null');317 assert('is_string($queryStringExtraPart) || $queryStringExtraPart == null');318 $queryString = self::makeSummationString($tableName, $columnName, $queryStringExtraPart);319 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);320 $this->increaseClausesCountByOne();321 }322 public function addAverageClause($tableName, $columnName, $aliasName = null, $queryStringExtraPart = null)323 {324 assert('is_string($tableName)');325 assert('is_string($columnName)');326 assert('is_string($aliasName) || $aliasName == null');327 assert('is_string($queryStringExtraPart) || $queryStringExtraPart == null');328 $queryString = self::makeAverageString($tableName, $columnName, $queryStringExtraPart);329 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);330 $this->increaseClausesCountByOne();331 }332 public function addMinimumClause($tableName, $columnName, $aliasName = null, $queryStringExtraPart = null)333 {334 assert('is_string($tableName)');335 assert('is_string($columnName)');336 assert('is_string($aliasName) || $aliasName == null');337 assert('is_string($queryStringExtraPart) || $queryStringExtraPart == null');338 $queryString = self::makeMinimumString($tableName, $columnName, $queryStringExtraPart);339 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);340 $this->increaseClausesCountByOne();341 }342 public function addMaximumClause($tableName, $columnName, $aliasName = null, $queryStringExtraPart = null)343 {344 assert('is_string($tableName)');345 assert('is_string($columnName)');346 assert('is_string($aliasName) || $aliasName == null');347 assert('is_string($queryStringExtraPart) || $queryStringExtraPart == null');348 $queryString = self::makeMaximumString($tableName, $columnName, $queryStringExtraPart);349 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);350 $this->increaseClausesCountByOne();351 }352 public function addDayClause($tableName, $columnName, $aliasName = null, $adjustForTimeZone = false)353 {354 assert('is_string($tableName)');355 assert('is_string($columnName)');356 assert('is_string($aliasName) || $aliasName == null');357 assert('is_bool($adjustForTimeZone)');358 $queryString = self::makeDayModifierString($tableName, $columnName, $adjustForTimeZone);359 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);360 $this->increaseClausesCountByOne();361 }362 public function addDayDateClause($tableName, $columnName, $aliasName = null, $adjustForTimeZone = false)363 {364 assert('is_string($tableName)');365 assert('is_string($columnName)');366 assert('is_string($aliasName) || $aliasName == null');367 assert('is_bool($adjustForTimeZone)');368 $queryString = self::makeDayDateModifierString($tableName, $columnName, $adjustForTimeZone);369 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);370 $this->increaseClausesCountByOne();371 }372 public function addWeekClause($tableName, $columnName, $aliasName = null, $adjustForTimeZone = false)373 {374 assert('is_string($tableName)');375 assert('is_string($columnName)');376 assert('is_string($aliasName) || $aliasName == null');377 assert('is_bool($adjustForTimeZone)');378 $queryString = self::makeWeekModifierString($tableName, $columnName, $adjustForTimeZone);379 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);380 $this->increaseClausesCountByOne();381 }382 public function addFirstDayOfWeekDateClause($tableName, $columnName, $aliasName = null, $adjustForTimeZone = false)383 {384 assert('is_string($tableName)');385 assert('is_string($columnName)');386 assert('is_string($aliasName) || $aliasName == null');387 assert('is_bool($adjustForTimeZone)');388 $queryString = self::makeFirstDayOfWeekDateModifierString($tableName, $columnName, $adjustForTimeZone);389 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);390 $this->increaseClausesCountByOne();391 }392 public function addMonthClause($tableName, $columnName, $aliasName = null, $adjustForTimeZone = false)393 {394 assert('is_string($tableName)');395 assert('is_string($columnName)');396 assert('is_string($aliasName) || $aliasName == null');397 assert('is_bool($adjustForTimeZone)');398 $queryString = self::makeMonthModifierString($tableName, $columnName, $adjustForTimeZone);399 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);400 $this->increaseClausesCountByOne();401 }402 public function addFirstDayOfMonthDateClause($tableName, $columnName, $aliasName = null, $adjustForTimeZone = false)403 {404 assert('is_string($tableName)');405 assert('is_string($columnName)');406 assert('is_string($aliasName) || $aliasName == null');407 assert('is_bool($adjustForTimeZone)');408 $queryString = self::makeFirstDayOfMonthDateModifierString($tableName, $columnName, $adjustForTimeZone);409 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);410 $this->increaseClausesCountByOne();411 }412 public function addQuarterClause($tableName, $columnName, $aliasName = null, $adjustForTimeZone = false)413 {414 assert('is_string($tableName)');415 assert('is_string($columnName)');416 assert('is_string($aliasName) || $aliasName == null');417 assert('is_bool($adjustForTimeZone)');418 $queryString = self::makeQuarterModifierString($tableName, $columnName, $adjustForTimeZone);419 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);420 $this->increaseClausesCountByOne();421 }422 public function addYearClause($tableName, $columnName, $aliasName = null, $adjustForTimeZone = false)423 {424 assert('is_string($tableName)');425 assert('is_string($columnName)');426 assert('is_string($aliasName) || $aliasName == null');427 assert('is_bool($adjustForTimeZone)');428 $queryString = self::makeYearModifierString($tableName, $columnName, $adjustForTimeZone);429 $this->clauses[] = self::resolveForAliasName($queryString, $aliasName);430 $this->increaseClausesCountByOne();431 }432 public function resolveIdClause($modelClassName, $tableAliasName)433 {434 assert('is_string($modelClassName)');435 assert('is_string($tableAliasName)');436 if (!isset($this->idTableAliasesAndModelClassNames[$tableAliasName]))437 {438 $this->idTableAliasesAndModelClassNames[$tableAliasName] = $modelClassName;439 $this->addClause($tableAliasName, 'id', $tableAliasName . 'id');440 }441 }442 public static function resolveForAliasName($clause, $aliasName = null)443 {444 assert('is_string($clause)');445 assert('is_string($aliasName) || $aliasName == null');446 if ($aliasName != null)447 {448 $clause .= " $aliasName";449 }450 return $clause;451 }452 }453?>...

Full Screen

Full Screen

is

Using AI Code Generation

copy

Full Screen

1$obj = new name;2$obj->method();3$obj = new name;4$obj->method();5$obj = new name;6$obj->method();7$obj = new name;8$obj->method();9$obj = new name;10$obj->method();11$obj = new name;12$obj->method();13$obj = new name;14$obj->method();15$obj = new name;16$obj->method();17$obj = new name;18$obj->method();19$obj = new name;20$obj->method();21$obj = new name;22$obj->method();23$obj = new name;24$obj->method();25$obj = new name;26$obj->method();27$obj = new name;28$obj->method();29$obj = new name;30$obj->method();31$obj = new name;32$obj->method();33$obj = new name;34$obj->method();35$obj = new name;36$obj->method();37$obj = new name;38$obj->method();

Full Screen

Full Screen

is

Using AI Code Generation

copy

Full Screen

1$obj = new ClassName();2$obj->methodName();3$obj = new ClassName();4$obj->methodName();5$obj = new ClassName();6$obj->methodName();7$obj = new ClassName();8$obj->methodName();9$obj = new ClassName();10$obj->methodName();11$obj = new ClassName();12$obj->methodName();13$obj = new ClassName();14$obj->methodName();15$obj = new ClassName();16$obj->methodName();17$obj = new ClassName();18$obj->methodName();19$obj = new ClassName();20$obj->methodName();21$obj = new ClassName();22$obj->methodName();23$obj = new ClassName();24$obj->methodName();25$obj = new ClassName();26$obj->methodName();27$obj = new ClassName();28$obj->methodName();29$obj = new ClassName();30$obj->methodName();31$obj = new ClassName();32$obj->methodName();33$obj = new ClassName();34$obj->methodName();35$obj = new ClassName();36$obj->methodName();37$obj = new ClassName();38$obj->methodName();

Full Screen

Full Screen

is

Using AI Code Generation

copy

Full Screen

1$var = new name;2$var->method();3$var = name::method();4$var = new name;5$var->method();6$var = name::method();7$var = new name;8$var->method();9$var = name::method();10$var = new name;11$var->method();12$var = name::method();13$var = new name;14$var->method();15$var = name::method();16$var = new name;17$var->method();18$var = name::method();19$var = new name;20$var->method();21$var = name::method();22$var = new name;23$var->method();24$var = name::method();25$var = new name;26$var->method();27$var = name::method();28$var = new name;29$var->method();

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Prophecy automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Trigger is code on LambdaTest Cloud Grid

Execute automation tests with is on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful