Jump to content
Macrura

images in WireArray with same name

Recommended Posts

came across a strange edge case;

I'm creating a new WireArray to collect images from various pages, which all get output into a gallery.

In this particular site, the client had several images all with the exact same name on different pages, and when those were imported into the WireArray, they are de-duplicated, even though they are different images on different pages, so those images were not showing.

I worked around it by renaming the images on the fly, and i can use the custom upload names to prevent this from happening in the future, but it does seem like someone else might run into this, not realizing that the wireArray is assuming the same named images are the same on import;

i guess maybe i could have imported them into the wireArray using this syntax?

    $key = 0;
    foreach($p->product_images as $image) {
        $productImages[$key] = $image;
        $key++;
    }

Share this post


Link to post
Share on other sites

You don't need to use the $key.

    foreach($p->product_images as $image) {
        $productImages[] = $image;
    }

How were you adding them to the WireArray in the first place?

Share this post


Link to post
Share on other sites

I was using import - is that the reason why it was de-duplicating on the file name?

this is the code

$productImages = new WireArray();

foreach( $page->children as $p ) {
   $productImages->import($p->product_images);
}

$productImages->import($page->product_images_master);

Share this post


Link to post
Share on other sites
I was using import - is that the reason why it was de-duplicating on the file name?

Yep. WireArray::import() des check if the value is already in the array, if so, it does not import it again.

In your case, I guess the PageImage::toString() method returns the same filename, so ProcessWire assumes that it's the same image, although it's from a different page.

What you could do is to add them to a normal PHP array and then use WireArray::setArray() to pass them (not tested):

$productImages = new WireArray();

$temp = array();
foreach ($page->childern as $p) {
  $temp = array_merge($temp, $p->product_images->getArray());
}

$productImages->setArray($temp);

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

I think i may actually require that these go directly into WireArray, because when they are being output, i am using a lot of the properties, like $image->page, and then all of the inherited fields of the page that the image was pulled from; if i were to put them into a plain array, i would lose the $page property...

maybe there needs to be a parameter for import which allows duplicates, especially in the case of page images?

EDIT: or maybe your example does preserve the properties, with the getArray() ? will have to get more up to speed on that..

Share this post


Link to post
Share on other sites

Yep, the values of the array are still wire derived objects, so it should work.

  • Like 1

Share this post


Link to post
Share on other sites

cool... will do some testing and report back;

wondering if this should be documented somewhere, because i can see people assuming that the WireArray would differentiate images with the same name if they were keyed to different pages..

Share this post


Link to post
Share on other sites

Why do you need WireArray? It can be a normal array and store images in there.

Share this post


Link to post
Share on other sites

You would not loose anything. You can add objects to a normal array and later can access them and they're still a Pageimage with all its properties.

Share this post


Link to post
Share on other sites

Why do you need WireArray? It can be a normal array and store images in there.

Why not? :)

WireArray offers way more possibilities for manipulating/filtering data, which is always nice to have.

Share this post


Link to post
Share on other sites

