How to use Sugarcrm\Sugarcrm\Util\Uuid::uuid1() in a custom entry point? - sugarcrm

I am learning suitecrm. I need to create a new bean using a specific id from a custom entry point, generating the id is not working, when i try this code
// Create bean
$testAccountBean = BeanFactory::newBean('Accounts');
// Set the new flag
$testAccountBean->new_with_id = true;
$id = Sugarcrm\Sugarcrm\Util\Uuid::uuid1();
$testAccountBean->id = $id;
$testAccountBean->name = generateRandomString();
$testAccountBeanId = $testAccountBean->save();
echo $testAccountBeanId;
I get nothing
When I inspect the result of calling Sugarcrm\Sugarcrm\Util\Uuid::uuid1() nothing get in return.
Thanks for any idea

The function is called create_guid, require the include/utils.php and you will be able to call it.
<?php
if (!defined('sugarEntry')) {
define('sugarEntry', true);
}
require_once 'data/BeanFactory.php';
require_once 'include/utils.php';
$testAccountBean = BeanFactory::newBean('Accounts');
$id = create_guid();
Having said so - If you do $testAccountBean->new_with_id = true; it means you will provide your own ID, we use that to insert IDs from other systems/migrations. But if you need the GUID just remove that line and suitecrm will generate it for you.

You will need to call it in following manner:
$testAccountBean->new_with_id = true;
$testAccountBean->id = create_guid();
Note that if you assigned your own ID using create_guid function then "new_with_id" need to be set as well. You can find function at this path: include\utils.php
Following is the function body:
function create_guid()
{
$microTime = microtime();
list($a_dec, $a_sec) = explode(' ', $microTime);
$dec_hex = dechex($a_dec * 1000000);
$sec_hex = dechex($a_sec);
ensure_length($dec_hex, 5);
ensure_length($sec_hex, 6);
$guid = '';
$guid .= $dec_hex;
$guid .= create_guid_section(3);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= $sec_hex;
$guid .= create_guid_section(6);
return $guid;
}

Related

How to loop the result from findnodes() with HTML::TreeBuilder::XPath

