301 lines
9.9 KiB
PHP
Executable File
301 lines
9.9 KiB
PHP
Executable File
<?php
|
|
|
|
namespace MauticPlugin\MauticSocialBundle\Command;
|
|
|
|
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
|
use Mautic\CoreBundle\Translation\Translator;
|
|
use Mautic\PluginBundle\Helper\IntegrationHelper;
|
|
use MauticPlugin\MauticSocialBundle\Entity\Monitoring;
|
|
use MauticPlugin\MauticSocialBundle\Event\SocialMonitorEvent;
|
|
use MauticPlugin\MauticSocialBundle\Helper\TwitterCommandHelper;
|
|
use MauticPlugin\MauticSocialBundle\Integration\TwitterIntegration;
|
|
use MauticPlugin\MauticSocialBundle\SocialEvents;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
|
|
abstract class MonitorTwitterBaseCommand extends Command
|
|
{
|
|
/**
|
|
* @var TwitterIntegration
|
|
*/
|
|
protected $twitter;
|
|
|
|
/**
|
|
* @var InputInterface
|
|
*/
|
|
protected $input;
|
|
|
|
/**
|
|
* @var OutputInterface
|
|
*/
|
|
protected $output;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $maxRuns = 5;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $runCount = 0;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $queryCount = 100;
|
|
|
|
public function __construct(
|
|
protected EventDispatcherInterface $dispatcher,
|
|
protected Translator $translator,
|
|
protected IntegrationHelper $integrationHelper,
|
|
private TwitterCommandHelper $twitterCommandHelper,
|
|
CoreParametersHelper $coreParametersHelper,
|
|
) {
|
|
$this->translator->setLocale($coreParametersHelper->get('locale', 'en_US'));
|
|
|
|
parent::__construct();
|
|
}
|
|
|
|
/**
|
|
* Command configuration. Set the name, description, and options here.
|
|
*/
|
|
protected function configure()
|
|
{
|
|
$this
|
|
->addOption(
|
|
'mid',
|
|
'i',
|
|
InputOption::VALUE_REQUIRED,
|
|
'The id of the monitor record'
|
|
)
|
|
->addOption(
|
|
'max-runs',
|
|
null,
|
|
InputOption::VALUE_REQUIRED,
|
|
'The maximum number of recursive iterations permitted',
|
|
5
|
|
)
|
|
->addOption(
|
|
'query-count',
|
|
null,
|
|
InputOption::VALUE_OPTIONAL,
|
|
'The number of records to search for per iteration.',
|
|
100
|
|
)
|
|
->addOption(
|
|
'show-posts',
|
|
null,
|
|
InputOption::VALUE_NONE,
|
|
'Use this option to display the posts retrieved'
|
|
)
|
|
->addOption(
|
|
'show-stats',
|
|
null,
|
|
InputOption::VALUE_NONE,
|
|
'Use this option to display the stats of the tweets fetched'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Used in various areas to set name of the network being searched.
|
|
*
|
|
* @return string twitter|facebook etc..
|
|
*/
|
|
abstract public function getNetworkName();
|
|
|
|
/**
|
|
* Search for tweets by creating your own search criteria.
|
|
*
|
|
* @param Monitoring $monitor
|
|
*
|
|
* @return array The results of makeRequest
|
|
*/
|
|
abstract protected function getTweets($monitor);
|
|
|
|
/**
|
|
* Main execution method. Gets the integration settings, processes the search criteria.
|
|
*/
|
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
|
{
|
|
$this->input = $input;
|
|
$this->output = $output;
|
|
$this->maxRuns = $this->input->getOption('max-runs');
|
|
$this->queryCount = $this->input->getOption('query-count');
|
|
$twitterIntegration = $this->integrationHelper->getIntegrationObject('Twitter');
|
|
|
|
if (false === $twitterIntegration || false === $twitterIntegration->getIntegrationSettings()->getIsPublished()) {
|
|
$this->output->writeln($this->translator->trans('mautic.social.monitoring.twitter.not.published'));
|
|
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
\assert($twitterIntegration instanceof TwitterIntegration);
|
|
$this->twitter = $twitterIntegration;
|
|
|
|
if (!$this->twitter->isAuthorized()) {
|
|
$this->output->writeln($this->translator->trans('mautic.social.monitoring.twitter.not.configured'));
|
|
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
// get the mid from the cli
|
|
$mid = (int) $input->getOption('mid');
|
|
|
|
if (!$mid) {
|
|
$this->output->writeln($this->translator->trans('mautic.social.monitoring.twitter.mid.empty'));
|
|
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
$this->twitterCommandHelper->setOutput($output);
|
|
|
|
$monitor = $this->twitterCommandHelper->getMonitor($mid);
|
|
|
|
if (!$monitor || !$monitor->getId()) {
|
|
$this->output->writeln($this->translator->trans('mautic.social.monitoring.twitter.monitor.does.not.exist', ['%id%' => $mid]));
|
|
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
// process the monitor
|
|
$this->processMonitor($monitor);
|
|
|
|
$this->dispatcher->dispatch(
|
|
new SocialMonitorEvent($this->getNetworkName(), $monitor, $this->twitterCommandHelper->getManipulatedLeads(), $this->twitterCommandHelper->getNewLeadsCount(), $this->twitterCommandHelper->getUpdatedLeadsCount()),
|
|
SocialEvents::MONITOR_POST_PROCESS
|
|
);
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* Process the monitor record.
|
|
*
|
|
* @Note: Keeping this method here instead of in the twitterCommandHelper
|
|
* so that the hashtag and mention commands can easily extend it.
|
|
*
|
|
* @param Monitoring $monitor
|
|
*
|
|
* @return bool
|
|
*/
|
|
protected function processMonitor($monitor)
|
|
{
|
|
$results = $this->getTweets($monitor);
|
|
|
|
if (false === $results || !isset($results['statuses'])) {
|
|
$this->output->writeln('No statuses found');
|
|
|
|
if (!empty($results['errors'])) {
|
|
foreach ($results['errors'] as $error) {
|
|
$this->output->writeln($error['code'].': '.$error['message']);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (count($results['statuses'])) {
|
|
$this->twitterCommandHelper->createLeadsFromStatuses($results['statuses'], $monitor);
|
|
} else {
|
|
$this->output->writeln($this->translator->trans('mautic.social.monitoring.twitter.no.new.tweets'));
|
|
}
|
|
|
|
$this->twitterCommandHelper->setMonitorStats($monitor, $results['search_metadata']);
|
|
$this->printInformation($monitor, $results);
|
|
|
|
// get stats after being updated
|
|
$stats = $monitor->getStats();
|
|
|
|
++$this->runCount;
|
|
|
|
// if we have stats and a next results request, process it here
|
|
// @todo add a check for max iterations
|
|
if (is_array($stats) && array_key_exists('max_id_str', $stats)
|
|
&& ($this->runCount < $this->maxRuns)
|
|
&& count($results['statuses'])
|
|
) {
|
|
// recursive
|
|
$this->processMonitor($monitor);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Prints all the returned tweets.
|
|
*
|
|
* @param array $statuses
|
|
*/
|
|
protected function printTweets($statuses)
|
|
{
|
|
if (!$this->input->getOption('show-posts') && $this->output->getVerbosity() < OutputInterface::VERBOSITY_VERY_VERBOSE) {
|
|
return;
|
|
}
|
|
|
|
foreach ($statuses as $status) {
|
|
$this->output->writeln('-- tweet -- ');
|
|
$this->output->writeln('ID: '.$status['id']);
|
|
$this->output->writeln('Message: '.$status['text']);
|
|
$this->output->writeln('Handle: '.$status['user']['screen_name']);
|
|
$this->output->writeln('Name: '.$status['user']['name']);
|
|
$this->output->writeln('Location: '.$status['user']['location']);
|
|
$this->output->writeln('Profile Img: '.$status['user']['profile_image_url']);
|
|
$this->output->writeln('Profile Description: '.$status['user']['description']);
|
|
$this->output->writeln('// tweet // ');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prints the search query metadata from twitter.
|
|
* Only shows stats if explicitly requested or if we're in verbose mode.
|
|
*
|
|
* @param array $metadata
|
|
*/
|
|
protected function printQueryMetadata($metadata)
|
|
{
|
|
if (!$this->input->getOption('show-stats') && $this->output->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) {
|
|
return;
|
|
}
|
|
|
|
$this->output->writeln('-- search meta -- ');
|
|
$this->output->writeln('max_id_str: '.$metadata['max_id_str']);
|
|
$this->output->writeln('since_id_str: '.$metadata['since_id_str']);
|
|
$this->output->writeln('Page Count: '.$metadata['count']);
|
|
$this->output->writeln('query: '.$metadata['query']);
|
|
|
|
if (array_key_exists('next_results', $metadata)) {
|
|
$this->output->writeln('next results: '.$metadata['next_results']);
|
|
}
|
|
|
|
$this->output->writeln('// search meta // ');
|
|
}
|
|
|
|
/**
|
|
* Prints a summary of the search query.
|
|
* Only shows stats if explicitly requested or if we're in verbose mode.
|
|
*
|
|
* @param Monitoring $monitor
|
|
* @param array $results
|
|
*/
|
|
protected function printInformation($monitor, $results)
|
|
{
|
|
if (!$this->input->getOption('show-stats') && $this->output->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) {
|
|
return;
|
|
}
|
|
|
|
$this->output->writeln('------------------------');
|
|
$this->output->writeln($monitor->getTitle());
|
|
$this->output->writeln('Published '.$monitor->isPublished());
|
|
$this->output->writeln($monitor->getNetworkType());
|
|
$this->output->writeln('New Leads '.$this->twitterCommandHelper->getNewLeadsCount());
|
|
$this->output->writeln('Updated Leads '.$this->twitterCommandHelper->getUpdatedLeadsCount());
|
|
$this->printQueryMetadata($results['search_metadata']);
|
|
$this->printTweets($results['statuses']);
|
|
$this->output->writeln('------------------------');
|
|
}
|
|
}
|