Symfony array of arrays - arrays

Maybe there is a simpler way of doing this. But I want to display entries (URLs) that were already found when trying to input in to a database table along with the current table. So in the controller I am trying to pass two arrays. One that is of the whole table and another of the entries it found matched the entries in the table. So the user can see they already existed.
$repository = $this->getDoctrine()->getRepository('ObjectBundle:object');
foreach ($mylinks as &$value) {
$linkexist = $repository->findOneByUrl($value);
if (!$linkexist) {
$obj = new Object();
$obj->setUrl($value);
$obj->setLastupdate(new \DateTime('now'));
$em = $this->getDoctrine()->getManager();
$em->persist($obj);
$em->flush();
} else {
$notfound = new Object();
$notfound->setUrl($value);
}
}
$em = $this->getDoctrine()->getManager();
$listurls = $em->getRepository('ObjectBundle:Object')->findAll();
return $this->render('object/index.html.twig', array(
'objects' => $listurls,
));
I would like to include the $notfound into a separate array or parse it without changing the Object entity. Any ideas?

You Object contains some sort of Id and it can be used here:
$existingIds = array();
$k=0;
Then collect the IDs:
} else {
$notfound = new Object();
$notfound->setUrl($value);
$nfound[$k]=$notfound;
$k++;
}
Pass the array:
return $this->render('object/index.html.twig', array(
'objects' => $listurls,
'existingIds' => $existingIds
));
Finally, in your Twig, you would have something like this:
{% if existingIds is defined %}
{% for existingId in existingIds %}
{{ existingId.url }}
{% endfor %}
{% endif %}
Hope this helps a bit...

Related

How to extract all URL's from webpage in an array an see if certain value is there

I am trying to extract all the links from a webpage and put them into an array that I can then compare values with to see if there is a match. The problem that I'm having is I cannot seem to get the values into an array. I am able to see all the links and I see that there is a match with the one I'm trying to compare with but it's not recognizing that it's there. My code is as follows. Any help would be greatly appreciated.
$content = file_get_contents("sample_url");
$content = strip_tags($content, "<a>");
$subString = preg_split("/<\/a>/", $content);
$items = array();
foreach ( $subString as $val ){
if( strpos($val, "<a href=") !== FALSE ) {
$val = preg_replace("/.*<a\s+href=\"/sm", "", $val);
$val = preg_replace("/\".*/", "", $val);
$items[] = $val;
var_dump($val . "<br />");
}
}
if (in_array($testing_link, $items, true)) {
echo 'It is here!';
}
else {
echo 'it is NOT here :( ';
}
Better to use the DOMDocument to get the links into an array. Like this:
$doc = new DOMDocument();
// the string containing all the URLs and stuff
$doc->loadHTML($content);
//Extract the links from the HTML. From https://thisinterestsme.com/php-find-links-in-html/
$links = $doc->getElementsByTagName('a');
//Array that will contain our extracted links.
$extracted_links = array();
//Loop through the DOMNodeList.
//We can do this because the DOMNodeList object is traversable.
foreach ($links as $link) {
//Get the link text.
//$linkText = $link->nodeValue;
//Get the link in the href attribute.
$linkHref = $link->getAttribute('href');
}
Now all the HREFS are in the $linkHref array.
Better to use DOMDocument rather than RegEx. Much easier, and more accurate and consistent in results.

Symfony - saving array to database

I wrote a function where I get array of marks that i need to post to my database..
My function stores it in a filed row like:
And I need to pull just one per column individually like:
Here is my api call..
public function generate(Map $seatMap)
{
$layout = $seatMap->getSeatLayout();
$seats = [];
$layoutArray = json_decode($layout, true);
$columns = range('A', 'Z');
foreach($layoutArray as $index => $result)
{
$columnLetter = $columns[$index];
$letters = str_split($result);
$letterIndex = 1;
foreach($letters as $letterIndex => $letter) {
switch($letter) {
case 'e':
$seats[] = $columnLetter . $letterIndex;
$letterIndex++;
}
}
}
foreach($seats as $seat => $result) {
$result = new Seat();
$result->setName(json_encode($seats));
$this->em->persist($result);
$this->em->flush();
}
}
Any suggestions?
I think that problem is in the part where I need to store it to database..
If I understand you correctly, your issue is here:
foreach($seats as $seat => $result) {
$result = new Seat();
$result->setName(json_encode($seats));
$this->em->persist($result);
$this->em->flush();
}
}
You're indeed creating new Seat instance for every seat, but in this line:
$result->setName(json_encode($seats));
you still assign all (encoded) seats to every instance of Seat. What you want is to assign only the seat from current loop iteration, which is represented by $result variable.
So try with:
$result->setName($result);
You do not need json_encode here too.
If your array is like you say it it then try this
foreach($seats as $seat) {
$result = new Seat();
$result->setName($seat);
$this->em->persist($result);
$this->em->flush();
}

Multiple collections in an array (session variable) — Property does not exist

