Composer Package (PHPLeague) in Codeigniter loading class - php

I am aiming to use the following package for my project Color Extractor.
I have composer working and setup in my project fine as per #philsturgeon's tutorial here, however I am stuck as the function returns an empty array for an image I know is there.
I am autoloading in the index.php using require FCPATH.'vendor/autoload.php';
And I have tested this using Phil's example.
My Code looks like this:
$client = new League\ColorExtractor\Client();
$image = $client->loadJpeg(FCPATH.'assets/images/tumblr_ma7gmzwfAq1r780z3o1_250.jpg');
// Get the most used color hex code
$palette = $image->extract();
// Get three most used color hex code
$palette = $image->extract(3);
// Change the Minimum Color Ratio (0 - 1)
// Default: 0
$image->setMinColorRatio(1);
$palette = $image->extract();
var_dump($palette);
Can anyone tell me what I am doing wrong here as I don't have any errors in my log and I get the standard output.
array(0) { }

I was being utterly stupid apologies for anyone who viewed this question I was trying to declare multiple variables with the same name and variants of the function.
My final code looks like
$client = new League\ColorExtractor\Client();
$image = $client->loadJpeg(FCPATH.'assets/images/tumblr_ma7gmzwfAq1r780z3o1_250.jpg');
$palette = $image->extract(3);
var_dump($palette);
Which returns an expected array like this.
array(3) { [0]=> string(7) "#E09D73" [1]=> string(7) "#AC4C34" [2]=>
string(7) "#EEDF6C" }

Related

Puphpeteer - Get text and href-attribute from link

