PHP variable assignment in foreach loop - unknown behavior - php

This has me completely stumped. I am using a Cakephp 3.9.6 application and tplaner/When library on PHP 7.4 to generate recurring events. Somewhere, the start and end dates are being set as the same date. Here is the section from my EventsController::add method:
$data = $this->request->getData();
$copies = new When();
$copies->freq($data['frequency'])
->interval($data['interval'])
->wkst('MO');
if ($data['frequency'] == 'WEEKLY') {
$copies->byday(implode(',', $data['days']));
}
if (!empty($data['count'])) {
$copies->count($data['count']);
} else {
$copies->until(new DateTime($data['last_date'] . " 23:59:59"));
}
$copies->startDate(new DateTime($event->start->toDateTimeString()))->generateOccurrences();
$newCopies = $copies->occurrences;
$interval = $event->start->diff($event->end);
foreach ($newCopies as $copy) {
Log::debug($copy); //Shows the next date in the series calculated from start date
if ($copy == $event->start) {
continue; //First event already saved in rest of action, do not create another copy
}
$temp = $event->toArray(); //copy entity details to array
$temp['start'] = $copy; //assign new start time
$start = $copy; //thought maybe due to race condition? Copying to new object to modify end time
$temp['end'] = $start->add($interval); //$interval calculated from original event data, added to new start time
Log::debug($temp);
$result = $this->Events->newEntity($temp); //return to new entity
Log::debug($result);
$events[] = $result; //add to array of entities for saveMany()
}
The problem I have is that the new start date in the array/entity are the same as the end date:
Log::debug($copy) outputs the correct new start date
Log::debug($temp) shows the array, but the start and end properties are the same...

you can not do $start=$copy as they will be the same "object" with different references, you actually want to CLONE $copy so it is a separate object. So when you alter one you do not touch the other

Related

While loop returning duplicate result in php

I am working with a JSON file that is nested and I am employing a JSON pull parser for PHP 7 due to the size of the file. I want to extract data and put them in a csv table as thus:
`FOO ID` `NAME` `UHC` `UHCCOMPANY`
`foo_1403039` `bana` `nege`
`foo_1403039` `baan`
`foo_13589` `anab` `neeg` `nege`
`foo_13590` `naab`
`foo_1403220` `suresh ltd`
`foo_1403223` `suresh ltd`
But then if you notice in the table above, the 1st and 2nd data (foo_1403039) under the first column titled FOO ID are duplicated, and I do not want that. Indeed, if I delete the 1st data under the first column, and shift the cell of that column up by one step, the table looks perfect. Similarly, the last two data (suresh ltd) under the under the second column titled NAME are also duplicate.
I do not know what is wrong in my code. Any help will be appreciated. Here is my dummy json file, and this is my php code:
<?php
require_once 'C:/xampp/htdocs/vendor/autoload.php';
use \pcrov\JsonReader\JsonReader;
ini_set("max_execution_time", 0);
$reader = new JsonReader();
$reader->open("myjsonfile.json");
$fo = fopen("mycsv.csv", "w" );
fputs($fo, "companyID1, name, ultimateHoldingCompany, uhcCountry".PHP_EOL);
while($reader->read()) {
if (preg_match('/^foo_/', $reader->name())){
$companyID = $reader->name();
$companyID1 = str_ireplace("foo_","",$companyID);
if ($reader->read("entityName")){
$entityName = $reader->value();
$entityName = str_ireplace(","," ",$entityName);
}
if ($reader->read("ultimateHoldingCompany")){
$uhcName = null;
$uhcCountry = null;
$ultimateHoldingCompany = $reader->value();
if (empty($ultimateHoldingCompany)){
}
else {
$uhcCountry = $ultimateHoldingCompany[0]['country'];
$uhcName = $ultimateHoldingCompany[0]['name'];
$uhcName = str_ireplace(","," ",$uhcName);
}
}
fputs($fo, $companyID1.",".$entityName.",".$uhcName.",".$uhcCountry.PHP_EOL);
}
}
$reader->close();

Extracting a precise value from a Json array with PHP (like a MySQL db)

