├── Assets ├── img │ └── icon.png └── js │ └── sqlconditions.js ├── Config └── config.php ├── Controller └── SqlConditionsController.php ├── Entity ├── SqlConditions.php └── SqlConditionsRepository.php ├── Event └── SqlConditionsEvent.php ├── EventListener └── CampaignConditionSubscriber.php ├── Executioner ├── Params │ └── Params.php ├── QueryBuilder.php ├── SqlConditionDetails.php └── SqlExecutioner.php ├── Form └── Type │ ├── SqlConditionsCampaignType.php │ ├── SqlConditionsType.php │ └── SqlListType.php ├── Integration └── SqlConditionsIntegration.php ├── MauticSqlConditionsBundle.php ├── Model └── SqlConditionsModel.php ├── README.md ├── Security └── Permissions │ └── SqlConditionsPermissions.php ├── SqlConditionsEvents.php ├── Translations └── en_US │ └── messages.ini ├── Views ├── FormTheme │ └── SqlConditionsList │ │ └── sqlConditions_list_row.html.php ├── Integration │ └── form.html.php └── SqlConditions │ ├── details.html.php │ ├── form.html.php │ ├── index.html.php │ └── list.html.php └── composer.json /Assets/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtcextendee/mautic-sql-conditions-bundle/2d5ba75c0a08da72653d74f056e5e2906b611dce/Assets/img/icon.png -------------------------------------------------------------------------------- /Assets/js/sqlconditions.js: -------------------------------------------------------------------------------- 1 | Mautic.disabledSqlConditionsActions = function(opener) { 2 | if (typeof opener == 'undefined') { 3 | opener = window; 4 | } 5 | var email = opener.mQuery('#campaignevent_properties_sql').val(); 6 | 7 | var disabled = email === '' || email === null; 8 | 9 | opener.mQuery('#campaignevent_properties_editButton').prop('disabled', disabled); 10 | }; 11 | 12 | Mautic.standardSqlConditionsUrl = function(options) { 13 | 14 | if (!options) { 15 | return; 16 | } 17 | 18 | var url = options.windowUrl; 19 | if (url) { 20 | var editKey = '/sqlConditions/edit/objectId'; 21 | if (url.indexOf(editKey) > -1) { 22 | options.windowUrl = url.replace('objectId', mQuery('#campaignevent_properties_sql').val()); 23 | } 24 | } 25 | 26 | return options; 27 | }; 28 | -------------------------------------------------------------------------------- /Config/config.php: -------------------------------------------------------------------------------- 1 | 'SqlConditions', 14 | 'description' => 'SQL conditions for Mautic', 15 | 'author' => 'mtcextendee.com', 16 | 'version' => '1.0.0', 17 | 'services' => [ 18 | 'events' => [ 19 | 'mautic.sqlConditions.campaign.condition.subscriber' => [ 20 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\EventListener\CampaignConditionSubscriber::class, 21 | 'arguments' => [ 22 | 'mautic.sqlConditions.executioner', 23 | ], 24 | ], 25 | ], 26 | 'forms' => [ 27 | 'mautic.sqlConditions.form.campaign.type' => [ 28 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\Form\Type\SqlListType::class, 29 | 'arguments' => [ 30 | ], 31 | ], 32 | 'mautic.sqlConditions.form.list.type' => [ 33 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\Form\Type\SqlConditionsCampaignType::class, 34 | 'arguments' => 'router', 35 | 'alias' => 'sqlconditions_list', 36 | ], 37 | ], 38 | 'command' => [ 39 | 40 | ], 41 | 'other' => [ 42 | 'mautic.sqlConditions.executioner' => [ 43 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\Executioner\SqlExecutioner::class, 44 | 'arguments' => [ 45 | 'mautic.sqlConditions.executioner.condition.details', 46 | 'mautic.sqlConditions.executioner.query.builder', 47 | ], 48 | ], 49 | 'mautic.sqlConditions.executioner.condition.details' => [ 50 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\Executioner\SqlConditionDetails::class, 51 | 'arguments'=>[ 52 | 'mautic.sqlConditions.model.sqlConditions' 53 | ] 54 | ], 55 | 'mautic.sqlConditions.executioner.params' => [ 56 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\Executioner\Params\Params::class, 57 | ], 58 | 'mautic.sqlConditions.executioner.query.builder' => [ 59 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\Executioner\QueryBuilder::class, 60 | 'arguments'=>[ 61 | 'doctrine.orm.entity_manager', 62 | 'mautic.sqlConditions.executioner.params' 63 | ] 64 | ], 65 | ], 66 | 67 | 'helpers' => [], 68 | 'models' => [ 69 | 'mautic.sqlConditions.model.sqlConditions' => [ 70 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\Model\SqlConditionsModel::class, 71 | ], 72 | ], 73 | 'integrations' => [ 74 | 'mautic.integration.sqlconditions' => [ 75 | 'class' => \MauticPlugin\MauticSqlConditionsBundle\Integration\SqlConditionsIntegration::class, 76 | 'arguments' => [ 77 | 'event_dispatcher', 78 | 'mautic.helper.cache_storage', 79 | 'doctrine.orm.entity_manager', 80 | 'session', 81 | 'request_stack', 82 | 'router', 83 | 'translator', 84 | 'logger', 85 | 'mautic.helper.encryption', 86 | 'mautic.lead.model.lead', 87 | 'mautic.lead.model.company', 88 | 'mautic.helper.paths', 89 | 'mautic.core.model.notification', 90 | 'mautic.lead.model.field', 91 | 'mautic.plugin.model.integration_entity', 92 | 'mautic.lead.model.dnc', 93 | ], 94 | ], 95 | ], 96 | ], 97 | 'routes' => [ 98 | 'main' => [ 99 | 'mautic_sqlConditions_index' => [ 100 | 'path' => '/sqlConditions/{page}', 101 | 'controller' => 'MauticSqlConditionsBundle:SqlConditions:index', 102 | ], 103 | 'mautic_sqlConditions_action' => [ 104 | 'path' => '/sqlConditions/{objectAction}/{objectId}', 105 | 'controller' => 'MauticSqlConditionsBundle:SqlConditions:execute', 106 | ], 107 | ], 108 | ], 109 | 'menu' => [ 110 | 'main' => [ 111 | 'items' => [ 112 | 'mautic.sqlConditions' => [ 113 | 'route' => 'mautic_sqlConditions_index', 114 | 'priority' => 49, 115 | 'iconClass' => 'fa fa-database', 116 | 'checks' => [ 117 | 'integration' => [ 118 | 'SqlConditions' => [ 119 | 'enabled' => true, 120 | ], 121 | ], 122 | ], 123 | ], 124 | ], 125 | ], 126 | ], 127 | 'categories' => [ 128 | 'plugin:sqlConditions' => 'mautic.sqlConditions', 129 | ], 130 | ]; 131 | -------------------------------------------------------------------------------- /Controller/SqlConditionsController.php: -------------------------------------------------------------------------------- 1 | batchDeleteStandard(); 69 | } 70 | 71 | /** 72 | * @param $objectId 73 | * 74 | * @return \Mautic\CoreBundle\Controller\Response|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse 75 | */ 76 | public function cloneAction($objectId) 77 | { 78 | return $this->cloneStandard($objectId); 79 | } 80 | 81 | /** 82 | * @param $objectId 83 | * @param bool $ignorePost 84 | * 85 | * @return \Mautic\CoreBundle\Controller\Response|\Symfony\Component\HttpFoundation\JsonResponse 86 | */ 87 | public function editAction($objectId, $ignorePost = false) 88 | { 89 | return $this->editStandard($objectId, $ignorePost); 90 | } 91 | 92 | /** 93 | * @param int $page 94 | * 95 | * @return \Mautic\CoreBundle\Controller\Response|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse 96 | */ 97 | public function indexAction($page = 1) 98 | { 99 | return $this->indexStandard($page); 100 | } 101 | 102 | /** 103 | * @return \Mautic\CoreBundle\Controller\Response|\Symfony\Component\HttpFoundation\JsonResponse 104 | */ 105 | public function newAction() 106 | { 107 | return $this->newStandard(); 108 | } 109 | 110 | 111 | /** 112 | * @param $objectId 113 | * 114 | * @return array|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response 115 | */ 116 | public function viewAction($objectId) 117 | { 118 | return $this->viewStandard($objectId, $this->getModelName(), null, null, 'entity'); 119 | } 120 | 121 | /** 122 | * @param $args 123 | * @param $action 124 | * 125 | * @return mixed 126 | */ 127 | protected function getViewArguments(array $args, $action) 128 | { 129 | $viewParameters = []; 130 | switch ($action) { 131 | case 'new': 132 | case 'edit': 133 | break; 134 | case 'view': 135 | break; 136 | } 137 | $args['viewParameters'] = array_merge($args['viewParameters'], $viewParameters); 138 | 139 | return $args; 140 | } 141 | 142 | 143 | /** 144 | * @param $objectId 145 | * 146 | * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse 147 | */ 148 | protected function deleteAction($objectId) 149 | { 150 | return $this->deleteStandard($objectId); 151 | } 152 | 153 | protected function getDefaultOrderColumn() 154 | { 155 | return 'id'; 156 | } 157 | 158 | 159 | /** 160 | * @param int $objectId 161 | * 162 | * @return JsonResponse|\Symfony\Component\HttpFoundation\Response 163 | */ 164 | public function batchCronsAction($objectId = 0) 165 | { 166 | /** @var \Mautic\LeadBundle\Model\LeadModel $model */ 167 | $model = $this->getModel('sqlConditions'); 168 | /** @var IntegrationHelper $integrationHelper */ 169 | $integrationHelper = $this->get('mautic.helper.integration'); 170 | $integration = $integrationHelper->getIntegrationObject('SqlConditions'); 171 | 172 | if (false === $integration || !$integration->getIntegrationSettings()->getIsPublished()) { 173 | return; 174 | } 175 | $settings = $integration->mergeConfigToFeatureSettings(); 176 | $ids = $this->request->get('ids'); 177 | $entities = $model->getEntities( 178 | [ 179 | 'filter' => [ 180 | 'force' => [ 181 | [ 182 | 'column' => 'e.id', 183 | 'expr' => 'in', 184 | 'value' => $ids, 185 | ], 186 | ], 187 | ], 188 | 'ignore_paginator' => true, 189 | ] 190 | ); 191 | return $this->delegateView( 192 | [ 193 | 'viewParameters' => [ 194 | 'entities' => $entities, 195 | 'crons' => $settings['crons'], 196 | 'pathsHelper' => $this->get('mautic.helper.paths'), 197 | ], 198 | 'contentTemplate' => 'MauticSqlConditionsBundle:Batch:crons.html.php', 199 | ] 200 | ); 201 | } 202 | 203 | 204 | /** 205 | * @param array $args 206 | * @param $action 207 | * 208 | * @return array 209 | */ 210 | protected function getPostActionRedirectArguments(array $args, $action) 211 | { 212 | $updateSelect = ($this->request->getMethod() == 'POST') 213 | ? $this->request->request->get('sqlConditions[updateSelect]', false, true) 214 | : $this->request->get( 215 | 'updateSelect', 216 | false 217 | ); 218 | if ($updateSelect) { 219 | switch ($action) { 220 | case 'new': 221 | case 'edit': 222 | $passthrough = $args['passthroughVars']; 223 | $passthrough = array_merge( 224 | $passthrough, 225 | [ 226 | 'updateSelect' => $updateSelect, 227 | 'id' => $args['entity']->getId(), 228 | 'name' => $args['entity']->getName(), 229 | ] 230 | ); 231 | $args['passthroughVars'] = $passthrough; 232 | break; 233 | } 234 | } 235 | 236 | return $args; 237 | } 238 | 239 | /** 240 | * @return array 241 | */ 242 | protected function getEntityFormOptions() 243 | { 244 | $updateSelect = ($this->request->getMethod() == 'POST') 245 | ? $this->request->request->get('sqlConditions[updateSelect]', false, true) 246 | : $this->request->get( 247 | 'updateSelect', 248 | false 249 | ); 250 | if ($updateSelect) { 251 | return ['update_select' => $updateSelect]; 252 | } 253 | } 254 | 255 | /** 256 | * Return array of options update select response. 257 | * 258 | * @param string $updateSelect HTML id of the select 259 | * @param object $entity 260 | * @param string $nameMethod name of the entity method holding the name 261 | * @param string $groupMethod name of the entity method holding the select group 262 | * 263 | * @return array 264 | */ 265 | protected function getUpdateSelectParams($updateSelect, $entity, $nameMethod = 'getName', $groupMethod = 'getLanguage') 266 | { 267 | $options = [ 268 | 'updateSelect' => $updateSelect, 269 | 'id' => $entity->getId(), 270 | 'name' => $entity->$nameMethod(), 271 | ]; 272 | 273 | return $options; 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /Entity/SqlConditions.php: -------------------------------------------------------------------------------- 1 | setDateAdded(new \DateTime()); 57 | } 58 | 59 | /** 60 | * @param ORM\ClassMetadata $metadata 61 | */ 62 | public static function loadMetadata(ORM\ClassMetadata $metadata) 63 | { 64 | $builder = new ClassMetadataBuilder($metadata); 65 | $builder->setTable('sql_conditions') 66 | ->setCustomRepositoryClass(SqlConditionsRepository::class); 67 | $builder->addIdColumns('name', ''); 68 | $builder->addNamedField('sqlQuery', Type::TEXT, 'sql_query'); 69 | $builder->addCategory(); 70 | } 71 | 72 | 73 | /** 74 | * Prepares the metadata for API usage. 75 | * 76 | * @param $metadata 77 | */ 78 | public static function loadApiMetadata(ApiMetadataDriver $metadata) 79 | { 80 | $metadata->setGroupPrefix('sqlConditions') 81 | ->addListProperties( 82 | [ 83 | 'id', 84 | 'name', 85 | 'sqlQuery', 86 | 'category', 87 | 'dateAdded', 88 | ] 89 | ) 90 | ->build(); 91 | } 92 | 93 | 94 | /** 95 | * Get id. 96 | * 97 | * @return int 98 | */ 99 | public function getId() 100 | { 101 | return $this->id; 102 | } 103 | 104 | /* 105 | * Set dateAdded. 106 | * 107 | * @param \DateTime $dateAdded 108 | * 109 | * @return LeadEventLog 110 | */ 111 | public function setDateAdded($dateAdded) 112 | { 113 | $this->dateAdded = $dateAdded; 114 | 115 | return $this; 116 | } 117 | 118 | /** 119 | * Get dateAdded. 120 | * 121 | * @return \DateTime 122 | */ 123 | public function getDateAdded() 124 | { 125 | return $this->dateAdded; 126 | } 127 | 128 | 129 | public function getCreatedBy() 130 | { 131 | 132 | } 133 | 134 | public function getHeader() 135 | { 136 | 137 | } 138 | 139 | public function getPublishStatus() 140 | { 141 | 142 | } 143 | 144 | /** 145 | * @param string $name 146 | * 147 | * @return SqlConditions 148 | */ 149 | public function setName($name) 150 | { 151 | $this->name = $name; 152 | 153 | return $this; 154 | } 155 | 156 | /** 157 | * @return string 158 | */ 159 | public function getName() 160 | { 161 | return $this->name; 162 | } 163 | 164 | /** 165 | * @param mixed $sqlQuery 166 | * 167 | * @return SqlConditions 168 | */ 169 | public function setSqlQuery($sqlQuery) 170 | { 171 | $this->sqlQuery = $sqlQuery; 172 | 173 | return $this; 174 | } 175 | 176 | /** 177 | * @return mixed 178 | */ 179 | public function getSqlQuery() 180 | { 181 | return $this->sqlQuery; 182 | } 183 | 184 | 185 | /** 186 | * @return \Mautic\CategoryBundle\Entity\Category 187 | */ 188 | public function getCategory() 189 | { 190 | return $this->category; 191 | } 192 | 193 | /** 194 | * @param \Mautic\CategoryBundle\Entity\Category $category 195 | * 196 | * @return $this 197 | */ 198 | public function setCategory($category) 199 | { 200 | $this->category = $category; 201 | 202 | return $this; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /Entity/SqlConditionsRepository.php: -------------------------------------------------------------------------------- 1 | $alias], null); 30 | } 31 | 32 | /** 33 | * Get a list of entities. 34 | * 35 | * @param array $args 36 | * 37 | * @return Paginator 38 | */ 39 | public function getEntities(array $args = []) 40 | { 41 | $alias = $this->getTableAlias(); 42 | 43 | $q = $this->_em 44 | ->createQueryBuilder() 45 | ->select($alias) 46 | ->from('MauticSqlConditionsBundle:SqlConditions', $alias, $alias.'.id'); 47 | 48 | if (empty($args['iterator_mode'])) { 49 | $q->leftJoin($alias.'.category', 'c'); 50 | } 51 | 52 | $args['qb'] = $q; 53 | 54 | return parent::getEntities($args); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Event/SqlConditionsEvent.php: -------------------------------------------------------------------------------- 1 | entity = $entity; 28 | $this->isNew = $isNew; 29 | } 30 | 31 | /** 32 | * @return SqlConditions 33 | */ 34 | public function getEntity() 35 | { 36 | return $this->entity; 37 | } 38 | 39 | /** 40 | * @param SqlConditions $entity 41 | */ 42 | public function setEntity(SqlConditions $entity) 43 | { 44 | $this->entity = $entity; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /EventListener/CampaignConditionSubscriber.php: -------------------------------------------------------------------------------- 1 | sqlExecutioner = $sqlExecutioner; 42 | } 43 | 44 | /** 45 | * @return array 46 | */ 47 | public static function getSubscribedEvents() 48 | { 49 | return [ 50 | CampaignEvents::CAMPAIGN_ON_BUILD => ['onCampaignBuild', 0], 51 | SqlConditionsEvents::ON_CAMPAIGN_CONDITION_TRIGGER => ['onCampaignTriggerCondition', 0], 52 | ]; 53 | } 54 | 55 | /** 56 | * @param CampaignBuilderEvent $event 57 | */ 58 | public function onCampaignBuild(CampaignBuilderEvent $event) 59 | { 60 | $event->addCondition( 61 | 'sql.condition', 62 | [ 63 | 'label' => 'mautic.sqlConditions', 64 | 'eventName' => SqlConditionsEvents::ON_CAMPAIGN_CONDITION_TRIGGER, 65 | 'formType' => SqlConditionsCampaignType::class, 66 | 'formTheme' => 'MauticSqlConditionsBundle:FormTheme\SqlConditionsList', 67 | 'formTypeOptions' => ['update_select' => 'campaignevent_properties_sql'], 68 | 69 | ] 70 | ); 71 | } 72 | 73 | /** 74 | * @param ConditionEvent $event 75 | */ 76 | public function onCampaignTriggerCondition(ConditionEvent $event) 77 | { 78 | if ($this->sqlExecutioner->execute($event)) { 79 | $event->pass(); 80 | } else { 81 | $event->fail(); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Executioner/Params/Params.php: -------------------------------------------------------------------------------- 1 | sqlConditionDetails = $sqlConditionDetails; 32 | $sqlQuery = $this->sqlConditionDetails->getSqlQuery(); 33 | $params = []; 34 | 35 | foreach ($this->getAllParams() as $key => $value) { 36 | if (strpos($sqlQuery, $key) !== false) { 37 | $params[$key] = $value; 38 | } 39 | } 40 | 41 | return $params; 42 | 43 | } 44 | 45 | /** 46 | * @return array 47 | * @throws \Exception 48 | */ 49 | private function getAllParams() 50 | { 51 | 52 | $params = []; 53 | $params[':contactId'] = $this->sqlConditionDetails->getConditionEvent()->getLead()->getId(); 54 | $params[':campaignId'] = $this->sqlConditionDetails->getConditionEvent()->getLogEntry()->getCampaign()->getId(); 55 | $params[':eventId'] = $this->sqlConditionDetails->getConditionEvent()->getEvent()['id']; 56 | $params[':rotation'] = $this->sqlConditionDetails->getConditionEvent()->getLogEntry()->getRotation(); 57 | 58 | return $params; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Executioner/QueryBuilder.php: -------------------------------------------------------------------------------- 1 | entityManager = $entityManager; 44 | $this->params = $params; 45 | 46 | /** @var Connection $connection */ 47 | $this->connection = $this->entityManager->getConnection(); 48 | if ($this->connection instanceof MasterSlaveConnection) { 49 | $this->connection->connect('slave'); 50 | } 51 | } 52 | 53 | /** 54 | * @param SqlConditionDetails $sqlConditionDetails 55 | * 56 | * @return \Doctrine\DBAL\Driver\Statement 57 | * @throws \Doctrine\DBAL\DBALException 58 | */ 59 | public function runQuery(SqlConditionDetails $sqlConditionDetails) 60 | { 61 | $sqlQuery = $sqlConditionDetails->getSqlQuery(); 62 | if (!$sqlQuery) { 63 | return false; 64 | } 65 | 66 | $params = $this->params->parseParamsFromSqlQuery($sqlConditionDetails); 67 | return $this->connection->executeQuery($sqlQuery, $params)->fetchAll(); 68 | } 69 | 70 | 71 | }; 72 | -------------------------------------------------------------------------------- /Executioner/SqlConditionDetails.php: -------------------------------------------------------------------------------- 1 | sqlConditionsModel = $sqlConditionsModel; 37 | } 38 | 39 | /** 40 | * @param ConditionEvent $conditionEvent 41 | */ 42 | public function setConditionEvent(ConditionEvent $conditionEvent) 43 | { 44 | $this->conditionEvent = $conditionEvent; 45 | } 46 | 47 | 48 | /** 49 | * @return ConditionEvent 50 | * @throws \Exception 51 | */ 52 | public function getConditionEvent() 53 | { 54 | if (!$this->conditionEvent) { 55 | throw new \Exception('Condition event not exist'); 56 | } 57 | 58 | return $this->conditionEvent; 59 | } 60 | 61 | /** 62 | * @return mixed 63 | * @throws \Exception 64 | */ 65 | public function getSqlQuery() 66 | { 67 | $sqlConditionId = $this->getConditionEvent()->getConfig()['sql']; 68 | $entity = $this->sqlConditionsModel->getEntity($sqlConditionId); 69 | 70 | if ($entity && $entity->isPublished()) { 71 | return $entity->getSqlQuery(); 72 | } 73 | 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /Executioner/SqlExecutioner.php: -------------------------------------------------------------------------------- 1 | sqlConditionDetails = $sqlConditionDetails; 37 | $this->queryBuilder = $queryBuilder; 38 | } 39 | 40 | /** 41 | * @param ConditionEvent $conditionEvent 42 | * 43 | * @return bool 44 | * @throws \Doctrine\DBAL\DBALException 45 | */ 46 | public function execute(ConditionEvent $conditionEvent) 47 | { 48 | $this->sqlConditionDetails->setConditionEvent($conditionEvent); 49 | return $this->queryBuilder->runQuery($this->sqlConditionDetails); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Form/Type/SqlConditionsCampaignType.php: -------------------------------------------------------------------------------- 1 | router = $router; 35 | } 36 | 37 | 38 | /** 39 | * @param FormBuilderInterface $builder 40 | * @param array $options 41 | */ 42 | public function buildForm(FormBuilderInterface $builder, array $options) 43 | { 44 | 45 | $builder->add( 46 | 'sql', 47 | SqlListType::class, 48 | [ 49 | 'label' => 'mautic.sqlConditions.sql', 50 | 'label_attr' => ['class' => 'control-label'], 51 | 'attr' => [ 52 | 'class' => 'form-control', 53 | 'onchange' => 'Mautic.disabledSqlConditionsActions()', 54 | ], 55 | 'multiple' => false, 56 | 'required' => true, 57 | 'constraints' => [ 58 | new NotBlank(), 59 | ], 60 | ] 61 | ); 62 | 63 | 64 | 65 | if (!empty($options['update_select'])) { 66 | $windowUrl = $this->router->generate( 67 | 'mautic_sqlConditions_action', 68 | [ 69 | 'objectAction' => 'new', 70 | 'contentOnly' => 1, 71 | 'updateSelect' => $options['update_select'], 72 | ] 73 | ); 74 | 75 | $builder->add( 76 | 'newButton', 77 | ButtonType::class, 78 | [ 79 | 'attr' => [ 80 | 'class' => 'btn btn-primary btn-nospin', 81 | 'onclick' => 'Mautic.loadNewWindow({ 82 | "windowUrl": "'.$windowUrl.'" 83 | })', 84 | 'icon' => 'fa fa-plus', 85 | ], 86 | 'label' => 'mautic.core.form.add', 87 | ] 88 | ); 89 | 90 | // create button edit focus 91 | $windowUrlEdit = $this->router->generate( 92 | 'mautic_sqlConditions_action', 93 | [ 94 | 'objectAction' => 'edit', 95 | 'objectId' => 'objectId', 96 | 'contentOnly' => 1, 97 | 'updateSelect' => $options['update_select'], 98 | ] 99 | ); 100 | 101 | $builder->add( 102 | 'editButton', 103 | ButtonType::class, 104 | [ 105 | 'attr' => [ 106 | 'class' => 'btn btn-primary btn-nospin', 107 | 'onclick' => 'Mautic.loadNewWindow(Mautic.standardSqlConditionsUrl({"windowUrl": "'.$windowUrlEdit.'"}))', 108 | 'disabled' => !isset($options['data']['sql']), 109 | 'icon' => 'fa fa-edit', 110 | ], 111 | 'label' => 'mautic.core.form.edit', 112 | ] 113 | ); 114 | } 115 | 116 | } 117 | 118 | 119 | /** 120 | * @param OptionsResolver $resolver 121 | */ 122 | public function configureOptions(OptionsResolver $resolver) 123 | { 124 | $resolver->setDefined(['update_select']); 125 | } 126 | 127 | /** 128 | * @return string 129 | */ 130 | public function getBlockPrefix() 131 | { 132 | return 'sqlconditions_list'; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Form/Type/SqlConditionsType.php: -------------------------------------------------------------------------------- 1 | add( 37 | 'name', 38 | TextType::class, 39 | [ 40 | 'label' => 'mautic.core.name', 41 | 'label_attr' => ['class' => 'control-label'], 42 | 'attr' => ['class' => 'form-control'], 43 | 'constraints' => [ 44 | new NotBlank(), 45 | ], 46 | ] 47 | ); 48 | 49 | $builder->add( 50 | 'sqlQuery', 51 | TextareaType::class, 52 | [ 53 | 'label' => 'mautic.sqlConditions.sql', 54 | 'label_attr' => ['class' => 'control-label'], 55 | 'attr' => [ 56 | 'class' => 'form-control', 57 | 'rows' => 5, 58 | ], 59 | 'required' => true, 60 | 'constraints' => [ 61 | new NotBlank(), 62 | ], 63 | ] 64 | ); 65 | 66 | $builder->add( 67 | 'category', 68 | CategoryListType::class, 69 | [ 70 | 'bundle' => 'plugin:sqlConditions', 71 | ] 72 | ); 73 | 74 | $builder->add('isPublished', YesNoButtonGroupType::class); 75 | 76 | 77 | if (!empty($options['update_select'])) { 78 | $builder->add( 79 | 'buttons', 80 | FormButtonsType::class, 81 | [ 82 | 'apply_text' => false, 83 | ] 84 | ); 85 | $builder->add( 86 | 'updateSelect', 87 | HiddenType::class, 88 | [ 89 | 'data' => $options['update_select'], 90 | 'mapped' => false, 91 | ] 92 | ); 93 | } else { 94 | $builder->add( 95 | 'buttons', 96 | FormButtonsType::class 97 | ); 98 | } 99 | } 100 | 101 | 102 | public function configureOptions(OptionsResolver $resolver) 103 | { 104 | $resolver->setDefaults( 105 | [ 106 | 'data_class' => 'MauticPlugin\MauticSqlConditionsBundle\Entity\SqlConditions', 107 | ] 108 | ); 109 | $resolver->setDefined(['update_select']); 110 | 111 | } 112 | 113 | 114 | 115 | /** 116 | * @return string 117 | */ 118 | public function getBlockPrefix() 119 | { 120 | return 'sqlConditions'; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Form/Type/SqlListType.php: -------------------------------------------------------------------------------- 1 | setDefaults( 27 | [ 28 | 'modal_route' => 'mautic_sqlConditions_action', 29 | 'modal_header' => 'mautic.core.new', 30 | 'model' => 'sqlConditions', 31 | 'model_lookup_method' => 'getLookupResults', 32 | 'lookup_arguments' => function (Options $options) { 33 | return [ 34 | 'type' => 'sqlConditions', 35 | 'filter' => '$data', 36 | 'limit' => 0, 37 | 'start' => 0, 38 | 'options' => [ 39 | 'sqlConditions_type' => $options['sqlConditions_type'], 40 | ], 41 | ]; 42 | }, 43 | 'ajax_lookup_action' => function (Options $options) { 44 | $query = [ 45 | 'sqlConditions_type' => $options['sqlConditions_type'], 46 | ]; 47 | 48 | return 'sqlConditions:getLookupChoiceList&'.http_build_query($query); 49 | }, 50 | 'multiple' => true, 51 | 'required' => false, 52 | 'sqlConditions_type' => 'template', 53 | ] 54 | ); 55 | } 56 | /** 57 | * @return string 58 | */ 59 | public function getParent() 60 | { 61 | return EntityLookupType::class; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Integration/SqlConditionsIntegration.php: -------------------------------------------------------------------------------- 1 | false, 61 | 'requires_authorization' => false, 62 | ]; 63 | } 64 | 65 | /** 66 | * {@inheritdoc} 67 | * 68 | * @return string 69 | */ 70 | public function getAuthenticationType() 71 | { 72 | return 'none'; 73 | } 74 | 75 | /** 76 | * @return bool 77 | */ 78 | public function isEnabledIntegration() 79 | { 80 | if (strpos($this->pathsHelper->getSystemPath('local_config'), 'local.php') !== false) { 81 | return true; 82 | } 83 | 84 | return false; 85 | } 86 | 87 | /** 88 | * @return \Mautic\PluginBundle\Entity\Integration 89 | */ 90 | public function getIntegrationSettings() 91 | { 92 | $integrationSettings = parent::getIntegrationSettings(); 93 | if (!$this->isEnabledIntegration()) { 94 | $integrationSettings->setIsPublished(false); 95 | } 96 | 97 | return $integrationSettings; 98 | } 99 | 100 | /** 101 | * @param \Mautic\PluginBundle\Integration\Form|\Symfony\Component\Form\FormBuilder $builder 102 | * @param array $data 103 | * @param string $formArea 104 | */ 105 | public function appendToForm(&$builder, $data, $formArea) 106 | { 107 | if ($formArea == 'features') { 108 | } 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /MauticSqlConditionsBundle.php: -------------------------------------------------------------------------------- 1 | em->getRepository('MauticSqlConditionsBundle:SqlConditions'); 46 | 47 | $repo->setTranslator($this->translator); 48 | 49 | return $repo; 50 | } 51 | 52 | /** 53 | * Here just so PHPStorm calms down about type hinting. 54 | * 55 | * @param null $id 56 | * 57 | * @return null|SqlConditions 58 | */ 59 | public function getEntity($id = null) 60 | { 61 | if ($id === null) { 62 | return new SqlConditions(); 63 | } 64 | 65 | return parent::getEntity($id); 66 | } 67 | 68 | /** 69 | * {@inheritdoc} 70 | * 71 | * @param $entity 72 | * @param $formFactory 73 | * @param null $action 74 | * @param array $options 75 | * 76 | * @return mixed 77 | * 78 | * @throws \InvalidArgumentException 79 | */ 80 | public function createForm($entity, $formFactory, $action = null, $options = []) 81 | { 82 | if (!$entity instanceof SqlConditions) { 83 | throw new \InvalidArgumentException('Entity must be of class Event'); 84 | } 85 | 86 | if (!empty($action)) { 87 | $options['action'] = $action; 88 | } 89 | 90 | return $formFactory->create(SqlConditionsType::class, $entity, $options); 91 | } 92 | 93 | /** 94 | * {@inheritdoc} 95 | * 96 | * @param $action 97 | * @param $entity 98 | * @param $isNew 99 | * @param $event 100 | * 101 | * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException 102 | */ 103 | protected function dispatchEvent($action, &$entity, $isNew = false, \Symfony\Component\EventDispatcher\Event $event = null) 104 | { 105 | if (!$entity instanceof SqlConditions) { 106 | throw new MethodNotAllowedHttpException(['SqlConditions']); 107 | } 108 | 109 | switch ($action) { 110 | case 'pre_save': 111 | $name = SqlConditionsEvents::PRE_SAVE; 112 | break; 113 | case 'post_save': 114 | $name = SqlConditionsEvents::POST_SAVE; 115 | break; 116 | case 'pre_delete': 117 | $name = SqlConditionsEvents::PRE_DELETE; 118 | break; 119 | case 'post_delete': 120 | $name = SqlConditionsEvents::POST_DELETE; 121 | break; 122 | default: 123 | return null; 124 | } 125 | 126 | if ($this->dispatcher->hasListeners($name)) { 127 | if (empty($event)) { 128 | $event = new SqlConditionsEvent($entity, $isNew); 129 | $event->setEntityManager($this->em); 130 | } 131 | 132 | $this->dispatcher->dispatch($name, $event); 133 | 134 | return $event; 135 | } else { 136 | return null; 137 | } 138 | } 139 | 140 | /** 141 | * @param $type 142 | * @param string $filter 143 | * @param int $limit 144 | * @param int $start 145 | * @param array $options 146 | * 147 | * @return array|mixed 148 | */ 149 | public function getLookupResults($type, $filter = '', $limit = 10, $start = 0, $options = []) 150 | { 151 | $results = []; 152 | switch ($type) { 153 | case 'sqlConditions': 154 | $entities = $this->getRepository()->getSimpleList(); 155 | 156 | foreach ($entities as $entity) { 157 | $results[$entity['value']] = $entity['label']; 158 | } 159 | 160 | //sort by language 161 | ksort($results); 162 | 163 | break; 164 | } 165 | 166 | return $results; 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MauticSqlConditionsBundle 2 | 3 | SQL conditions for Mautic 4 | 5 | ## Support 6 | 7 | https://mtcextendee.com/plugins 8 | 9 | ## Installation 10 | 11 | ### Command line 12 | - `composer require mtcextendee/mautic-sql-conditions-bundle` 13 | - `php app/console mautic:plugins:reload` 14 | - Go to /s/plugins and setup SQL Conditions 15 | 16 | ### Manual 17 | - Download last version https://github.com/mtcextendee/mautic-sql-conditions-bundle/releases 18 | - Unzip files to plugins/MauticSqlConditionsBundle 19 | - Clear cache (app/cache/prod/) 20 | - Go to /s/plugins/reload 21 | - Setup SQL Conditions integration 22 | 23 | ## Usage 24 | 25 | 1, See new item on left menu: 26 | 27 |  28 | 29 | 2, Setup SQL conditions 30 | 31 | 3, Parameters for SQL 32 | 33 | - :contactId 34 | - :campaignId 35 | - :eventId 36 | - :rotation 37 | 38 | 4, Condition return true If there is results 39 | 40 | ## Examples 41 | 42 | Condition for contacts with ID greather like 2000 43 | 44 | `SELECT l.id FROM leads l WHERE l.id = :contactId and l.id > 2000` 45 | 46 | ## Credits 47 | 48 | Icons made by Eleonor Wang from www.flaticon.com 49 | -------------------------------------------------------------------------------- /Security/Permissions/SqlConditionsPermissions.php: -------------------------------------------------------------------------------- 1 | addExtendedPermissions('sqlConditions'); 26 | } 27 | 28 | /** 29 | * {@inheritdoc} 30 | * 31 | * @return string|void 32 | */ 33 | public function getName() 34 | { 35 | return 'sqlConditions'; 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | * 41 | * @param FormBuilderInterface $builder 42 | * @param array $options 43 | */ 44 | public function buildForm(FormBuilderInterface &$builder, array $options, array $data) 45 | { 46 | $this->addExtendedFormFields('sqlConditions', 'sqlConditions', $builder, $data); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SqlConditionsEvents.php: -------------------------------------------------------------------------------- 1 | includeScript('plugins/MauticSqlConditionsBundle/Assets/js/sqlconditions.js'); 12 | 13 | ?> 14 | 15 |
72 | render( 74 | 'MauticCoreBundle:Helper:list_actions.html.php', 75 | [ 76 | 'item' => $item, 77 | 'templateButtons' => [ 78 | 'edit' => $view['security']->hasEntityAccess( 79 | $permissions['sqlConditions:sqlConditions:editown'], 80 | $permissions['sqlConditions:sqlConditions:editother'], 81 | $item->getCreatedBy() 82 | ), 83 | 'clone' => $permissions['sqlConditions:sqlConditions:create'], 84 | 'delete' => $view['security']->hasEntityAccess( 85 | $permissions['sqlConditions:sqlConditions:deleteown'], 86 | $permissions['sqlConditions:sqlConditions:deleteother'], 87 | $item->getCreatedBy() 88 | ), 89 | ], 90 | 'routeBase' => 'sqlConditions', 91 | 'nameGetter' => 'getName', 92 | ] 93 | ); 94 | ?> 95 | | 96 |97 | 101 | getName(); ?> 102 | 103 | 104 | | 105 |106 | getCategory(); ?> 107 | getTitle() : $view['translator']->trans('mautic.core.form.uncategorized'); ?> 108 | getColor() : 'inherit'; ?> 109 | 110 | | 111 |getId(); ?> | 112 |