I am using "#nesk/puphpeteer": "^2.0.0" Link to Github-Repo and want get the text and the href-attribute from a link.
I tried the following:
<?php
require_once '../vendor/autoload.php';
use Nesk\Puphpeteer\Puppeteer;
use Nesk\Rialto\Data\JsFunction;
$debug = true;
$puppeteer = new Puppeteer([
'read_timeout' => 100,
'debug' => $debug,
]);
$browser = $puppeteer->launch([
'headless' => !$debug,
'ignoreHTTPSErrors' => true,
]);
$page = $browser->newPage();
$page->goto('http://example.python-scraping.com/');
//get text and link
$links = $page->querySelectorXPath('//*[#id="results"]/table/tbody/tr/td/div/a', JsFunction::createWithParameters(['node'])
->body('return node.textContent;'));
// iterate over links and print each link and its text
// get single text
$singleText = $page->querySelectorXPath('//*[#id="pagination"]/a', JsFunction::createWithParameters(['node'])
->body('return node.textContent;'));
$browser->close();
When I run the above script I get the nodes from the page, BUT I cannot access the attributes or the text?
Any suggestions how to do this?
I appreciate your replies!
querySelectorXPath return array of ElementHandle. one more thing querySelectorXPath does not support callback function.
first get all node ElementHandle
$links = $page->querySelectorXPath('//*[#id="results"]/table/tbody/tr/td/div/a');
then loop over links to access attributes or text of node
foreach($links as $link){
// for text
$text = $link->evaluate(JsFunction::createWithParameters(['node'])
->body('return node.innerText;'));
// for link
$link = $link->evaluate(JsFunction::createWithParameters(['node'])
->body('return node.href;'));
}
Disclaimer: This is just an intermediate answer - I would update once I've got more specific requests on HTML attrs or other expectations to be retrieved.
tl;dr: Mentioned composer package nesk/puphpeteer really is just a wrapper to underlying NodeJS based implementation of puppeteer. Thus, accessing data and structures has to be "similar" to their JavaScript counterparts...
Maybe Codeception (headless) or symfony/dom-crawler (raw markup) might be better and more mature alternatives.
Anyway, let's pick the example from above and go through it step by step:
$links = $page->querySelectorXPath(
'//*[#id="results"]/table/tbody/tr/td/div/a',
JsFunction::createWithParameters(['node'])->body('return node.textContent;')
);
XPath query $x() would result in an array of ElementHandle items
to access exported node.textContent (from JsFunction), corresponding data gets fetched via ElementHandle.getProperty(prop)
exporting a scalar value (to PHP) is then done via ElementHandle.jsonValue()
Thus, after that we would have something like this:
$links = $page->querySelectorXPath(
'//*[#id="results"]/table/tbody/tr/td/div/a',
JsFunction::createWithParameters(['node'])->body('return node.textContent;')
);
/** #var \Nesk\Puphpeteer\Resources\ElementHandle $link */
foreach ($links as $link) {
var_dump($link->getProperty('textContent')->jsonValue());
}
Which outputs the following raw data (as retrieved from http://example.python-scraping.com/):
string(12) " Afghanistan"
string(14) " Aland Islands"
string(8) " Albania"
string(8) " Algeria"
string(15) " American Samoa"
string(8) " Andorra"
string(7) " Angola"
string(9) " Anguilla"
string(11) " Antarctica"
string(20) " Antigua and Barbuda"

How to sort Japanese like Excel

I want to sort Japanese words ( Kanji) like sort feature in excel.
I have tried many ways to sort Japanese text in PHP but the result is not 100% like result in excel.
First . I tried to convert Kanji to Katakana by using this lib (https://osdn.net/projects/igo-php/) but some case is not same like excel.
I want to sort these words ASC
けやきの家
高森台病院
みのりの里
My Result :
けやきの家
高森台病院
みのりの里
Excel Result:
けやきの家
みのりの里
高森台病院
Second I tried other way by using this function
mb_convert_kana($text, "KVc", "utf-8");
The sorting result is correct with those text above, but it contain some case not correct
米田病院
米田病院
高森台病院
My result :
米田病院
米田病院
高森台病院
Excel Result:
高森台病院
米田病院
米田病院
Do you guys have any idea about this. (Sorry for my English ) . Thank you
Firstly, Japanese kanji are not sortable. You can sort by its code number, but that order has no meanings.
Your using Igo (or any other morphological analysis libraries) sounds good solution, though it can not be perfect. And your first sort result seems fine for me. Why do you want them to be sorted in Excel order?
In Excel, if a cell keeps remembering its phonetic notations when the user initially typed on Japanese IME (Input Method Editor), that phonetics will be used in sort. That means, as not all cell might be typed manually on IME, some cells may not have information how those kanji-s are read. So results of sorting Kanji-s on Excel could be pretty unpredictable. (If sort seriously needed, usually we add another yomigana field, either in hiragana or katakana, and sort by that column.)
The second method mb_convert_kana() is totally off point. That function is to normalize hiragana/katakana, as there are two sets of letters by historical reason (full-width kana and half-width kana). Applying that function to your Japanese texts only changes kana parts. If that made your expectation satisfied, that must be coincidence.
You must define what Excel Japanese sort order your customer requires first. I will be happy to help you if it is clear.
[Update]
As op commented, mb_convert_kana() was to sort mixed hiragana/katakana. For that purpose, I suggest to use php_intl Collator. For example,
<?php
// demo: Japanese(kana) sort by php_intl Collator
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
exit ('php_intl extension is available on PHP 5.3.0 or later.');
}
if (!class_exists('Collator')) {
exit ('You need to install php_intl extension.');
}
$collator = new Collator('ja_JP');
$textArray = [
'カキクケコ',
'日本語',
'アアト',
'Alphabet',
'アイランド',
'はひふへほ',
'あいうえお',
'漢字',
'たほいや',
'さしみじょうゆ',
'Roma',
'ラリルレロ',
'アート',
];
$result = $collator->sort($textArray);
if ($result === false) {
echo "sort failed" . PHP_EOL;
exit();
}
var_dump($textArray);
This sorts hiragana/katakana mixed texts array. Results are here.
array(13) {
[0]=>
string(8) "Alphabet"
[1]=>
string(4) "Roma"
[2]=>
string(9) "アート"
[3]=>
string(9) "アアト"
[4]=>
string(15) "あいうえお"
[5]=>
string(15) "アイランド"
[6]=>
string(15) "カキクケコ"
[7]=>
string(21) "さしみじょうゆ"
[8]=>
string(12) "たほいや"
[9]=>
string(15) "はひふへほ"
[10]=>
string(15) "ラリルレロ"
[11]=>
string(6) "漢字"
[12]=>
string(9) "日本語"
}
You won't need to normalize them by yourself. Both PHP(though with php_intl extension) and database(such like MySQL) know how to sort alphabets in many languages so you do not need to write it.
And, this does not solve the original issue, Kanji sort.
Laravel Alpha to Hiragana with a custom function
Note : $modals (laravel models with get() )
alphabets : Hiragana orders
Source : https://gist.github.com/mdzhang/899a427eb3d0181cd762
public static function orderByHiranagana ($modals,$column){
$outArray = array();
$alphabets = array("a","i","u","e","o","ka","ki","ku","ke","ko","sa","shi","su","se","so","ta","chi","tsu","te","to","na","ni","nu","ne","no","ha","hi","fu","he","ho","ma","mi","mu","me","mo","ya","yu","yo","ra","ri","ru","re","ro","wa","wo","n","ga","gi","gu","ge","go","za","ji","zu","ze","zo","da","ji","zu","de","do","ba","bi","bu","be","bo","pa","pi","pu","pe","po","(pause)","kya","kyu","kyo","sha","shu","sho","cha","chu","cho","nya","nyu","nyo","hya","hyu","hyo","mya","myu","myo","rya","ryu","ryo","gya","gyu","gyo","ja","ju","jo","bya","byu","byo","pya","pyu","pyo","yi","ye","va","vi","vu","ve","vo","vya","vyu","vyo","she","je","che","swa","swi","swu","swe","swo","sya","syu","syo","si","zwa","zwi","zwu","zwe","zwo","zya","zyu","zyo","zi","tsa","tsi","tse","tso","tha","ti","thu","tye","tho","tya","tyu","tyo","dha","di","dhu","dye","dho","dya","dyu","dyo","twa","twi","tu","twe","two","dwa","dwi","du","dwe","dwo","fa","fi","hu","fe","fo","fya","fyu","fyo","ryi","rye","(wa)","wi","(wu)","we","wo","wya","wyu","wyo","kwa","kwi","kwu","kwe","kwo","gwa","gwi","gwu","gwe","gwe","mwa","mwi","mwu","mwe","mwo");
$existIds = array();
foreach ($alphabets as $alpha){
foreach ($modals as $modal) {
if($alpha == strtolower(substr($modal->$column, 0, strlen($alpha))) && !in_array($modal->id,$existIds)) {
array_push($outArray,$modal);
array_push($existIds,$modal->id);
}
}
}
return $outArray;
}
Call like this :
$students = Students::get();
$students = CommonHelper::orderByHiranagana($students,'lastname');

How to convert String(16) to Int(1) in php

For instance
<div ng-repeat = 'list in lists'>
<?php
$user_post_id = "{{list.user.id}}"; //this syntax works
var_dump($user_post_id); // gives String(16) '1'
$user_post_int_id = (int)$user_post_id; // change from string to int
var_dump($user_post_int_id); // gives int(1) 0, I don't know why isn't type conversion working!
echo $user_post_id; // echoes out 1
echo $user_post_int_id; //echoes out the 0
So the main problem I think is of type conversion, as I tried one more thing where String(1) is converting to int(1) with no problem but with string(16) everything blows apart and results to 0.
i got 3 suggestion 4u (on my server all works fine)
as a original with my comments:
<div ng-repeat = 'list in lists'>
<?php
$user_post_id = "{{list.user.id}}"; //this syntax works
var_dump($user_post_id); // gives String(16) '1'
$user_post_int_id = (int)$user_post_id; // change to int
var_dump($user_post_int_id);
// gives int(1) 1, is not test your php/server conf!
echo $user_post_id; // echoes out 1
echo $user_post_int_id; //echoes out 1
then i advise you to try with your code, run on your server with changes:
replace $user_post_id = "{{list.user.id}}";
to $user_post_id = (int){{list.user.id}};
//hopes your php wudn't show an error
replace $user_post_int_id = (int)$user_post_id;
to $user_post_int_id = floor((int)$user_post_id);
or $user_post_int_id = ceil((int)$user_post_id);
replace $user_post_id = "{{list.user.id}}";
to $user_post_id = (int)({{list.user.id}}) + 1 ;
or plus zero, these hack sometimes works for me !
p.s. (int) can do a trick with you, php can thout that you uses hex bin or smth else. retest it twice !
php.net/manual/en/language.types.integer.php
php.net/manual/en/language.types.type-juggling.php
You cannot use Angular expression inside a server side statements, as Angular statement runs on client side after running all server logic.
In your code:
<div ng-repeat = 'list in lists'>
<?php
$user_post_id = "{{list.user.id}}" //list.user.id is a JS variable, you cannot use it in PHP.
$user_post_int_id = (int)$user_post_id; // something wrong here, you do not need this step, normally if you retrieved the code from server side.
{{ $user_post_int_id }} //this should not work
But still this blade function fails
#if(Auth::user()->id == $user_post_int_id)
do something //returns false, makes alot of sense, as again you are trying to get variables from JS and passing them to PHP scripts. This will never work.
#endif

Getting a list of Contacts from Acumatica Web Services API using PHP

I'm trying to use the Acumatica Web Services API to get a list of Contacts (really I'm looking to get ANYTHING, but Contacts are what I'm playing with right now).
I'm successfully able to get a SoapClient connected, but not sure what exactly to do from there to pull a list of all Contacts.
Seeing how you didn't specify Acumatica version or Webservices I'm assuming you are trying to use the "Screen WebAPI" that was in 5.2 and earlier and not the new "Contract Based API" in 5.3
With that in mind, here is an example of how to make the connection and retrieve a list of all of the contacts.
The first step is to utilize the "acuwsdl2php" helper file to generate the needed screen helper classes for PHP.
In the case of contacts:
php acuwsdl2php.php {url of your site}/Soap/CR302000.asmx?WSDL CR302000
This will create the CR302000 subfolder with a Screen.php file that is the php equivalent of the schema for the screen.
Second, here is a sample class that retrieves contact information
<?php
require_once('AcumaticaGate.php');
$client = new AcumaticaGate('{user}', '{password}', 'CR302000','{site}/Soap/');
$Contact_summary = $client->Schema->GetSchemaResult->ContactSummary;
$Contact_detailsummary = $client->Schema->GetSchemaResult->DetailsSummary;
$every_Contact = $Contact_summary->ServiceCommands->EveryContactID;
$Contact = $Contact_summary->ContactID;
$Contact_fname = $Contact_detailsummary->FirstName;
$Contact_lname = $Contact_detailsummary->LastName;
$export_param = new Export();
$export_param->commands = array($every_Contact, $Contact, $Contact_fname, $Contact_lname);
$export_param->filters = array();
$export_param->breakOnError = false;
$export_param->includeHeaders = true;
$export_param->topCount = 0;
$export = $client->Client->Export($export_param);
print_r(var_dump($export));
The output here is something like this:
[177]=>
object(stdClass)#562 (1) {
["string"]=>
array(3) {
[0]=>
string(3) "358"
[1]=>
string(4) "Anna"
[2]=>
string(7) "Johnson"
}
}
[178]=>
object(stdClass)#563 (1) {
["string"]=>
array(3) {
[0]=>
string(3) "359"
[1]=>
string(4) "Yona"
[2]=>
string(5) "Jones"
}
}
The acuwsdl2php and AcumaticaGate files are helper files that Acumatica provided to partners. They might also be available on the client portal for download. A quick google for them though and I believe you can find them on a few public sites.
As a side note, these helper files were originally written for 4.x. You should look at the 5.x guides (assuming you have 5.x) for added information on logging off of a webapi when finished calling it.

