Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -0,0 +1,156 @@
<?php
namespace MauticPlugin\MauticSocialBundle\Model;
use Mautic\CoreBundle\Model\FormModel;
use MauticPlugin\MauticSocialBundle\Entity\Monitoring;
use MauticPlugin\MauticSocialBundle\Event as Events;
use MauticPlugin\MauticSocialBundle\Form\Type\MonitoringType;
use MauticPlugin\MauticSocialBundle\Form\Type\TwitterHashtagType;
use MauticPlugin\MauticSocialBundle\Form\Type\TwitterMentionType;
use MauticPlugin\MauticSocialBundle\SocialEvents;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Contracts\EventDispatcher\Event;
/**
* @extends FormModel<Monitoring>
*/
class MonitoringModel extends FormModel
{
/**
* @var array<string, mixed>
*/
private array $networkTypes = [
'twitter_handle' => [
'label' => 'mautic.social.monitoring.type.list.twitter.handle',
'form' => TwitterMentionType::class,
],
'twitter_hashtag' => [
'label' => 'mautic.social.monitoring.type.list.twitter.hashtag',
'form' => TwitterHashtagType::class,
],
];
/**
* @param object $entity
* @param string|null $action
* @param mixed[] $options
*/
public function createForm($entity, FormFactoryInterface $formFactory, $action = null, $options = []): \Symfony\Component\Form\FormInterface
{
if (!$entity instanceof Monitoring) {
throw new MethodNotAllowedHttpException(['Monitoring']);
}
if (!empty($action)) {
$options['action'] = $action;
}
return $formFactory->create(MonitoringType::class, $entity, $options);
}
/**
* Get a specific entity or generate a new one if id is empty.
*/
public function getEntity($id = null): ?Monitoring
{
return $id ? parent::getEntity($id) : new Monitoring();
}
/**
* @throws MethodNotAllowedHttpException
*/
protected function dispatchEvent($action, &$entity, $isNew = false, ?Event $event = null): ?Event
{
if (!$entity instanceof Monitoring) {
throw new MethodNotAllowedHttpException(['Monitoring']);
}
switch ($action) {
case 'pre_save':
$name = SocialEvents::MONITOR_PRE_SAVE;
break;
case 'post_save':
$name = SocialEvents::MONITOR_POST_SAVE;
break;
case 'pre_delete':
$name = SocialEvents::MONITOR_PRE_DELETE;
break;
case 'post_delete':
$name = SocialEvents::MONITOR_POST_DELETE;
break;
default:
return null;
}
if ($this->dispatcher->hasListeners($name)) {
if (empty($event)) {
$event = new Events\SocialEvent($entity, $isNew);
}
$this->dispatcher->dispatch($event, $name);
return $event;
} else {
return null;
}
}
/**
* @param Monitoring $monitoringEntity
* @param bool $unlock
*/
public function saveEntity($monitoringEntity, $unlock = true): void
{
// we're editing an existing record
if (!$monitoringEntity->isNew()) {
// increase the revision
$revision = $monitoringEntity->getRevision();
++$revision;
$monitoringEntity->setRevision($revision);
} // is new
else {
$now = new \DateTime();
$monitoringEntity->setDateAdded($now);
}
parent::saveEntity($monitoringEntity, $unlock);
}
/**
* @return \MauticPlugin\MauticSocialBundle\Entity\MonitoringRepository
*/
public function getRepository()
{
return $this->em->getRepository(Monitoring::class);
}
public function getPermissionBase(): string
{
return 'mauticSocial:monitoring';
}
/**
* @return string[]
*/
public function getNetworkTypes(): array
{
$types = [];
foreach ($this->networkTypes as $type => $data) {
$types[$type] = $data['label'];
}
return $types;
}
/**
* @param string $type
*
* @return string|null
*/
public function getFormByType($type)
{
return array_key_exists($type, $this->networkTypes) ? $this->networkTypes[$type]['form'] : null;
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace MauticPlugin\MauticSocialBundle\Model;
use Mautic\CoreBundle\Model\AbstractCommonModel;
use MauticPlugin\MauticSocialBundle\Entity\PostCount;
/**
* @extends AbstractCommonModel<PostCount>
*/
class PostCountModel extends AbstractCommonModel
{
/**
* Get a specific entity or generate a new one if id is empty.
*/
public function getEntity($id = null): ?PostCount
{
if (null !== $id) {
$repo = $this->getRepository();
if (method_exists($repo, 'getEntity')) {
return $repo->getEntity($id);
}
return $repo->find($id);
}
return new PostCount();
}
/**
* Get this model's repository.
*
* @return \MauticPlugin\MauticSocialBundle\Entity\PostCountRepository
*/
public function getRepository()
{
return $this->em->getRepository(PostCount::class);
}
/*
* Updates a monitor record's post count on a daily basis
*
* @return boolean
*/
public function updatePostCount($monitor, \DateTime $postDate): bool
{
// query the db for posts on this date
$q = $this->getRepository()->createQueryBuilder($this->getRepository()->getTableAlias());
$expr = $q->expr()->eq($this->getRepository()->getTableAlias().'.postDate', ':date');
$q->setParameter('date', $postDate, 'date');
$q->where($expr);
$args['qb'] = $q;
// ignore paginator so we can use the array later
$args['ignore_paginator'] = true;
/** @var \MauticPlugin\MauticSocialBundle\Entity\PostCountRepository $postCountsRepository */
$postCountsRepository = $this->getRepository();
// get any existing records
$postCounts = $postCountsRepository->getEntities($args);
// if there isn't anything then create it
if (!count($postCounts)) {
/** @var PostCount $postCount */
$postCount = $this->getEntity();
$postCount->setMonitor($monitor);
$postCount->setPostDate($postDate); // $postDate->format('m-d-Y')
} else {
// use the first record to increment it.
$postCount = $this->getEntity($postCounts[0]->getId());
}
// increment
$postCount->setPostCount($postCount->getPostCount() + 1);
// now save it
$postCountsRepository->saveEntity($postCount);
// nothing went wrong so return true here
return true;
}
}

View File

@@ -0,0 +1,209 @@
<?php
namespace MauticPlugin\MauticSocialBundle\Model;
use Mautic\CoreBundle\Model\AjaxLookupModelInterface;
use Mautic\CoreBundle\Model\FormModel;
use Mautic\LeadBundle\Entity\Lead;
use MauticPlugin\MauticSocialBundle\Entity\Tweet;
use MauticPlugin\MauticSocialBundle\Entity\TweetRepository;
use MauticPlugin\MauticSocialBundle\Entity\TweetStat;
use MauticPlugin\MauticSocialBundle\Entity\TweetStatRepository;
use MauticPlugin\MauticSocialBundle\Event as Events;
use MauticPlugin\MauticSocialBundle\Form\Type\TweetType;
use MauticPlugin\MauticSocialBundle\SocialEvents;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Contracts\EventDispatcher\Event;
/**
* @extends FormModel<Tweet>
*
* @implements AjaxLookupModelInterface<Tweet>
*/
class TweetModel extends FormModel implements AjaxLookupModelInterface
{
/**
* @param string $filter
* @param int $limit
* @param int $start
* @param array $options
*/
public function getLookupResults($type, $filter = '', $limit = 10, $start = 0, $options = []): array
{
$results = [];
switch ($type) {
case 'social.tweet':
case 'tweet':
if (isset($filter['tweet_text'])) {
// This tweet was created as the campaign action param and these params are not the filter. Clear the filter.
$filter = '';
}
$tweetRepo = $this->getRepository();
$tweetRepo->setCurrentUser($this->userHelper->getUser());
$entities = $tweetRepo->getTweetList(
$filter,
$limit,
$start,
$this->security->isGranted($this->getPermissionBase().':viewother')
);
foreach ($entities as $entity) {
$results[$entity['language']][$entity['id']] = $entity['name'];
}
// sort by language
ksort($results);
unset($entities);
break;
}
return $results;
}
/**
* Create/update Tweet Stat and update sent count for Tweet.
*
* @param string $source
* @param int $sourceId
*
* @return $this
*/
public function registerSend(Tweet $tweet, Lead $lead, array $sendResponse, $source = null, $sourceId = null)
{
$statRepo = $this->getStatRepository();
// Update failed tweet
$stat = $statRepo->findOneBy(
[
'lead' => $lead->getId(),
'tweet' => $tweet->getId(),
'source' => $source,
'sourceId' => $sourceId,
'isFailed' => true,
]
);
if (!$stat) {
// Create new entity
$stat = new TweetStat();
} else {
// Or add 1 to the retry count
$stat->retryCountUp();
}
$stat->setTweet($tweet);
$stat->setLead($lead);
$stat->setResponseDetails($sendResponse);
$stat->setSource($source);
$stat->setSourceId($sourceId);
$fields = $lead->getProfileFields();
if (!empty($fields['twitter'])) {
$stat->setHandle($fields['twitter']);
}
if (!empty($sendResponse['id_str'])) {
$stat->setDateSent(new \DateTime());
$stat->setTwitterTweetId($sendResponse['id_str']);
$tweet->sentCountUp();
$this->saveEntity($tweet);
} else {
$stat->setIsFailed(true);
}
$statRepo->saveEntity($stat);
return $this;
}
/**
* @param Tweet $entity
* @param array<mixed> $options
*/
public function createForm($entity, FormFactoryInterface $formFactory, $action = null, $options = []): \Symfony\Component\Form\FormInterface
{
if (!$entity instanceof Tweet) {
throw new MethodNotAllowedHttpException(['Tweet']);
}
if (!empty($action)) {
$options['action'] = $action;
}
return $formFactory->create(TweetType::class, $entity, $options);
}
/**
* Get a specific entity or generate a new one if id is empty.
*
* @param int $id
*/
public function getEntity($id = null): ?Tweet
{
if (null === $id) {
return new Tweet();
}
return parent::getEntity($id);
}
/**
* @throws MethodNotAllowedHttpException
*/
protected function dispatchEvent($action, &$entity, $isNew = false, ?Event $event = null): ?Event
{
if (!$entity instanceof Tweet) {
throw new MethodNotAllowedHttpException(['Tweet']);
}
switch ($action) {
case 'pre_save':
$name = SocialEvents::TWEET_PRE_SAVE;
break;
case 'post_save':
$name = SocialEvents::TWEET_POST_SAVE;
break;
case 'pre_delete':
$name = SocialEvents::TWEET_PRE_DELETE;
break;
case 'post_delete':
$name = SocialEvents::TWEET_POST_DELETE;
break;
default:
return null;
}
if ($this->dispatcher->hasListeners($name)) {
if (empty($event)) {
$event = new Events\SocialEvent($entity, $isNew);
}
$this->dispatcher->dispatch($event, $name);
return $event;
} else {
return null;
}
}
public function getRepository(): TweetRepository
{
return $this->em->getRepository(Tweet::class);
}
public function getStatRepository(): TweetStatRepository
{
return $this->em->getRepository(TweetStat::class);
}
public function getPermissionBase(): string
{
return 'mauticSocial:tweets';
}
}