PHPackages                             topshelfcraft/walk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. topshelfcraft/walk

ActiveCraft-plugin[Database &amp; ORM](/categories/database)

topshelfcraft/walk
==================

A Craft-aware array\_walk() method, plus some super-convenient console commands, to easily call Craft service methods on a collection of elements or values.

4.0.1(3y ago)221.5k2[3 issues](https://github.com/TopShelfCraft/Walk/issues)proprietaryPHPCI failing

Since Oct 19Pushed 3y ago2 watchersCompare

[ Source](https://github.com/TopShelfCraft/Walk)[ Packagist](https://packagist.org/packages/topshelfcraft/walk)[ RSS](/packages/topshelfcraft-walk/feed)WikiDiscussions 3.x Synced 2d ago

READMEChangelogDependencies (2)Versions (11)Used By (0)

Walk
====

[](#walk)

*Provides a Craft-aware `array_walk()` method, plus some super-convenient console commands, allowing you to easily call Craft service methods on a collection of elements or values.*

by [Michael Rog](https://topshelfcraft.com)

### TL;DR.

[](#tldr)

You want to perform some action, in bulk, on a bunch of elements.

Maybe you want to do it ad-hoc with an easy [console command](#walk-console-commands).

Or, maybe you want to do it in [one line of PHP](#walk-php-usage), in a custom component.

And you want to do this with several different sets of elements, and with several different bulk actions, without needing to write new code every time.

**Walk** gives you a special Craft-aware `array_walk` method to apply a Craft component method to each element in a list.

---

### Installation

[](#installation)

Install with Composer by running `composer require topshelfcraft/walk` from your project directory.

Then, visit the *Settings &gt; Plugins* page of the CP, and click to *Install* the **Walk** plugin.

### Walk a what?

[](#walk-a-what)

Applying a method to every item in a list is known as "walking" an array. In fact, PHP provides a method — [`array_walk()`](http://php.net/manual/en/function.array-walk.php) — to do just that.

However, PHP's [`array_walk`](http://php.net/manual/en/function.array-walk.php) method isn't aware of how Craft's *components* are set up, and it doesn't know anything about Elements.

So, where PHP's `array_walk` is useful for applying a *PHP* method to each item in an array, this plugin provides a *Craft-aware* walk function — `craftyArrayWalk()` — to run a *Craft* component method on each item in a list.

### Yes! This will save me *minutes*! How do I start?

[](#yes-this-will-save-me-minutes-how-do-i-start)

First, you need to have a *callable* in mind. A *callable* is the method that will be run on each item in the list.

**A callable is specified by its name as a string.** With this plugin, a *callable* can be:

- a method in one of Craft's native components: `'component.method'`
- a method in a plugin's module components: `'plugin.component.method'`
- any accessible custom function: `'myCustomMethod'`
- any native PHP function, e.g. `'strtolower'`

Second, you need a list of stuff (an *array*).

Then, just call the `craftyArrayWalk()` method, like this:

```
$success = WalkHelper::craftyArrayWalk($elements, $callable);
```

It works pretty much just like the native `array_walk` method:

- The *callable* is run once for each item in the array.
- For each step, the *item* is passed as the first parameter to the method.
- The array *index* is passed as the second parameter to the method.
- The array item is passed *by reference*, meaning if you change the variable inside the method, it will be changed in the source array.
- `craftyArrayWalk()` returns a boolean: `true` if successful, `false` if there was an issue.

*Technically, you can supply any valid PHP callable object to the `craftyArrayWalk` method. But if you already have a callable object in-hand, you probably don't have much need for this plugin. The advantage that this plugin's method provides over the native `array_walk` is that it recognizes those special callable strings, which represent methods in Craft.*

You can also provide extra some custom data if needed, by adding a third parameter, like this:

```
$success = WalkHelper::craftyArrayWalk($elements, $callable, $userdata);
```

The `$userdata` will be passed as the third parameter to the *callable* method on each step.

So, in technical terms, a *callable* method has the following *signature*:

```
public function myMethod( $element [, $index [, $userdata ]] )
```

### I need an example.

[](#i-need-an-example)

Let's start with an example of PHP's native `array_walk`:

You could do this:

```
$myArray = ["Michael", "Aaron", "Andrew", "Brad", "Brandon"]

foreach ($myArray as $key => $value)
{
    $myArray[$key] = strtolower($value);
}
```

But this is way prettier:

```
array_walk($myArray, 'strtolower');
```

These two examples accomplish the same thing: Afterwards, each string item in the array will have been transformed to lowercase.

**Now let's look at a *Crafty* example.**

You could do this:

```
$myEntries = Entry::find()->all();

foreach ($myEntries as $entry)
{
    Craft::$app->getElements->saveElement($entry);
}
```

But this is tighter:

```
WalkHelper::craftyArrayWalk($myEntries, 'elements.saveElement');
```

In both examples, each Entry in the query will be re-saved.

### Nifty... but I don't want to write any PHP. What about some ***console commands***?

[](#nifty-but-i-dont-want-to-write-any-php-what-about-some-console-commands)

That's actually why I wrote this plugin: I needed a fast, convenient way to do a bunch of indexing/re-saving, preferably from the CLI, without having to write a new custom command for each job/criteria combo.

So, without further ado, I give you... the `walk` *CLI command*.

```
./craft walk [list] [callable] --[options]=blah --asJob
```

So, let's break that down:

- `[list]` is:
    - an element type identifier (`assets`, `entries`, etc.)
    - an element *IDs* identifier (`assetIds`, `entryIds`, etc.)
    - a "count" directive (`countAssets`, `countEntries`, etc.)
- `[callable]` is the method/task you want to run on each item, as described [above](#walk-callable-formats).
- There are several supported `[options]`, described [below](#walk-command-options).
- The special (optional) `--asJob` option... I'll get to that [later](#walk-jobs-info).
- The order of *options* is arbitrary.

If you want to re-save all your blog entries...

```
./craft walk entries --section=blog --limit=null elements.saveElement
```

If you have a custom service method, and you want to run it once on each user:

```
./craft walk users --limit=null myPlugin.myComponent.myMethod
```

What if your custom method takes an element *ID* rather than an element *object*?

```
./craft walk entryIds myModule.myComponent.methodThatTakesAnId

```

Tada!

Or, perhaps you want to get a *count* of elements in a criteria, without actually *doing* anything to them?

```
./craft walk countEntries --section=blog

```

### Command options

[](#command-options)

The following Element Criteria attributes can be set via CLI option:

- `id`
- `limit` *(a number, or `null` for no limit)*
- `title`
- `slug`
- `relatedTo`
- `source`
- `sourceId`
- `kind`
- `filename`
- `folderId`
- `size`
- `group`
- `groupId`
- `authorGroup`
- `authorGroupId`
- `authorId`
- `locale`
- `section`
- `status`

(...plus, for Commerce Orders...)

- `dateOrdered`
- `datePaid`
- `email`
- `gatewayId`
- `hasPurchasables`
- `isCompleted`
- `isPaid`
- `isUnpaid`
- `orderStatus`
- `orderStatusId`
- `customerId`

### Does it work with custom element types?

[](#does-it-work-with-custom-element-types)

The Walk CLI command provides easy shorthands for Craft's built-in element types. However, you can use Walk with **any element type** by supplying its \[fully-qualified\] class name, along with the \[fully-qualified\] class name of the associated element *query*.

```
./craft walk/elements "mynamespace\elements\MyElementClass" --queryClass="mynamespace\elements\db\MyElementQuery" myPlugin.myComponent.myMethod

./craft walk/element-ids "craft\commerce\elements\Donation" --queryClass="craft\commerce\elements\db\DonationQuery" myPlugin.myComponent.methodThatTakesAnId

./craft walk/count "craft\elements\Entry" --queryClass="craft\elements\db\EntryQuery" elements.saveElement
```

### Oh, and you said something about *Jobs*...?

[](#oh-and-you-said-something-about-jobs)

Say you have a lot of elements... or your callable methods are performance-intensive... or you need things to keep running even if your CLI connection is closed... or you just prefer to schedule things one-at-a-time using the Craft queue...

There are a couple ways **Walk** might help.

#### 1. Schedule callables as Jobs using the CLI

[](#1-schedule-callables-as-jobs-using-the-cli)

You can use the special `--asJob` [command option](#walk-command-options) to schedule each walk step as a Job:

```
./craft walk entries elements.saveElement --asJob

./craft walk entryIds myModule.someComponent.aMethod --asJob
```

This will still invoke the callable once for each element or ID in the criteria, but it will do so from inside a Job — i.e. one request per element/step.

This is nice if you want to keep track of the queue progress, or if you want to be able to conveniently re-run any steps that fail due to an error.

In the Control Panel sidebar these show up as `CallOnElement` and `CallOnValue` jobs.

#### 2. Use a Job as a *callable* via the PHP methods

[](#2-use-a-job-as-a-callable-via-the-php-methods)

```
WalkHelper::spawnJobs(MyJob::class, $elementsOrIds, $settings = [], $valParam = 'elementId')
```

The `spawnJobs` method can be used to schedule one instance of a specified job per element or ID in the provided set.

The job is specified by full class name, just as if you were using `Craft::$app->queue->push()`.

You can supply an array of extra settings in the `$settings` argument, which will be applied to each job.

The specified job should expect to receive an `elementId` setting containing the element ID. Alternatively, you can also change the name of the setting that will receive the ID of the element, using the `$valParam` argument.

### Can I use this stuff with *any* array? Does it *have* to be elements/IDs?

[](#can-i-use-this-stuff-with-any-array-does-it-have-to-be-elementsids)

The console commands are designed to perform bulk actions on sets of Elements or IDs.

However, if you're feeling clever, you can use the `craftyArrayWalk()` helper method **with any array**.

For example, if you have an array of email addresses, and a `processEmailAddress` service method that takes an email address as its first argument...

```
$success = WalkHelper::craftyArrayWalk($emailAddresses, 'myPlugin.myService.processEmailAddress');
```

If you want to make your own console command that walks through some other set (i.e. not Elements or Element IDs), just check out the source code of the *WalkController*. You'll find it pretty easy to copy/paste your way to success!

### This is great! I still have questions.

[](#this-is-great-i-still-have-questions)

Ask a question on [StackExchange](http://craftcms.stackexchange.com/), and ping me with a URL via email or Discord.

### What are the system requirements?

[](#what-are-the-system-requirements)

Craft 3.0+ and PHP 7.0+

### I found a bug.

[](#i-found-a-bug)

Please open a GitHub Issue, submit a PR to the `3.x.dev` branch, or just email me.

---

#### Contributors:

[](#contributors)

- Plugin development: [Michael Rog](http://michaelrog.com) / @michaelrog
- Icon: [Margot Nadot](http://margotnadot.com/), via [The Noun Project](https://thenounproject.com/search/?q=walking&i=79275)

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance17

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~163 days

Recently: every ~194 days

Total

9

Last Release

1459d ago

Major Versions

3.x-dev → 4.0.02022-05-16

### Community

Maintainers

![](https://www.gravatar.com/avatar/7fabbca3f39380eadb6f89517be9a0fbc550159a1eec925452da43d14338de66?d=identicon)[TopShelfCraft](/maintainers/TopShelfCraft)

---

Top Contributors

[![michaelrog](https://avatars.githubusercontent.com/u/102379?v=4)](https://github.com/michaelrog "michaelrog (10 commits)")

---

Tags

bulk-actionscraftcms-pluginpluginconsolemigrationdevelopmentimportcmsutilitiesCraftcraftcmswalkarray\_walklist processing

### Embed Badge

![Health badge](/badges/topshelfcraft-walk/health.svg)

```
[![Health](https://phpackages.com/badges/topshelfcraft-walk/health.svg)](https://phpackages.com/packages/topshelfcraft-walk)
```

###  Alternatives

[dgrigg/craft-migration-assistant

Create content migrations at the click of a mouse. Keep environments in sync with ease.

2782.3k](/packages/dgrigg-craft-migration-assistant)[am-impact/amcommand

Command palette in Craft.

8674.1k3](/packages/am-impact-amcommand)[putyourlightson/craft-log-to-file

Logs messages to a specific log file for Craft CMS.

29368.0k5](/packages/putyourlightson-craft-log-to-file)[topshelfcraft/scraper

Easily fetch, parse, and rejigger HTML or XML from anywhere.

162.2k](/packages/topshelfcraft-scraper)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