MongoDB MapReduce returning no data in PHP

I'm using a Mongo MapReduce to perform a word-count operation on a bunch of documents. The documents are very simple (just an ID and a hash of words):
{ "_id" : 6714078, "words" : { "my" : 1, "cat" : 1, "john" : 1, "likes" : 1, "cakes" : 1 } }
{ "_id" : 6715298, "words" : { "jeremy" : 1, "kicked" : 1, "the" : 1, "ball" : 1 } }
{ "_id" : 6717695, "words" : { "dogs" : 1, "can't" : 1, "look" : 1, "up" : 1 } }
The database is called "words" in my environment, the collections in question are named "wordsX" where X is a category number (I know, don't ask). The field in the document hash where the words are stored is also named "words". Gah.
The problem I'm having is that under certain conditions in my PHP app, the MapReduce doesn't return any data. Annoyingly, running the same commands from the Mongo shell gives perfect results. I'm trying to pin down where this bug is occurring but I'm really stumped, so hoping someone might be able to shed some light on this. The lead-up to this question does go on a bit, because the environment is a bit complicated, but please bear with me.
The commands I've tried running from the Mongo shell to replicate the PHP-based operations are as follows:
m = function () {
if (this.words) {
for (index in this.words) {
emit(index, this.words[index]);
}
}
}
r = function (key, values) {
var total = 0;
for (var i in values) {
total += values[i];
}
return total;
}
res = db.words.mapReduce(m, r, { query : { _id : { $in : [6714078,6715298,6717695] } } });
This results in a temporary collection being created containing the word count data. All OK so far.
However if I run the same commands from PHP (using the standard Mongo library), I end up with no data under certain conditions. It's a bit tricky to describe because I don't want to bore you with the details of the application/environment beyond Mongo, but basically I'm using Sphinx to filter some records, then supplying a list of content IDs to Mongo on which the MapReduce is performed. If I filter back into the data set by 2 or 3 days, I get results back from Mongo; if I don't filter, I get an empty dataset back. The PHP code to run the same operation is as follows. I've not included the Sphinx-based parts as I don't think they're relevant (just know that we get a list of IDs back) because I've tried supplying exactly the same list to Mongo on the command line and got the right results, whereas I don't from within PHP. Hope that makes sense.
The PHP code I'm using looks like this:
$objMongo = new Mongo();
$objDB = $objMongo->words;
$arrWordList = array();
$strMap = '
function() {
if (this.words) {
for (index in this.words) {
emit(index, this.words[index]);
}
}
}
';
$strReduce = '
function(key, values) {
var total = 0;
for (var i in values) {
total += values[i];
}
return total;
}
';
$objMapFunc = new MongoCode($strMap);
$objReduceFunc = new MongoCode($strReduce);
$arrQuery = array(
'_id' => array('$in' => $arrIDs) // <--- list of IDs from Sphinx
);
$arrCommand = array(
'mapreduce' => 'wordsX',
'map' => $objMapFunc,
'reduce' => $objReduceFunc,
'query' => $arrQuery
);
MongoCursor::$timeout = -1;
$arrStatsInfo = $objDB->command($arrCommand);
var_dump($arrStatsInfo);
The contents of the result-info array ($arrStatsInfo) under working and non-working conditions (the filtering as specified above) are as follows.
Working results:
array(4) {
["result"]=>
string(31) "tmp.mr.mapreduce_1279637336_227"
["timeMillis"]=>
int(171)
["counts"]=>
array(3) {
["input"]=>
int(54)
["emit"]=>
int(2517)
["output"]=>
int(1526)
}
["ok"]=>
float(1)
}
Empty results:
array(4) {
["result"]=>
string(31) "tmp.mr.mapreduce_1279637381_228"
["timeMillis"]=>
int(21)
["counts"]=>
array(3) {
["input"]=>
int(0)
["emit"]=>
int(0)
["output"]=>
int(0)
}
["ok"]=>
float(1)
}
So it looks like under the broken condition, no records even make it into the MapReduce. I've spent ages trying to work out what on earth is going on here but I've had no insights thus far. As I've said, running the same commands (as above) directly in the Mongo command line using exactly the same set of IDs returns the right results.
After all that, I guess my question is: is there anything obviously wrong with the PHP-Mongo interaction I'm doing above? Are there other steps I can take to try to debug this?
Please let me know if supplying any further information would be helpful. I appreciate this is a somewhat expansive and ill-defined question but I've tried my best to communicate the issue! Really hope someone can suggest a way out of this.
Many thanks for reading!
For future readers, this issue turned out to be the result of inconsistent handling of ints/numeric strings elsewhere in the app. Sorry about the red herring!

Categories