for now i'm using the method that Wanze posted, and it is working fine... along the way of this project i may test it with a normal array..

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By ngrmm
      I want to have filters with month names in german. I fetch them from date-fields with strftime('%B', $timestamp);
      But i'm not able to add them correctly to a wireArray()
      What's the right way to do that?
      $ms = wireArray(); $m1 = strftime('%B', 1579643232); // Januar $m2 = strftime('%B', 1583107200); // März $ms->prepend($m1); $ms->prepend($m2); foreach($ms as $name) { echo "$name "; // result: Januar M�rz }  
    • By celfred
      Hello,
      Still in my 'teaching game'. Here's my problem : I 'find' all players with a request like

      $allPlayers = $pages->find("template=player"); [/code Then, I limit to players belonging to the team of the logged in player with [code] $teamPlayers = $allPlayers->find("team=$loggedPlayer->team");
      No problem so far. But my scoreboards rely on either :

      $allPlayers->getItemKey($loggedPlayer);
      or

      $teamPlayers->getItemKey($loggedPlayer);
      to find the logged player's position in the charts.
      On the 'global' newboard with scoreboards based upon $allPlayers, everything works as expected.
      BUT on my 'team' newsboard, even though I'm using $teamPlayers, the returned indexes are based upon $allPlayers. Am I clear ? In other words, I have a total of 125 players, and my logged player is 61 out of 125 regarding the number of places he freed. But in his particular team of 25 players, he sould be 15 whereas he's still 61
      I'd like to reset my indexes (and start back from 0), but I can't find my way out of this...
      If someone has a hint to help, I'd appreciate.
      I have a second part in my worry : I had a way around it by simply making another 'raw' request :

      $teamPlayers = $pages->find("team=$loggedPlayer->team");
      Then my team indexes were right, but I faced another issue : Reordering my wirearray according to the scoreboard I want usually worked fine (simple sort() based upon an integer field, for example, player's coins, player's karma...) and indexes were updated BUT resorting with places.count ('places' field is a pageArray) doesn't update the indexes returned by getItemKey and my logged player is always at the position he was when I first did my initial $pages->find() query  
      So my way around found its limit and that's why I'm posting here, after struggling with this for a couple of hours...
      Thanks in advance for the help. 
    • By SwimToWin
      While ProcessWire and WireArray does not have support for array_chunk, there is a simple way to achieve this.
      With array_chunk() you can easily add DIVs to a foreach loop, without having to set up counters when using general PHP (hat-tip to Laurance over at StackOverflow). The idea in a ProcessWire context is to use array_chunk() to split an array into chunks - and use eq() when looping page results.
      Simple example that will split a WireArray into three columns. Before we begin, you should know the array_chunk syntax: array_chunk($array, $chunk_size, $preserve_keys=true|false).
      <?php $p = $pages->get('/news')->children('limit=15, template=article, sort=-sort'); ?> <div class="row"> <?php foreach (array_chunk(range(0,14),5) as $chunk): ?> <div class="col"> <?php foreach ($chunk as $i): ?> <h5><a href="<?=$p->eq($i)->url?>"><?=$p->eq($i)->title?></a></h5> <?php endforeach; ?> </div> <?php endforeach; ?> </div> A more realistic example:
      <?php $p = $pages->get('/news'); $pp = $p->children('limit=15, template=article, sort=-sort'); ?> <h2><a href="<?=$p->url?>"><?=$p->title?></a></h2> <div class="row"> <?php foreach (array_chunk(range(0,14),5) as $chunk): ?> <div class="col"> <?php foreach ($chunk as $i): ?> <h5> <a href="<?=$pp->eq($i)->url?>"><?=$pp->eq($i)->title?></a> </h5> <?php endforeach; ?> </div> <?php endforeach; ?> </div>
    • By kongondo
      In a module-context, as we know, stuff like single file or image fields return 'arrays', i.e. become iterable. This means that directly using WireArray::Iterable() to check whether a field is iterable can be misleading. Other than to temporarily set a page's output formatting to true (still within a module context), checking iterability of a field on the page, then reverting the page's output formatting to false after the check, is there another/a better way to achieve the same feat? Thanks.
       
       
    • By pwFoo
      Hi,
      I build a new module and try to convert data into WireArray to get the PW API benefits (find('selector'), get('selector'), ...).
      Some code to my tests...
      Define a custom WireArray class
      class CustomWireArray extends WireArray { public $toStringString = ''; public function __toString() { return $this->toStringString; } public function __get($key) { return $this->$key; } public function __set($key, $value) { $this->$key = $value; } } Create a new CustomWireArray
      $customWireArray = new customWireArray(); Create a new array item
      $item = new customWireArray(); // set properties to $item... $customWireArray->add($item); // add to the customWireArray So far it works fine. No problem to find() / get() properties from the $customWireArray, but I need sub-items 
      Tested it with a sub-customWireArray and also a simple stdClass, but it won't work with PW find() / get().
      Is there a way to get sub-properties work with something like that?
      $result = $customWireArray->find('property.subfield=MyValue');
×
×
  • Create New...