In my lottery project I have 5 tickets, in which you select numbers and buy. The thing is, you can only buy the tickets if you buy them in order... For example:
Ticket 1 Ticket 2 Ticket 3 Ticket 4 Ticket 5
If you add numbers to the ticket 1 and then the others it works... If you skip the ticket 1 and add numbers to the other ones, when you try to buy you get this error:
ContextErrorException: Notice: Undefined offset: 0 in C:\wamp\www\Digidis\front\src\MediaparkLt\UserBundle\Service\MoneyManager.php line 313
The full stack:
array('cartProduct' => array('title' => 'EUROMILLONES', 'price' => '2.35', 'product' => '2', 'ticket_id' => '1433921783_19792', 'numbers' => '8,13,14,17,37', 'stars' => '4,7', 'betslip' => '{"duration":"1","subscription":"false","jsPrice":"235","type":"simple","numbers1":"0,0,0,0,0","numbers2":"8,13,14,17,37","numbers3":"0,0,0,0,0","numbers4":"0,0,0,0,0","numbers5":"0,0,0,0,0","stars1":"0,0","stars2":"4,7","stars3":"0,0","stars4":"0,0","stars5":"0,0","dayOfWeek":"3"}', 'is_syndicate' => false, 'draw' => object(DateTime)), 'product' => object(Product), 'user' => object(User), 'reference' => null, 'paymentResult' => 'Authorised', 'bets' => object(stdClass), 'individualBets' => array(), 'tickets' => array(array('numbers' => '8,13,14,17,37', 'stars' => '4,7')), 'k' => '0', 't' => array('numbers' => '0,0,0,0,0', 'stars' => '0,0'), 'is_ticket_filled' => false, 'week_id' => array(array('ticketId' => '7005')), 'g' => '0', 'lastId' => '7005', 'purchase' => object(Purchase), 'price' => '2.35', 'bet' => object(Bet), 'euromillonesBet' => object(EuromillonesBet), 'drawDate' => array(object(DrawDate)), 'j' => '0')) in C:\wamp\www\Digidis\front\src\MediaparkLt\UserBundle\Service\MoneyManager.php line 313
As you can see first it gets the ticket 1, which is empty(or 0) and thats why it causes the error... How can I make it so that it skips the empty tickets?
Here is the controller where the error occurs:
$bets = json_decode($cartProduct['betslip']);
$individualBets = array();
$tickets = array(
array('numbers' => $bets->numbers1, 'stars' => $bets->stars1),
array('numbers' => $bets->numbers2, 'stars' => $bets->stars2),
array('numbers' => $bets->numbers3, 'stars' => $bets->stars3),
array('numbers' => $bets->numbers4, 'stars' => $bets->stars4),
array('numbers' => $bets->numbers5, 'stars' => $bets->stars5)
);
if ($bets->type === 'simple') {
foreach ($tickets as $k => $t) {
$is_ticket_filled = ((int) str_replace(',', '', $t['numbers'])) > 0;
if (!$is_ticket_filled) {
unset($tickets[$k]);
}
}
} else if ($bets->type === 'multiple') {
$tickets = array(array('numbers' => $bets->numbers1, 'stars' => $bets->stars1));
}
$week_id = null;
for ($k = 0; $k < (count($tickets)); $k++) {
for ($g = 0; $g < $bets->duration; $g++) {
if (!isset($week_id[$g])) {
$week_id[$g] = $this->entityManager->getRepository('MediaparkLtLotteryBundle:Bet')->getLastTicketId();
if ($week_id[$g]) {
$week_id[$g]['ticketId'] ++;
} else {
$week_id[$g]['ticketId'] = 0;
}
}
$lastId = $week_id[$g]['ticketId'];
$purchase = new Purchase();
$purchase->setUser($user);
$purchase->setDrawDate($cartProduct['draw']);
$purchase->setProduct($product);
$purchase->setReference($reference);
$price = $cartProduct['price'];
$bet = new Bet();
if ('eurojackpot' == $product->getAlias()) {
$euromillonesBet = new EurojackpotBet();
} else {
$euromillonesBet = new EuromillonesBet();
}
$drawDate = $this->entityManager->getRepository('MediaparkLtLotteryBundle:DrawDate')->findByDrawDate($cartProduct['draw']);
if (!$drawDate)
die('no draw date found ' . $cartProduct['draw']->format('Y-m-d H:i:s'));
$bet->setDrawDate($drawDate[0]);
$bet->setTicketId($lastId);
if (strtoupper($paymentResult) === 'AUTHORISED') {
$bet->setStatus(BetStatus::AUTHORISED);
} else {
$bet->setStatus(BetStatus::FAILED);
}
$bet->setWinnings(0);
$euromillonesBet->setBet($bet);
/// LINE 313 ABOVE!!!!!!!
$numbers = $this->getNumbersArray($tickets[$k]['numbers']);
$j = 0;
foreach ($numbers as $number) {
$j++;
$name = 'setN' . $j;
$euromillonesBet->$name($number);
}
$numbers = $this->getNumbersArray($tickets[$k]['stars']);
$euromillonesBet->setS1($numbers[0]);
$euromillonesBet->setS2($numbers[1]);
$euromillonesBet->setAmountOfStars(Bet::NUMBER_OF_STARS);
$purchase->addBet($bet);
$purchase->setPricePaid($price);
if (strtoupper($paymentResult) === 'AUTHORISED') {
$purchase->setStatus(PaymentStatus::AUTHORISED);
} else {
$purchase->setStatus(PaymentStatus::FAILED);
}
if ($bets->subscription === "true") {
$contract = new PurchaseContract();
$contract->setAccumulatedWinnings(0);
$contract->setCancellationDate(null);
$contract->setFirstDrawDate($purchase->getDrawDate());
$contract->setLastRenewedDate($purchase->getDrawDate());
$contract->setNextRenewalFirstDrawDate($purchase->getDrawDate());
// $contract->setPurchase($purchase);
$contract->setStatusPurchaseContract(1);
$contract->setWeeks(1);
$purchase->setPurchaseContract($contract);
$this->entityManager->persist($contract);
}
if ($g == 0)
$individualBets[] = $euromillonesBet;
$this->entityManager->persist($bet);
$this->entityManager->persist($euromillonesBet);
$this->entityManager->persist($purchase);
$this->entityManager->flush();
}
}
return $individualBets;
}
From what I see the bet type in your object is set to "type":"simple" and numbers1":"0,0,0,0,0"
$is_ticket_filled = ((int) str_replace(',', '', $t['numbers'])) > 0;
//(int) 00000 = 0
if (!$is_ticket_filled) {
unset($tickets[$k]);
}
Is causing the issue since unset does not reset the array indexes.
http://ideone.com/5q74Wv
Then later you iterate using for($k=0; $k < count($tickets); $k++)
You should instead rebase the array after using unset($tickets[$k])
if ($bets->type === 'simple') {
//...
$tickets = array_values($tickets);
}
or check the existence of the ticket when iterating over indexes
$ticketCount = count($tickets);
for ($k=0; $k < $ticketCount; $k++) {
if (false === isset($tickets[$k]) {
continue;
}
//...
}
or easier still, iterate over the existing tickets array using foreach instead of for.
foreach ($tickets as $k => $ticket) {
//...
}
Then change $tickets[$k] with just $ticket since $k is not used anywhere else.
Related
I am beginner in PHP.
I have this array:
$array = array(
['name' => 'project 1', 'url' => 'www.name1.com', 'photo' => '1.jpg'],
['name' => 'project 2', 'url' => 'www.name2.com', 'photo' => '2.jpg'],
['name' => 'project 3', 'url' => 'www.name3.com', 'photo' => '3.jpg'],
['name' => 'project 4', 'url' => 'www.name4.com', 'photo' => '4.jpg'],
['name' => 'project 5', 'url' => 'www.name5.com', 'photo' => '5.jpg'],
['name' => 'project 6', 'url' => 'www.name6.com', 'photo' => '6.jpg'],
)
I need get by function next and previous element from my array (if exist):
$next = next($actualUrl);
$previous = previous($actualUrl);
How can I make it?
this simple code will help you:
<?php
function next_elm ($array, $actualUrl) {
$i = 0;
while ( $i < count($array) && $array[$i]["url"] != $actualUrl ) $i++;
if ($i < (count($array) - 1)) {
return $array[$i+1];
} else if ($i == (count($array) - 1)) {
return $array[0]; // this is depend what you want to return if the url is the last element
} else {
return false; // there is no url match
}
}
function prev_elm ($array, $actualUrl) {
$i = 0;
while ( $i < count($array) && $array[$i]["url"] != $actualUrl ) $i++;
if ($i < (count($array)) && $i>0) {
return $array[$i-1];
} else if ($i == 0) {
return $array[count($array) - 1]; // this is depend what you want to return if the url is the first element
} else {
return false; // there is no url match
}
}
I prefer to iterate over any array via a foreach loop. if you want anything specific out of it just copy it into a tmp variable. for example:
$tmp_var = null;
foreach($array as $key => $value){
$tmp_var = $value['name'];
}
First find actual url, then use this index to find previous and next items. Also you should add checks if the current item is first or last element to avoid null pointer exception.
$curr = 0;
foreach($array as $value){
if($value['url'] == 'www.name2.com'){
break;
}
$curr += 1;
}
$previous = $array[$curr-1];
$next = $array[$curr+1];
I make a parser of items from DotA 2 user inventory in the Steam service. Every time I try to parse user data, I get an empty value:
{"success":true,"items":[]}, but there are items in my Steam inventory.
My function to parse items:
public function loadMyInventory() {
if(Auth::guest()) return ['success' => false];
$prices = json_decode(Storage::get('prices.txt'), true);
$response = json_decode(file_get_contents('https://steamcommunity.com/inventory/'.$this->user->steamid64.'/570/2?l=russian&count=5000'), true);
if(time() < (Session::get('InvUPD') + 5)) {
return [
'success' => false,
'msg' => 'Error, repeat in '.(Session::get('InvUPD') - time() + 5).' сек.',
'status' => 'error'
];
}
//return $response;
$inventory = [];
foreach($response['assets'] as $item) {
$find = 0;
foreach($response['descriptions'] as $descriptions) {
if($find == 0) {
if(($descriptions['classid'] == $item['classid']) && ($descriptions['instanceid'] == $item['instanceid'])) {
$find++;
# If we find the price of an item, then move on.
if(isset($prices[$descriptions['market_hash_name']])) {
# Search data
$price = $prices[$descriptions['market_hash_name']]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($descriptions['tradable'] == 0) || ($descriptions['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
# Adding to Array
$inventory[] = [
'name' => $descriptions['market_name'],
'price' => floor($price),
'color' => $this->getRarity($descriptions['tags']),
'tradable' => $descriptions['tradable'],
'class' => $class,
'text' => $text,
'classid' => $item['classid'],
'assetid' => $item['assetid'],
'instanceid' => $item['instanceid']
];
}
}
}
}
}
Session::put('InvUPD', (time() + 5));
return [
'success' => true,
'items' => $inventory
];
}
But should return approximately the following value:
{"success":true,"items":[{"classid":"2274725521","instanceid":"57949762","assetid":"18235196074","market_hash_name":"Full-Bore Bonanza","price":26}]}
Where my mistake?
First of all, you are iterating on descriptions for every assets, which is assets*descriptions iteration, it's quite a lot, but you can optimize this.
let's loop once for descriptions and assign classid and instanceid as object key.
$assets = $response["assets"];
$descriptions = $response["descriptions"];
$newDescriptions=[];
foreach($descriptions as $d){
$newDescriptions[$d["classid"]][$d["instanceid"]] = $d;
}
this will give as the ability to not loop over description each time, we can access the description of certain asset directly $newDescriptions[$classid][$instanceid]]
foreach($assets as $a){
if(isset($newDescriptions[$a["classid"]]) && isset($newDescriptions[$a["classid"]][$a["instanceid"]])){
$assetDescription = $newDescriptions[$a["classid"]][$a["instanceid"]];
$inventory = [];
if(isset($prices[$assetDescription["market_hash_name"]])){
$price = $prices[$assetDescription['market_hash_name']]["price"]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($assetDescription['tradable'] == 0) || ($assetDescription['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
$inventory["priceFound"][] = [
'name' => $assetDescription['market_name'],
'price' => floor($price),
'color' => $this->getRarity($assetDescription['tags']),
'tradable' => $assetDescription['tradable'],
'class' => $class,
'text' => $text,
'classid' => $a['classid'],
'assetid' => $a['assetid'],
'instanceid' => $a['instanceid']
];
}else{
$inventory["priceNotFound"][] = $assetDescription["market_hash_name"];
}
}
}
About your mistake:
are you Sure your "prices.txt" contains market_hash_name?
I don't see any other issue yet, operationg on the data you have provided in comment, I got print of variable $assetDescription. Please doublecheck variable $prices.
I have this array:
$actualPlan = 'medium';
$plans = array(
array(
'plans' => array(
'tiny' => 29,
'small' => 69,
'medium' => 179,
'big' => 359
)
)
);
During a foreach, I display the contents of plans of this array like this:
foreach($plans as $key => $data) {
foreach($data['plans'] as $plan => $rate) {
...
}
}
But how can I know the position of the $actualPlan ?
For example, for :
if $actualPlan == medium it should return me 3.
if $actualPlan == tiny it should return me 1.
Thanks.
inside the loop:
echo array_search($actualPlan, array_keys($rate)); // returns the index position as int
here will output 1,2,3,4 for the inputs 'tiny','small','medium','big'
Within the foreach($plans as $key => $data) {, you could make the conditional like this :
$current_plan = explode('___', $actualPlan);
$current_key = array_search($current_plan[0],array_keys($data['plans']));
foreach($data['plans'] as $plan => $rate) {
$current_iterated_key = array_search($plan,array_keys($data['plans']));
if ($current_iterated_key < $current_key) {
echo "$plan => Downgrade\r\n";
} elseif ($current_iterated_key > $current_key) {
echo "$plan => Upgrade\r\n";
} elseif($current_iterated_key == $current_key) {
echo "$plan => Current\r\n";
}
}
Below if my code for column search of datatables as well as complete search,
$columns = array(0 => 'ship_id' ,
1 => 'sr',
2 => 'ce',
3 => 'sto',
4 => 'supply' ,
5 => 'part',
6 => 'description',
7 => 'quantity',
8 => 'date',
9 => 'shipn',
10 => 'ship',
11 => 'transport',
12 => 'docket',
13 => 'delivery');
if(isset($searchValue) && $searchValue != '')
{
$searchingAll = array();
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = $this->db->or_like($columns[$i], $searchValue);
$searchingColumns = NULL;
}
}
else if($this->input->post('columns[1][search][value]', TRUE) != '')
{
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = NULL;
$searchingColumns = $this->db->or_like($columns[1], $this->input->post('columns[1][search][value]', TRUE));
}
}
else
{
$searchingAll = NULL;
$searchingColumns = NULL;
}
First IF condition will search complete datatable, then else-if will search individual column,
I have 12 columns in my datatables, so i need to loop 12 times else-if condition,
In above code currently i shown only column 1, but i need to check all 12 columns that something is entered in any of column search then it will go to for loop of else-if condition,
How can i check all 12 columns in else-if condition?
Thanks,
You were not using the $i you defined in the else if.
Use this instead:
$columns = array(0 => 'ship_id' ,
1 => 'sr',
2 => 'ce',
3 => 'sto',
4 => 'supply' ,
5 => 'part',
6 => 'description',
7 => 'quantity',
8 => 'date',
9 => 'shipn',
10 => 'ship',
11 => 'transport',
12 => 'docket',
13 => 'delivery');
if(isset($searchValue) && $searchValue != '')
{
$searchingAll = array();
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = $this->db->or_like($columns[$i], $searchValue);
$searchingColumns = NULL;
}
}
else if($this->input->post('columns[1][search][value]', TRUE) != '')
{
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = NULL;
$searchingColumns = $this->db->or_like($columns[$i], $this->input->post('columns['.$i.'][search][value]', TRUE));
}
}
else
{
$searchingAll = NULL;
$searchingColumns = NULL;
}
I have the following code, and i keep getting undefined index error, the code is failing on test5() but i'm unable to find the error.
<?php
function test1() {
$vars = [0, 1, 2, 4, 3];
for ($i = 0; $i < count($vars); $i++) {
print $vars[$i] . "\n";
}
}
function test2() {
$flavors = ['vanilla', 'pistachio', 'banana', 'caramel', 'strawberry'];
$favorite = 'banana';
foreach ($flavors as $key => $flavor) {
if ($flavor === $favorite) {
print $key . "\n";
break;
}
}
}
function test3() {
$stuff = ['shoes', 33, null, false, true];
$selected = 0;
foreach ($stuff as $key => $thing) {
if ($thing == $selected) {
print $key . "\n";
break;
}
}
}
function test4() {
$four = 4;
$five = test4_helper($four);
print "four: $four\n";
print "five: $five\n";
}
function test4_helper(&$arg) {
$return = $arg++;
return $return;
}
function test5() {
$products = [
'Trek Fuel EX 8' => [
'price' => 2000,
'quantity' => 1
],
'Trek Remedy 9' => [
'price' => 2600,
'quantity' => 2
],
'Trek Scratch 8' => [
'price' => 3500,
'quantity' => 1
]
];
$total = 0;
$callback = function ($product, $name) {
//$total = 0;
$tax = 1.2;
$price = $product[$name]['price'];
$total += ($price * $product[$name]['quantity']) * $tax;
return $total;
};
array_walk($products, $callback);
print "$total\n";
}
/* * **********************************
* *** DO NOT EDIT BELOW THIS LINE ****
* *********************************** */
$tests = 5;
for ($i = 1; $i <= $tests; $i++) {
$function = "test$i";
print "\n\n==== Test $i ====\n";
$function();
print "==== END of test $i ====\n <br>";
}
what is the problem with this code?
it looks that it's failing on test 5
PHP closures are not like JavaScript ones in that they do not inherit the parent scope. You need to pass in any dependencies via the use construct. In your example...
$callback = function ($product, $name) use ($total) {
// etc
See http://php.net/manual/functions.anonymous.php#example-166
Arrays in PHP are defined like this:
$products = array(
'Trek Fuel EX 8' => array(
'price' => 2000,
'quantity' => 1
),
'Trek Remedy 9' => array(
'price' => 2600,
'quantity' => 2
),
'Trek Scratch 8' => array(
'price' => 3500,
'quantity' => 1
)
);
Which means you also need to look at $vars = [0, 1, 2, 4, 3]; and $flavors = ['vanilla', 'pistachio', 'banana', 'caramel', 'strawberry']; and fix them too.