I have my script to monitor some Facebook pages. Since Facebook API banned page public access permission on 4-SEP-2019. I need to parse the content by xpath method.
Each Facebook post is wrap by div[contains(#class,"userContentWrapper")]. I would like to loop posts one by one to find a desired data.
I don't known why $message = $post->findvalue('//div[#data-testid="post_message"]//p'); show all text in <p> of every posts.
use LWP::UserAgent;
$ua = new LWP::UserAgent;
$request = new HTTP::Request;
$request->url('https://www.facebook.com/pg/FIFA/posts/');
$request->method('GET');
$request->header('User-Agent' => 'Mozilla/5.0 Chrome/71.0.3578.98 Safari/537.36');
$response = $ua->request($request);
open(HTM, ">zzz.htm");
print HTM $response->content;
close(HTM);
use HTML::TreeBuilder::XPath;
$tree = HTML::TreeBuilder::XPath->new_from_content($response->content);
$posts = $tree->findnodes('//div[contains(#class,"userContentWrapper")]');
for my $post (#{$posts})
{
$id = $post->findnodes('//div[#data-testid="story-subtitle"]/#id');
$id = $id->[0]->getValue;
print "id = $id\n\n";
$object_id = $post->findnodes('//div[#data-testid="story-subtitle"]//a/#href');
$object_id = 'https://www.facebook.com' . $object_id->[0]->getValue;
print "object_id = $object_id\n\n";
$message = $post->findvalue('//div[#data-testid="post_message"]//p');
# $message = $message->[0]->getValue;
print "$message\n\n";
$ajaxify = $post->findnodes('//div[#class="mtm"]//a/#ajaxify');
$ajaxify = $ajaxify->[0]->getValue;
print "ajaxify = $ajaxify\n\n";
$ploi = $post->findnodes('//div[#class="mtm"]//a/#data-ploi');
$ploi = $ploi->[0]->getValue;
print "ploi = $ploi\n\n";
# $plsi = $post->findnodes('//div[#class="mtm"]//a/#data-plsi');
# $plsi = $plsi->[0]->getValue;
# print "plsi = $plsi\n\n";
$href = $post->findnodes('//div[#class="mtm"]//a/#href');
$href = 'https://www.facebook.com' . $href->[0]->getValue;
print "href = $href\n\n";
print "---------------------------------------------------------\n\n";
}
The post is unclear and it seems to contain multiple questions. This needs to be fixed, but in the mean time, I'll address the following:
I would like to loop posts one by one to find a desired data.
From HTML::TreeBuilder::XPath,
findnodes ($path)
Returns a list of nodes found by $path. In scalar context returns an Tree::XPathEngine::NodeSet object.
From Tree::XPathEngine::NodeSet,
get_nodelist()
Returns a list of nodes. See Tree::XPathEngine::XMLParser for the format of the nodes.
So,
my #posts = $tree->findnodes('...');
for my $post (#posts) { ... }
or
my $posts = $tree->findnodes('...');
for my $post ($posts->get_nodelist()) { ... }
Any other questions should be posted as separate Questions.

How correctly to use the snippet() function?

My first Sphinx app almost works!
I successfully save path,title,content as attributes in index!
But I decided go to SphinxQL PDO from AP:
I found snippets() example thanks to barryhunter again but don't see how use it.
This is my working code, except snippets():
$conn = new PDO('mysql:host=ununtu;port=9306;charset=utf8', '', '');
if(isset($_GET['query']) and strlen($_GET['query']) > 1)
{
$query = $_GET['query'];
$sql= "SELECT * FROM `test1` WHERE MATCH('$query')";
foreach ($conn->query($sql) as $info) {
//snippet. don't works
$docs = array();
foreach () {
$docs[] = "'".mysql_real_escape_string(strip_tags($info['content']))."'";
}
$result = mysql_query("CALL SNIPPETS((".implode(',',$docs)."),'test1','" . mysql_real_escape_string($query) . "')",$conn);
$reply = array();
while ($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$reply[] = $row['snippet'];
}
// path, title out. works
$path = rawurlencode($info["path"]); $title = $info["title"];
$output = '<a href=' . $path . '>' . $title . '</a>'; $output = str_replace('%2F', '/', $output);
print( $output . "<br><br>");
}
}
I have got such structure from Sphinx index:
Array
(
[0] => Array
(
[id] => 244
[path] => DOC7000/zdorovie1.doc
[title] => zdorovie1.doc
[content] => Stuff content
I little bit confused with array of docs.
Also I don't see advice: "So its should be MUCH more efficient, to compile the documents and call buildExcepts just once.
But even more interesting, is as you sourcing the the text from a sphinx attribute, can use the SNIPPETS() sphinx function (in setSelect()!) in the main query. SO you dont have to receive the full text, just to send back to sphinx. ie sphinx will fetch the text from attribute internally. even more efficient!
"
Tell me please how I should change code for calling snippet() once for docs array, but output path (link), title for every doc.
Well because your data comes from sphinx, you can just use the SNIPPET() function (not CALL SNIPPETS()!)
$query = $conn->quote($_GET['query']);
$sql= "SELECT *,SNIPPET(content,$query) AS `snippet` FROM `test1` WHERE MATCH($query)";
foreach ($conn->query($sql) as $info) {
$path = rawurlencode($info["path"]); $title = $info["title"];
$output = '<a href=' . $path . '>' . $title . '</a>'; $output = str_replace('%2F', '/', $output);
print("$output<br>{$info['snippet']}<br><br>");
}
the highlighted text is right there in the main query, dont need to mess around with bundling the data back up to send to sphinx.
Also shows you should be escaping the raw query from user.
(the example you found does that, because the full text comes fom MySQL - not sphinx - so it has no option but to mess around sending data back and forth!)
Just for completeness, if REALLY want to use CALL SNIPPETS() would be something like
<?php
$query =$conn->quote($_GET['query']);
//make query request
$sql= "SELECT * FROM `test1` WHERE MATCH($query)";
$result = $conn->query($sql);
$rows = $result->fetchAll(PDO::FETCH_ASSOC);
//build list of docs to send
$docs = array();
foreach ($rows as $info) {
$docs[] = $conn->quote(strip_tags($info['content']));
}
//make snippet reqest
$sql = "CALL SNIPPETS((".implode(',',$docs)."),'test1',$query)";
//decode reply
$reply = array();
foreach ($conn->query($sql) as $row) {
$reply[] = $row['snippet'];
}
//output results using $rows, and cross referencing with $reply
foreach ($rows as $idx => $info) {
// path, title out. works
$path = rawurlencode($info["path"]); $title = $info["title"];
$output = '<a href=' . $path . '>' . $title . '</a>'; $output = str_replace('%2F', '/', $output);
$snippet = $reply[$idx];
print("$output<br>$snippet<br><br>");
}
Shows putting the rows into an array, because need to lopp though the data TWICE. Once to 'bundle' up the docs array to send. Then again to acully display rules, when have $rows AND $reply both available.

Typo3 Scheduler - Command Controller: I can't execute a command that uses class repositories of my extension

Yesterday i finally got my Typo3 Scheduler working the way i want. Mostly it was the implementation of the CommandController into my extension that was a little bit "problematic".
Now i have another question regarding the Scheduler and the CommandController specifically. I have the following code. It's an Action i have implemented in the controller of a class of my extension:
public function simpleCommand()
{
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$apprep = $objectManager->get(\Cjk\Icingaconfgen\Domain\Repository\HostRepository::class);
$hosts = $apprep->findAll();
$objectManager2 = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$apprep2 = $objectManager2->get(\Cjk\Icingaconfgen\Domain\Repository\ServicesRepository::class);
$services = $apprep2->findAll();
foreach($hosts as $host)
{
$name = $host->getUid();
$address = $host->getIpv4();
$file = '/etc/icinga2/conf.d/hosts/' . $name . '.conf';
$code_a = 'object Host "';
$code_b = '" {
import "generic-host"
address = "';
$code_c = '"
vars.notification["mail"] = {
groups = [ "icingaadmins" ]
}
}';
$fp = fopen("{$file}", 'wb');
fwrite($fp, $code_a . $name . $code_b . $address . $code_c);
fclose($fp);
mkdir('/etc/icinga2/conf.d/hosts/' . $name);
foreach($services as $service)
{
if($service->getHost() == $name)
{
$name = $host->getUid();
$chkcmd = 'http';
$file = '/etc/icinga2/conf.d/hosts/'.$name.'/' . $name . '-service.conf';
$code_a = 'object Service "';
$code_b = '" {
import "generic-service"
host_name = "';
$code_c = '"
check_command = "http"
}';
$fp = fopen("{$file}", 'wb');
fwrite($fp, $code_a . $name.'-service'. $code_b . $name . $code_c);
fclose($fp);
}
}
exec('sudo /etc/init.d/icinga2 restart');
}
}
This is the way i implemented the code in the CommandController, but in a similar way it is also implementd in my Action in the Class Controller. Now, what this function does is simply generating a specific file i need to use in another application. The function gets the repsitory of the class "Host" and then finds all objects of it. Then it just uses the properties of each object to generate the beforementioned files. It does the same with the class "services".
In the frontend through the Action the code works perfectly and generates the files, but in the CommandController, executed automatically through the Scheduler it simply doesn't work.
Is there a missunderstanding on my side? Can't i access each class repository via a command or rather: "Are the repositories only accessable via an Action?"
Or is there another error?
I guess the reason here, is the difference between frontend and backend context.This answer here, from a different context, sums it up very nice and is worth a read
Basically, in the frontend context, you have the typoscript configuration, telling the repository where to store and find records. That is not present in the backend context. That is explained in the answer above with this code
module.tx_yourext.persistence < plugin.tx_yourext.persistence
As it didn't work with the CommandController for my specific case and i had no access to the persistence layer with with it, not even with dependency injection, i decided to not use CommandContoller tasks at all, but rather the normal Scheduler task for it. The biggest problem i encountered was to actually use the findAll() function for the repositories (it worked with findByUid(). This was because the repository expects a storage page by default. As i don’t have a module nor a plugin, my typoscript settings were ignored in that case.
So i had to set the repository to disrespect the storage page in my task. Here the code:
<?php
namespace Cjk\Icingaconfgen\Tasks;
class TestTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
{
public function execute() {
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
/** #var CustomerRepository $apprep */
$apprep = $objectManager->get(\Cjk\Icingaconfgen\Domain\Repository\HostRepository::class);
/** #var Typo3QuerySettings $querySettings */
$querySettings = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
$querySettings->setRespectStoragePage(FALSE);
$apprep->setDefaultQuerySettings($querySettings);
$hosts = $apprep->findAll();
/** #var CustomerRepository $apprep2 */
$apprep2 = $objectManager->get(\Cjk\Icingaconfgen\Domain\Repository\ServicesRepository::class);
/** #var Typo3QuerySettings $querySettings */
$querySettings = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
$querySettings->setRespectStoragePage(FALSE);
$apprep2->setDefaultQuerySettings($querySettings);
$services = $apprep2->findAll();
foreach($hosts as $host)
{
$name = $host->getUid();
$address = $host->getIpv4();
$file = '/etc/icinga2/conf.d/hosts/' . $name . '.conf';
$code_a = 'object Host "';
$code_b = '" {
import "generic-host"
address = "';
$code_c = '"
vars.notification["mail"] = {
groups = [ "icingaadmins" ]
}
}';
$fp = fopen("{$file}", 'wb');
fwrite($fp, $code_a . $name . $code_b . $address . $code_c);
fclose($fp);
mkdir('/etc/icinga2/conf.d/hosts/' . $name);
foreach($services as $service)
{
if($service->getHost() == $name)
{
$name = $host->getUid();
$chkcmd = 'http';
$file = '/etc/icinga2/conf.d/hosts/'.$name.'/' . $name . '-service.conf';
$code_a = 'object Service "';
$code_b = '" {
import "generic-service"
host_name = "';
$code_c = '"
check_command = "http"
}';
$fp = fopen("{$file}", 'wb');
fwrite($fp, $code_a . $name.'-service'. $code_b . $name . $code_c);
fclose($fp);
}
}
exec('sudo /etc/init.d/icinga2 restart');
}
return TRUE;
}
}

How can set up the table correctly for receiving the string converted from dates?

I have a problem and don't know how to solve it. After i run the code i didn't receive corectly a period of time. I put the code here.
I think something is wrong with table from database (i use PhpMyAdmin 4.2.0 module from EasyPhp). I put an image too to see what happens. The dates marked with red need to be at the end of table.
<?php
function data_range($first, $last, $step = '+1 day', $output - format = 'd-m-Y')
{
$dates = array();
$current = strtotime($first);
$last = strtotime($last);
while ($current <= $last)
{
$dates[] = date($output_format, $current);
$current = strtotime($step, $current);
}
foreach($dates as $zile)
{
$krr = explode('-', $zile);
var_dump($krr);
$result2 = implode('/', $krr);
echo $result2 . "<br/>";
$sql4 = "INSERT INTO studenti3 (data) VALUES ('$result2')";
$rez4 = mysql_query($sql4);
}
var_dump($dates);
}
$first = "06-04-2015";
$last = "07-05-2015";
$step = "+1day";
$output_format = 'd-m-Y';
date_range($first, $last, $step, $output_format); ?>

replace text with url in twitter feed

I have this code:
public function linkify($status_text)
{
$status_text = preg_replace('/(https?:\/\/\S+)/','\1', $status_text);
$status_text = preg_replace('/(^|\s)#(\w+)/','\1#\2',$status_text);
$status_text = preg_replace('/(^|\s)#(\w+)/','\1#\2',$status_text);
return $status_text;
}
and display feeds from twitter like this
foreach($feed as $feed_item) {
$html .= '<li>';
$html .= '' . $this->linkify($feed_item->text) . '';
$html .= '' . $this->relativedate((strtotime($feed_item->created_at))) . '';
$html .= '</li>';
}
echo $html;
result of this code is
<li>Twitter Feed Text http://t.co/TnkNfxCdRu</li>
if anyone can help me, how can I add text inside tag <a></a>. for example, to be exactly like this:
<li>Twitter Feed Text</li>
Thank you so much
Just change your first preg_replace to:
$status_text = preg_replace('~(https?://(\S+))~','$2',$status_text);