I'am trying to fetch a session variable if the user is a guest. The variable is called "cart" and is set like this:
$product = new Collection((object) [
'product_id' => $request->pId,
'amount' => $request->amount,
'variations' => $variations
]);
Session::push('cart', $product);
Then I later fetch it:
if(Auth::check()){
$cartProducts = ShoppingCartItem::where('user_id', '=', Auth::user()->id)->get();
}else{
$cartProducts = Session::get('cart');
}
foreach($cartProducts as $product){
dd($product);
$totalAmount += $product->amount;
$totalPrice += (PriceHelper::getProductPrice($product->product->id, $product->amount));
}
The problem here is that dd($product) still outputs an array (the session variable array I assume) which means that for example $product->amount does not exist.
This is the output from dd($product):
You can either access the values using get():
foreach ($cartProducts as $product) {
$totalAmount += $product->get('amount');
$totalPrice += PriceHelper::getProductPrice($product->get('product_id'), $product->get('amount'));
}
or as an array:
foreach ($cartProducts as $product) {
$totalAmount += $product['amount'];
$totalPrice += PriceHelper::getProductPrice($product['product_id'], $product['amount']);
}
or you could use sum() on the collection instead of using foreach:
$cartProducts = collect(Session::get('cart'));
$totalAmount = $cartProducts->sum('amount');
$totalPrice = $cartProducts->sum(function ($product) {
return PriceHelper::getProductPrice($product['product_id'], $product['amount']);
});
Edit
For a quick fix if you need $product to be an object you could do something like:
$cartProducts = collect(Session::get('cart'))->map(function ($item) {
return (object)$item->toArray();
});
Hope this helps!

SilverStripe 3.1 loop associative array

In SilverStripe 3.1 I have a function that loops through an array and outputs its contents.
The output it gives me is:
Layout: John
Strategy: John
Management: Martin
In this example John has more than one job.
I would like to group the jobs if a person has more than one job.
This is my desired Output:
Layout and Strategy: John
Management: Martin
//$InfoFieldArray = array('Layout' => 'John', 'Strategy' => 'John', 'Management' => 'Martin');
public function createInfoFields($InfoFieldArray){
$Info = ArrayList::create();
foreach($InfoFieldArray as $key => $value ){
$fields = new ArrayData(array('FieldName' => $key, 'Value' => $value));
$Info->push($fields);
}
return $Info;
}
How do I alter my function to achieve my desired output?
One possible solution to that is by restructuring the data before adding it to the ArrayList.
public function createInfoFields($InfoFieldArray)
{
$info = array();
foreach ($InfoFieldArray as $job => $person)
{
if (!isset($info[$person]))
{
$info[$person] = array();
}
$info[$person][] = $job;
}
$result = ArrayList::create();
foreach ($info as $person => $jobs)
{
$fields = new ArrayData(array('FieldName' => implode(' and ', $jobs), 'Value' => $person));
$result->push($fields);
}
return $result;
}
What I have done is go over the array of jobs and the person assigned and flipped it the other way around, so I have an array of people with a list of jobs. This allows me to then just call implode in PHP, joining the various jobs by the word and.
There are some potential drawbacks, if there are two people named "John", they will be treated as one as I am using the name as the array key.
Also, if there are three jobs for a person, it will list it like "Layout and Strategy and Management". To avoid that, we need to modify the second foreach loop in my code to something like this:
foreach ($info as $person => $jobs)
{
$jobString = null;
if (count($jobs) > 1)
{
$jobString = implode(', ', array_slice($jobs, 0, -1)) . ' and ' . array_pop($jobs);
}
else
{
$jobString = $jobs[0];
}
$fields = new ArrayData(array('FieldName' => $jobString, 'Value' => $person));
$result->push($fields);
}
When there is more than 1 job for a person, we want to implode (glue together) the array pieces for the $jobs array however we don't want the last element at this point. Once array is glued together, we append with with and along with the last item.

symfony2 custom entity to array function

I have to help me convert an entity to array but I have issues resolving associated records, which I need.
However, this gives me an error
The class 'Doctrine\ORM\PersistentCollection' was not found in the
chain configured namespaces ...
The code follows:
public function serialize($entityObject)
{
$data = array();
$className = get_class($entityObject);
$metaData = $this->entityManager->getClassMetadata($className);
foreach ($metaData->fieldMappings as $field => $mapping)
{
$method = "get" . ucfirst($field);
$data[$field] = call_user_func(array($entityObject, $method));
}
foreach ($metaData->associationMappings as $field => $mapping)
{
// Sort of entity object
$object = $metaData->reflFields[$field]->getValue($entityObject);
if ($object instanceof ArrayCollection) {
$object = $object->toArray();
}
else {
$data[$field] = $this->serialize($object);
}
}
return $data;
}
How can I resolve the associated fields into their respective arrays.
I have tried using the built-in, and JMS serialiser, but this gives me issues of nestedness limits, so this is not an option for me.
UPDATE:
I have updated the code to handle instance of ArrayCollection as per #ScayTrase's suggestion. However, the error above is still reported with a one-to-many field map. In debug, the variable $object is of type "Doctrine\ORM\PersistentCollection"
For *toMany association properties implemented with ArrayCollection you should call ArrayCollection::toArray() first. Just check it with instanceof before, like this
if ($object instanceof ArrayCollection) {
$object = $object->toArray();
}

Resources