another (probably) easy question for you.
As I wrote many times, I'm not a programmer but thanks to you I was able to build an interesting site for my uses.
So again thx.
This is my new problem:
I have a site that recover json data from a file and store it locally once a day (this is the code - I post it so it can be useful to anyone):
// START
findList();
function findList() {
$serverName = strtolower($_POST["Server"]); // GET SERVER FROM FORM POST
$localCoutryList = ("json/$serverName/countries.json"); // LOCAL LOCATIONS OF FILE
$urlCountryList = strtolower("url.from.where.I.get.Json.file.$serverName/countries.json"); // ONLINE LOCATION OF FILE
if (file_exists($localCoutryList)) { // FILE EXIST
$fileLastMod = date("Y/m/d",filemtime($localCoutryList)); // IF FILE LAST MOD = FILE DATE TIME
$now = date('Y/m/d', time()); // NOW
if ($now != $fileLastMod) { // IF NOW != FILE LAST MOD (date)
createList($serverName,$localCoutryList,$urlCountryList); // GO AND CREATE FILE
} else { // IF NOW = FILE LAST MOD (date)
jsonList($serverName,$localCoutryList,$urlCountryList); // CALL JSON DATA FROM FILE
}} else { // FILE DOESN'T EXIST
createList($serverName,$localCoutryList,$urlCountryList); // CALL CREATE FILE
}};
function createList($serverName,$localCoutryList,$urlCountryList) {
file_put_contents($localCountryList, file_get_contents($urlCountryList)); // CREATE FILE
jsonList($serverName); // CALL JSON DATA FROM FILE
};
function jsonList($serverName,$localCoutryList,$urlCountryList) { // JSON DATA FROM FILE
$jsonLoopCountry = file_get_contents($localCoutryList); // GET CONTENT OF THE LOCAL FILE
$outLoopCountry = json_decode($jsonLoopCountry, true); // DECODE JSON FILE
$countryList = $outLoopCountry['country']; // ACCESS TO JSON OBJECT
foreach ($countryList as $dataCountry) { // FOR EACH "COUNTRY" IN JSON DECODED OBJECT
// SET VARS FOR ALL THE COUNTRIES
$iscountryID = ($dataCountry['id']); // TEST
$countryCurrency = ($dataCountry['curr']); // TEST
$countryName = ($dataCountry['name']);} // TEST
echo "<br>total country list: ".count($countryList); // THIS RETURN TOTAL ELEMENTS IN THE ARRAY
[...]
The kind of Json data I'm working with is structured as it follows:
{"country":[{"id":130,"curr":"AFN","name":"Afghanistan"},{"id":55,"curr":"ALL","name":"Albania"},{"id":64,"curr":"DZD","name":"Algeria"},{"id":65,"curr":"AOA","name":"Angola"},{"id":24,"curr":"ARS","name":"Argentina"}...
So I can say that
$outLoopCountry = json_decode($jsonLoopCountry, true); // DECODE JSON FILE
creates the JSON ARRAY right? (Because JSON array starts with {"something":[{"..."...)
if it was [{"a":"answer","b":"answer",...} ... it would have a been a JSON Object right?
So to access to the array I uses
$countryList = $outLoopCountry['country']; // ACCESS TO JSON OBJECT
right?
So I understood that arrays are a fast useful ways to store relational data and access to it right?
So the question is how to make a precise search inside the array, so to make it works like a Query MySQLi, like "SEARCH INSIDE ARRAY WHERE id == 7" and have as a result "== ITALY" (ex.).
The way exist for sure, but with whole exmples I found on the net, I was able to fix one to make it works.
Thx again.
Alberto

Php-ews: creating contact birthday's event

I am trying to add a contact in Exchange, using the php-ews and the following code:
$request = new EWSType_CreateItemType();
$request->SendMeetingInvitations = 'SendToNone';
$contact = new EWSType_ContactItemType();
$contact->GivenName = $updates['name'];
$contact->Surname = $updates['surname'];
if($updates['email'] != ""){
$email = new EWSType_EmailAddressDictionaryEntryType();
$email->Key = new EWSType_EmailAddressKeyType();
$email->Key->_ = EWSType_EmailAddressKeyType::EMAIL_ADDRESS_1;
$email->_ = $updates['email'];
// set the email
$contact->EmailAddresses = new EWSType_EmailAddressDictionaryType();
$contact->EmailAddresses->Entry[] = $email;
}
$contact->CompanyName = $updates['companyname'];
$contact->JobTitle = $updates['jobtitle'];
$contact->Birthday = $updates['birthday'];
$request->Items->Contact[] = $contact;
$response = $this->ews->CreateItem($request);
Where $updates is an array of strings I have as a parameter.
(I skipped the includes, tell me if you need them.)
Now, the contact gets created and everything works, but the birthday event does not get created automatically in my calendar.
So, I would like to know if there's a simple way to have this done, except the obvious (non-elegant) way of creating it manually.
Thank you in advance,
Riccardo
Could solve this using DateTime in the right format as expected in the comments.
$contact->Birthday = (new DateTime($updates['birthday']))->format(DATE_W3C);
https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/time-zones-and-ews-in-exchange
The time zone specified in the value of dateTime elements can take three forms. You can read all the details in XML Schema Part 2: Datatypes Second Edition, but to paraphrase:
Universal Coordinated Time (UTC): Specified by 'Z'. For example, 2014-06-06T19:00:00.000Z
Specific time zone: Specified by '+' or '-' followed by hours and minutes. For example, 2014-06-06T19:00:00.000-08:00
No time zone: Specified by the absence of any time zone. For example, 2014-06-06T19:00:00.000

Creating a recurring calendar event with php-ews

I am trying to create a recurring calendar event with php-ews and the documentation is very limited in this aspect. I have got what is below so far I just can not find out how to have it repeat say every Monday and Wednesday. Can anyone who has done this before or knows how help me out?
$request->Items->CalendarItem->Recurrence = new Type\RecurrenceType();
$request->Items->CalendarItem->Recurrence->WeeklyRecurrence = new Type\IntervalRecurrencePatternBaseType();
$request->Items->CalendarItem->Recurrence->NumberedRecurrence = new Type\NumberedRecurrenceRangeType();
$request->Items->CalendarItem->Recurrence->NumberedRecurrence->NumberOfOccurrences = 2;
$request->Items->CalendarItem->Recurrence->NumberedRecurrence->StartDate = //start date here;
I've successfully used this...
// Set up recurrence days
$request->Items->CalendarItem->Recurrence = new EWSType_RecurrenceType();
$request->Items->CalendarItem->Recurrence->WeeklyRecurrence = new EWSType_IntervalRecurrencePatternBaseType();
$request->Items->CalendarItem->Recurrence->WeeklyRecurrence->Interval = 1;
$request->Items->CalendarItem->Recurrence->WeeklyRecurrence->DaysOfWeek = new EWSType_ArrayOfStringsType();
$request->Items->CalendarItem->Recurrence->WeeklyRecurrence->DaysOfWeek = array(EWSType_DayOfWeekType::MONDAY, EWSType_DayOfWeekType::WEDNESDAY, EWSType_DayOfWeekType::FRIDAY);
// Specify recurrence start and end
$request->Items->CalendarItem->Recurrence->EndDateRecurrence = new EWSType_EndDateRecurrenceRangeType();
$request->Items->CalendarItem->Recurrence->EndDateRecurrence->EndDate = '2014-05-30';
$request->Items->CalendarItem->Recurrence->EndDateRecurrence->StartDate = '2014-05-14';
Looks like you're just missing the DaysOfWeek array item. Adjust your array as needed based on the days you'd like the meeting to occur, and of course set your own start and end dates as well. I believe the Interval item would be equivalent to 1=every week, 2=every other week, etc. but i have not tested that.

php RRD graph separation

I am trying to create RRD graphs with the help of PHP in order to keep track of the inoctets,outoctets and counter of a server.
So far the script is operating as expected but my problems comes when I am trying to produce 2 or more separate graphs. I am trying to produce (hourly, weekly , etc) graphs. I thought by creating a loop would solve my problem, since I have split the RRA in hours and days. Unfortunately I end up having 2 graphs that updating simultaneously as expected but plotting the same thing. Has any one encounter similar problem? I have applied the same program in perl with RRD::Simple,where is extremely easy and everything is adjusted almost automatically.
I have supplied under a working example of my code with the minimum possible data because the code is a bit long:
<?php
$file = "snmp-2";
$rrdFile = dirname(__FILE__) . "/snmp-2.rrd";
$in = "ifInOctets";
$out = "ifOutOctets";
$count = "sysUpTime";
$step = 5;
$rounds = 1;
$output = array("Hourly","Daily");
while (1) {
sleep (6);
$options = array(
"--start","now -15s", // Now -10 seconds (default)
"--step", "".$step."",
"DS:".$in.":GAUGE:10:U:U",
"DS:".$out.":GAUGE:10:U:U",
"DS:".$count.":ABSOLUTE:10:0:4294967295",
"RRA:MIN:0.5:12:60",
"RRA:MAX:0.5:12:60",
"RRA:LAST:0.5:12:60",
"RRA:AVERAGE:0.5:12:60",
"RRA:MIN:0.5:300:60",
"RRA:MAX:0.5:300:60",
"RRA:LAST:0.5:300:60",
"RRA:AVERAGE:0.5:300:60",
);
if ( !isset( $create ) ) {
$create = rrd_create(
"".$rrdFile."",
$options
);
if ( $create === FALSE ) {
echo "Creation error: ".rrd_error()."\n";
}
}
$t = time();
$ifInOctets = rand(0, 4294967295);
$ifOutOctets = rand(0, 4294967295);
$sysUpTime = rand(0, 4294967295);
$update = rrd_update(
"".$rrdFile."",
array(
"".$t.":".$ifInOctets.":".$ifOutOctets.":".$sysUpTime.""
)
);
if ($update === FALSE) {
echo "Update error: ".rrd_error()."\n";
}
$start = $t - ($step * $rounds);
foreach ($output as $test) {
$final = array(
"--start","".$start." -15s",
"--end", "".$t."",
"--step","".$step."",
"--title=".$file." RRD::Graph",
"--vertical-label=Byte(s)/sec",
"--right-axis-label=latency(min.)",
"--alt-y-grid", "--rigid",
"--width", "800", "--height", "500",
"--lower-limit=0",
"--alt-autoscale-max",
"--no-gridfit",
"--slope-mode",
"DEF:".$in."_def=".$file.".rrd:".$in.":AVERAGE",
"DEF:".$out."_def=".$file.".rrd:".$out.":AVERAGE",
"DEF:".$count."_def=".$file.".rrd:".$count.":AVERAGE",
"CDEF:inbytes=".$in."_def,8,/",
"CDEF:outbytes=".$out."_def,8,/",
"CDEF:counter=".$count."_def,8,/",
"COMMENT:\\n",
"LINE2:".$in."_def#FF0000:".$in."",
"COMMENT:\\n",
"LINE2:".$out."_def#0000FF:".$out."",
"COMMENT:\\n",
"LINE2:".$count."_def#FFFF00:".$count."",
);
$outputPngFile = rrd_graph(
"".$test.".png",
$final
);
if ($outputPngFile === FALSE) {
echo "<b>Graph error: </b>".rrd_error()."\n";
}
} /* End of foreach function */
$debug = rrd_lastupdate (
"".$rrdFile.""
);
if ($debug === FALSE) {
echo "<b>Graph result error: </b>".rrd_error()."\n";
}
var_dump ($debug);
$rounds++;
} /* End of while loop */
?>
A couple of issues.
Firstly, your definition of the RRD has a step of 5seconds and RRAs with steps of 12x5s=1min and 300x5s=25min. They also have a length of only 60 rows, so 1hr and 25hr respectively. You'll never get a weekly graph this way! You need to add more rows; also the step seems rather short, and you might need a smaller-step RRA for hourly graphs and a larger-step one for weekly graphs.
Secondly, it is not clear how you're calling the graph function. You seem to be specifying:
"--start","".$start." -15s",
"--end", "".$t."",
"--step","".$step."",
... which would force it to use the 5s interval (unavailable, so the 1min one would always get used) and for the graph to be only for the time window from the start to the last update, not a 'hourly' or 'daily' as you were asking.
Note that the RRA you have defined do not define the time window of the graph you are asking for. Also, just because you have more than one RRA defined, it doesnt mean you'll get more than one graph unless oyu call the graph function twice with different arguments.
If you want a daily graph, use
"--start","end - 1 hour",
"--end",$t,
Do not specify a step as the most appropriate available will be used anyway. For a daily graph, use
"--start","end - 1 day"
"--end",$t,
Similarly, no need to specify a step.
Hopefully this will make it a little clearer. Most of the RRD graph options have sensible defaults, and RRDTool is pretty good at picking the correct RRA to use based on the graph size, time window, and DEF statements.

Categories