From 77fb5c5bd0366a7be7044e0adc22d3ee1299a6d8 Mon Sep 17 00:00:00 2001 From: jjgrainger Date: Wed, 10 Dec 2025 21:59:50 +0000 Subject: [PATCH 1/7] update columns methods --- src/Column.php | 6 +- src/ColumnBuilder.php | 107 ++++++++++++++++ src/Columns.php | 207 ++++++++++++++++++------------- src/Contracts/ColumnContract.php | 8 +- tests/ColumBuilderTest.php | 122 ++++++++++++++++++ tests/ColumnTest.php | 2 +- tests/ColumnsTest.php | 198 +++++++++++++---------------- 7 files changed, 444 insertions(+), 206 deletions(-) create mode 100644 src/ColumnBuilder.php create mode 100644 tests/ColumBuilderTest.php diff --git a/src/Column.php b/src/Column.php index 857c7b0..7bdace6 100644 --- a/src/Column.php +++ b/src/Column.php @@ -37,9 +37,9 @@ public function populate(int $objectId): void /** * Set the column order. * - * @return integer|null + * @return array|null */ - public function order(): ?int + public function position(): ?array { return null; } @@ -50,7 +50,7 @@ public function order(): ?int * @param \WP_Query|\WP_Term_Query $query * @return void */ - public function sort($query) + public function sort($query): void { return; } diff --git a/src/ColumnBuilder.php b/src/ColumnBuilder.php new file mode 100644 index 0000000..be599b5 --- /dev/null +++ b/src/ColumnBuilder.php @@ -0,0 +1,107 @@ +manager = $manager; + $this->key = $key; + } + + /** + * Set the label for the column. + * + * @param string $label + * @return ColumnBuilder + */ + public function label(string $label): ColumnBuilder + { + $this->manager->add($this->key, $label); + + return $this; + } + + /** + * Position a column. + * + * @param string $direction + * @param string $reference + * @return ColumnBuilder + */ + public function position(string $direction, string $reference): ColumnBuilder + { + $this->manager->position($this->key, $direction, $reference); + + return $this; + } + + /** + * Position a column after another. + * + * @param string $reference + * @return ColumnBuilder + */ + public function after(string $reference): ColumnBuilder + { + return $this->position('after', $reference); + } + + /** + * Position a column before another. + * + * @param string $reference + * @return ColumnBuilder + */ + public function before(string $reference): ColumnBuilder + { + return $this->position('before', $reference); + } + + /** + * Set columns populate callback. + * + * @param callable $callback + * @return ColumnBuilder + */ + public function populate(callable $callback): ColumnBuilder + { + $this->manager->populate($this->key, $callback); + + return $this; + } + + /** + * Set columns sort callback. + * + * @param callable $callback + * @return ColumnBuilder + */ + public function sort(callable $callback): ColumnBuilder + { + $this->manager->sort($this->key, $callback); + + return $this; + } +} diff --git a/src/Columns.php b/src/Columns.php index cdd7be5..e442f6b 100644 --- a/src/Columns.php +++ b/src/Columns.php @@ -2,6 +2,7 @@ namespace PostTypes; +use InvalidArgumentException; use PostTypes\Contracts\ColumnContract; class Columns @@ -11,35 +12,42 @@ class Columns * * @var array */ - public $add = []; + protected $columns = []; /** - * Column populate callbacks. + * Columns to remove. * * @var array */ - public $populate = []; + protected $remove = []; /** - * Columns to remove. + * Columns to set. + * + * @var array + */ + protected $only = []; + + /** + * Column positions. * * @var array */ - public $remove = []; + protected $positions = []; /** - * Columns order. + * Column populate callbacks. * * @var array */ - public $order = []; + protected $populateCallbacks = []; /** * Sortable columns and sort callbacks. * * @var array */ - public $sortable = []; + protected $sortCallbacks = []; /** * Add a column object. @@ -47,48 +55,55 @@ class Columns * @param ColumnContract $column * @return void */ - public function column(ColumnContract $column) + public function column(ColumnContract $column): void { $this->add($column->name(), $column->label()); $this->populate($column->name(), [$column, 'populate']); - if (!is_null($column->order())) { - $this->order[$column->name()] = $column->order(); + if (!is_null($column->position())) { + [$direction, $reference] = $column->position(); + + $this->position($column->name(), $direction, $reference); } if ($column->isSortable()) { - $this->sortable($column->name(), [$column, 'sort']); + $this->sort($column->name(), [$column, 'sort']); } } /** - * Add a column. + * Create a new Column. * * @param string $key - * @param string $label - * @param callable|null $callback - * @return void + * @return ColumnBuilder */ - public function add(string $key, string $label, callable $callback = null) + public function create(string $key): ColumnBuilder { - $this->add[$key] = $label; + return new ColumnBuilder($this, $key); + } - if (is_callable($callback)) { - $this->populate($key, $callback); - } + /** + * Modify an existing column. + * + * @param string $key + * @return ColumnBuilder + */ + public function modify(string $key): ColumnBuilder + { + return $this->create($key); } /** - * Set column populate callback. + * Add a column. * * @param string $key - * @param callable $callback + * @param string $label * @return void */ - public function populate(string $key, callable $callback) + public function add(string $key, string $label): void { - $this->populate[$key] = $callback; + $this->columns[$key] = $label; } /** @@ -97,115 +112,133 @@ public function populate(string $key, callable $callback) * @param array $keys * @return void */ - public function remove(array $keys) + public function remove(array $keys): void { $this->remove = array_merge($this->remove, $keys); } /** - * Set columns order + * Set columns. * - * @param array $order + * @param array $keys * @return void */ - public function order(array $order) + public function only(array $keys): void { - $this->order = array_merge($this->order, $order); + $this->only = array_merge($this->only, $keys); } /** - * Set sortable columns and sort callback. + * Set column position. * * @param string $key - * @param callable $callback + * @param string $direction + * @param string $reference * @return void + * @throws InvalidArgumentException */ - public function sortable(string $key, callable $callback) + public function position(string $key, string $direction, string $reference): void { - $this->sortable[$key] = $callback; + if (!in_array($direction, ['before', 'after'], true)) { + throw new InvalidArgumentException("Invalid position direction '{$direction}'"); + } + + $this->positions[$key] = [$direction, $reference]; } /** - * Apply columns. + * Set column populate callback. * - * @param array $columns + * @param string $key + * @param callable $callback * @return void */ - public function applyColumns(array $columns) + public function populate(string $key, callable $callback): void { - if (!empty($this->add)) { - $columns = array_merge($columns, $this->add); - } - - if (!empty($this->remove)) { - $columns = array_diff_key($columns, array_flip($this->remove)); - } - - if (!empty($this->order)) { - $order = $this->order; - - // Sort the order array. - asort($order); - - // Flip order so the index is the position. - $order = array_flip($order); + $this->populateCallbacks[$key] = $callback; + } - // Create the current order array. - $current = array_keys($columns); + /** + * Set sortable columns and sort callback. + * + * @param string $key + * @param callable $callback + * @return void + */ + public function sort(string $key, callable $callback): void + { + $this->sortCallbacks[$key] = $callback; + } - // Loop over the order. - foreach ($order as $index => $key) { - array_splice($current, $index, 0, $key); - } + /** + * Get columns to add. + * + * @return array + */ + public function getColumns(): array + { + return $this->columns; + } - $new = array_flip(array_unique($current)); + /** + * Get removed columns. + * + * @return array + */ + public function getRemoved(): array + { + return $this->remove; + } - $columns = array_merge($new, $columns); - } + /** + * Get only columns. + * + * @return array + */ + public function getOnly(): array + { + return $this->only; + } - return $columns; + /** + * Get column positions. + * + * @return array + */ + public function getPositions(): array + { + return $this->positions; } /** - * Populate a column. + * Get a column populate callback. * - * @param string $column - * @param array $params - * @return void + * @param string $key + * @return callable|null */ - public function populateColumn(string $column, array $params) + public function getPopulateCallback(string $key): ?callable { - if (isset($this->populate[$column]) && is_callable($this->populate[$column])) { - call_user_func_array($this->populate[$column], $params); - } + return $this->populateCallbacks[$key] ?? null; } /** - * Set sortable columns + * Get sortable columns. * - * @param array $columns * @return array */ - public function setSortable(array $columns): array + public function getSortableColumns(): array { - foreach (array_keys($this->sortable) as $key) { - $columns[$key] = $key; - } - - return $columns; + return array_combine(array_keys($this->sortCallbacks), array_keys($this->sortCallbacks)); } /** - * Sort a column. + * Get column sort callback. * - * @param string $column - * @param \WP_Query|\WP_Term_Query $query - * @return void + * @param string $key + * @return callable|null */ - public function sortColumn(string $column, $query) + public function getSortCallback(string $key): ?callable { - if (isset($this->sortable[$column]) && is_callable($this->sortable[$column])) { - call_user_func_array($this->sortable[$column], [$query]); - } + return $this->sortCallbacks[$key] ?? null; } } diff --git a/src/Contracts/ColumnContract.php b/src/Contracts/ColumnContract.php index 45c955e..73edd25 100644 --- a/src/Contracts/ColumnContract.php +++ b/src/Contracts/ColumnContract.php @@ -27,11 +27,11 @@ public function label(): string; public function populate(int $objectId): void; /** - * Set the column order. + * Set the column position. * - * @return integer|null + * @return array|null */ - public function order(): ?int; + public function position(): ?array; /** * Handle sorting the column. @@ -39,7 +39,7 @@ public function order(): ?int; * @param \WP_Query|\WP_Term_Query $query * @return void */ - public function sort($query); + public function sort($query): void; /** * Can the column be sorted. diff --git a/tests/ColumBuilderTest.php b/tests/ColumBuilderTest.php new file mode 100644 index 0000000..e5b3558 --- /dev/null +++ b/tests/ColumBuilderTest.php @@ -0,0 +1,122 @@ +createMock(Columns::class); + + $manager->expects($this->once()) + ->method('add') + ->with('price', 'Price Label'); + + $builder = new ColumnBuilder($manager, 'price'); + + $result = $builder->label('Price Label'); + + $this->assertSame($builder, $result); // fluent + } + + public function test_position_sets_position_correctly() + { + $manager = $this->createMock(Columns::class); + + $manager->expects($this->once()) + ->method('position') + ->with('price', 'after', 'title'); + + $builder = new ColumnBuilder($manager, 'price'); + + $result = $builder->position('after', 'title'); + + $this->assertSame($builder, $result); + } + + public function test_after_sets_position_after_reference() + { + $manager = $this->createMock(Columns::class); + + $manager->expects($this->once()) + ->method('position') + ->with('price', 'after', 'title'); + + $builder = new ColumnBuilder($manager, 'price'); + + $result = $builder->after('title'); + + $this->assertSame($builder, $result); + } + + public function test_before_sets_position_before_reference() + { + $manager = $this->createMock(Columns::class); + + $manager->expects($this->once()) + ->method('position') + ->with('price', 'before', 'title'); + + $builder = new ColumnBuilder($manager, 'price'); + + $result = $builder->before('title'); + + $this->assertSame($builder, $result); + } + + public function test_populate_sets_populate_callback() + { + $callback = function () {}; + + $manager = $this->createMock(Columns::class); + + $manager->expects($this->once()) + ->method('populate') + ->with('price', $callback); + + $builder = new ColumnBuilder($manager, 'price'); + + $result = $builder->populate($callback); + + $this->assertSame($builder, $result); + } + + public function test_sort_sets_sort_callback() + { + $callback = function () {}; + + $manager = $this->createMock(Columns::class); + + $manager->expects($this->once()) + ->method('sort') + ->with('price', $callback); + + $builder = new ColumnBuilder($manager, 'price'); + + $result = $builder->sort($callback); + + $this->assertSame($builder, $result); + } + + public function test_builder_fluency_all_methods_chain() + { + $manager = $this->createMock(Columns::class); + + $manager->expects($this->once())->method('add')->with('price', 'Price'); + $manager->expects($this->once())->method('position')->with('price', 'after', 'title'); + $manager->expects($this->once())->method('populate'); + $manager->expects($this->once())->method('sort'); + + $builder = new ColumnBuilder($manager, 'price'); + + $result = $builder + ->label('Price') + ->after('title') + ->populate(function () {}) + ->sort(function () {}); + + $this->assertSame($builder, $result); + } +} diff --git a/tests/ColumnTest.php b/tests/ColumnTest.php index 4bafa1a..ab7e5bd 100644 --- a/tests/ColumnTest.php +++ b/tests/ColumnTest.php @@ -16,7 +16,7 @@ public function test_column_returns_defaults() $this->assertEquals('price', $stub->name()); $this->assertEquals('Price', $stub->label()); $this->assertEquals(null, $stub->populate(1)); - $this->assertEquals(null, $stub->order()); + $this->assertEquals(null, $stub->position()); $this->assertEquals(null, $stub->sort(true)); $this->assertEquals(false, $stub->isSortable()); } diff --git a/tests/ColumnsTest.php b/tests/ColumnsTest.php index 7500015..b0818ad 100644 --- a/tests/ColumnsTest.php +++ b/tests/ColumnsTest.php @@ -1,8 +1,9 @@ add('column', 'Test Column'); - $this->assertArrayHasKey('column', $columns->add); - $this->assertSame('Test Column', $columns->add['column']); + $output = $columns->getColumns(); + + $this->assertArrayHasKey('column', $output); + $this->assertSame('Test Column', $output['column']); } public function test_can_add_column_with_column_class() { - $stub = $this->getMockForAbstractClass(Column::class); + $stub = $this->createMock(ColumnContract::class); - $stub->expects($this->any()) - ->method('name') - ->will($this->returnValue('column')); + $stub->method('name')->willReturn('column'); + $stub->method('label')->willReturn('Column'); + $stub->method('position')->willReturn(['after', 'title']); + $stub->method('isSortable')->willReturn(true); + $stub->method('sort')->willReturnCallback(function () {}); $columns = new Columns; $columns->column($stub); - $this->assertArrayHasKey('column', $columns->add); - $this->assertSame('Column', $columns->add['column']); + $output = $columns->getColumns(); + $positions = $columns->getPositions(); + $sortable = $columns->getSortCallback('column'); + + $this->assertArrayHasKey('column', $output); + $this->assertSame('Column', $output['column']); + + $this->assertArrayHasKey('column', $positions); + $this->assertSame(['after', 'title'], $positions['column']); + + $this->assertIsCallable($sortable); + } + + public function test_create_returns_column_builder() + { + $columns = new Columns; - $this->assertArrayHasKey('column', $columns->populate); - $this->assertIsCallable($columns->populate['column']); + $builder = $columns->create('new_column'); + + $this->assertInstanceOf(ColumnBuilder::class, $builder); } - public function test_can_add_column_with_populate_callback() + public function test_modify_returns_column_builder() { $columns = new Columns; - $columns->add('column', 'Test Column', function() {}); + $builder = $columns->modify('existing'); - $this->assertArrayHasKey('column', $columns->populate); - $this->assertIsCallable($columns->populate['column']); + $this->assertInstanceOf(ColumnBuilder::class, $builder); } public function test_can_set_column_populate_callback() { $columns = new Columns; - $columns->populate('column', function() {}); + $callback = function () {}; + $columns->populate('column', $callback); + + $this->assertSame($callback, $columns->getPopulateCallback('column')); + } - $this->assertArrayHasKey('column', $columns->populate); - $this->assertIsCallable($columns->populate['column']); + public function test_get_populate_callback_returns_null_for_missing_key() + { + $columns = new Columns; + + $this->assertNull($columns->getPopulateCallback('missing')); } public function test_can_set_remove_column() @@ -60,7 +86,7 @@ public function test_can_set_remove_column() $columns->remove(['column']); - $this->assertEquals(['column'], $columns->remove); + $this->assertEquals(['column'], $columns->getRemoved()); } public function test_can_set_remove_columns_with_multiple_calls() @@ -70,150 +96,100 @@ public function test_can_set_remove_columns_with_multiple_calls() $columns->remove(['column']); $columns->remove(['column_2']); - $this->assertEquals(['column', 'column_2'], $columns->remove); + $this->assertEquals(['column', 'column_2'], $columns->getRemoved()); } - public function test_can_set_order_columns() + public function test_can_set_only_columns() { $columns = new Columns; - $columns->order([ - 'column' => 1, - ]); + $columns->only(['one']); + $columns->only(['two']); - $this->assertEquals(['column' => 1], $columns->order); + $this->assertEquals(['one', 'two'], $columns->getOnly()); } - public function test_can_set_order_columns_with_multiple_calls() + public function test_can_set_position_after() { $columns = new Columns; - $columns->order(['column' => 1]); - $columns->order(['column_2' => 3]); + $columns->position('col', 'after', 'title'); - $this->assertEquals(['column' => 1, 'column_2' => 3], $columns->order); + $this->assertSame(['after', 'title'], $columns->getPositions()['col']); } - public function test_can_order_column_with_column_class() + public function test_can_set_position_before() { $columns = new Columns; - $stub = $this->createMock(Column::class); - - $stub->expects($this->any()) - ->method('name') - ->will($this->returnValue('column')); - - $stub->expects($this->any()) - ->method('order') - ->will($this->returnValue(1)); + $columns->position('col', 'before', 'date'); + $this->assertSame(['before', 'date'], $columns->getPositions()['col']); + } - $columns->column($stub); + public function test_position_throws_exception_for_invalid_direction() + { + $this->expectException(InvalidArgumentException::class); - $this->assertEquals(['column' => 1], $columns->order); + $columns = new Columns; + $columns->position('col', 'sideways', 'title'); } public function test_can_set_sortable_column() { $columns = new Columns; - $columns->sortable('column', function() {}); + $callback = function () {}; + $columns->sort('column', $callback); - $this->assertArrayHasKey('column', $columns->sortable); - $this->assertIsCallable($columns->sortable['column']); + $this->assertSame($callback, $columns->getSortCallback('column')); } - public function test_can_apply_columns() + public function test_get_sortable_columns_returns_keys_mapped_to_keys() { $columns = new Columns; - $columns->add('column_5', 'Column 5'); + $columns->sort('a', function () {}); + $columns->sort('b', function () {}); - $columns->remove(['column_2']); - - $columns->order([ - 'column_3' => 0, - ]); - - $original = [ - 'column_1' => 'Column 1', - 'column_2' => 'Column 2', - 'column_3' => 'Column 3', - 'column_4' => 'Column 4', - ]; - - $modified = $columns->applyColumns($original); - - $expected = [ - 'column_3' => 'Column 3', - 'column_1' => 'Column 1', - 'column_4' => 'Column 4', - 'column_5' => 'Column 5', - ]; - - $this->assertSame($expected, $modified); + $this->assertSame(['a' => 'a', 'b' => 'b'], $columns->getSortableColumns()); } - public function test_can_populate_column() + public function test_get_sortable_callback_returns_null_for_missing_key() { $columns = new Columns; - $stub = $this->createMock(Column::class); - - $stub->expects($this->any()) - ->method('name') - ->will($this->returnValue('column')); - - $stub->expects($this->once()) - ->method('populate') - ->with($this->greaterThan(0)); - - $columns->column($stub); - - $columns->populateColumn('column', [1]); + $this->assertNull($columns->getSortCallback('missing')); } - public function test_can_add_sortable_columns_to_sortable_list() + public function test_populate_does_not_affect_sort_callbacks() { $columns = new Columns; - $columns->sortable('column', function() {}); - - $sortable = [ - 'title' => 'title', - ]; - - $sortable = $columns->setSortable($sortable); + $columns->populate('col', function () {}); - $expected = [ - 'title' => 'title', - 'column' => 'column', - ]; - - $this->assertSame($expected, $sortable); + $this->assertNull($columns->getSortCallback('col')); } - public function test_can_sort_column() + public function test_sort_does_not_affect_populate_callbacks() { $columns = new Columns; - $stub = $this->createMock(Column::class); - - $stub->expects($this->any()) - ->method('name') - ->will($this->returnValue('column')); + $columns->sort('col', function () {}); - $stub->expects($this->once()) - ->method('isSortable') - ->will($this->returnValue(true)); + $this->assertNull($columns->getPopulateCallback('col')); + } - $stub->expects($this->once()) - ->method('sort') - ->with($this->greaterThan(0)); + public function test_add_does_not_overwrite_callback_data() + { + $columns = new Columns; - $columns->column($stub); + $columns->populate('col', function () {}); + $columns->sort('col', function () {}); + $columns->add('col', 'Label'); - $columns->sortColumn('column', 1); + // Callbacks remain unchanged + $this->assertIsCallable($columns->getPopulateCallback('col')); + $this->assertIsCallable($columns->getSortCallback('col')); } } From 57a178ac9c69e1b7a283f6492345bf62d11931b8 Mon Sep 17 00:00:00 2001 From: jjgrainger Date: Wed, 10 Dec 2025 22:00:12 +0000 Subject: [PATCH 2/7] update columns integration --- src/Registrars/PostTypeRegistrar.php | 57 +++++++++++++++++++--- src/Registrars/TaxonomyRegistrar.php | 52 ++++++++++++++++++-- tests/Registrars/PostTypeRegistrarTest.php | 2 +- tests/Registrars/TaxonomyRegistrarTest.php | 2 +- 4 files changed, 101 insertions(+), 12 deletions(-) diff --git a/src/Registrars/PostTypeRegistrar.php b/src/Registrars/PostTypeRegistrar.php index 6923693..2a5703b 100644 --- a/src/Registrars/PostTypeRegistrar.php +++ b/src/Registrars/PostTypeRegistrar.php @@ -45,11 +45,11 @@ public function register() add_action('init', [$this, 'initialize'], 10, 0); // Handle PostType filters. - add_action('restrict_manage_posts', [$this, 'modifyFilters'], 10, 2); + add_action('restrict_manage_posts', [$this, 'modifyFilters'], 10, 1); // Handle PostType columns. add_filter('manage_' . $name . '_posts_columns', [$this, 'modifyColumns'], 10, 1); - add_filter('manage_' . $name . '_posts_custom_column', [$this, 'populateColumns'], 10, 2); + add_action('manage_' . $name . '_posts_custom_column', [$this, 'populateColumns'], 10, 2); add_filter('manage_edit-' . $name . '_sortable_columns', [$this, 'setSortableColumns'], 10, 1); add_action('pre_get_posts', [$this, 'sortSortableColumns'], 10, 1); @@ -171,7 +171,43 @@ public function modifyFilters($posttype) */ public function modifyColumns(array $columns) { - return $this->columns->applyColumns($columns); + foreach ($this->columns->getColumns() as $key => $label) { + $columns[$key] = $label; + } + + if ($remove = $this->columns->getRemoved()) { + $columns = array_diff_key($columns, array_flip($remove)); + } + + if ($only = $this->columns->getOnly()) { + $columns = array_intersect_key($columns, array_flip($only)); + } + + foreach ($this->columns->getPositions() as $key => $position) { + [$direction, $reference] = $position; + + if (!isset($direction) || !isset($reference)) { + continue; + } + + $new = []; + + foreach ($columns as $k => $label) { + if ('before' === $direction && $k === $reference) { + $new[$key] = $columns[$key]; + } + + $new[$k] = $label; + + if ('after' === $direction && $k === $reference) { + $new[$key] = $columns[$key]; + } + } + + $columns = $new; + } + + return $columns; } /** @@ -183,7 +219,11 @@ public function modifyColumns(array $columns) */ public function populateColumns($column, $post_id) { - $this->columns->populateColumn($column, [$post_id]); + $callback = $this->columns->getPopulateCallback($column); + + if ($callback) { + call_user_func_array($callback, [$post_id]); + } } /** @@ -194,7 +234,9 @@ public function populateColumns($column, $post_id) */ public function setSortableColumns($columns) { - return $this->columns->setSortable($columns); + $sortable = $this->columns->getSortableColumns(); + + return array_merge($columns, $sortable); } /** @@ -210,7 +252,10 @@ public function sortSortableColumns($query) } $column = $query->get('orderby'); + $callback = $this->columns->getSortCallback($column); - $this->columns->sortColumn($column, $query); + if ($callback) { + call_user_func_array($callback, [$query]); + } } } diff --git a/src/Registrars/TaxonomyRegistrar.php b/src/Registrars/TaxonomyRegistrar.php index 1548c06..ec04262 100644 --- a/src/Registrars/TaxonomyRegistrar.php +++ b/src/Registrars/TaxonomyRegistrar.php @@ -115,7 +115,44 @@ public function registerTaxonomyToPostTypes() */ public function modifyColumns(array $columns) { - return $this->columns->applyColumns($columns); + foreach ($this->columns->getColumns() as $key => $label) { + $columns[$key] = $label; + } + + if ($remove = $this->columns->getRemoved()) { + $columns = array_diff_key($columns, array_flip($remove)); + } + + if ($only = $this->columns->getOnly()) { + $columns = array_intersect_key($columns, array_flip($only)); + } + + + foreach ($this->columns->getPositions() as $key => $position) { + [$direction, $reference] = $position; + + if (!isset($direction) || !isset($reference)) { + continue; + } + + $new = []; + + foreach ($columns as $k => $label) { + if ('before' === $direction && $k === $reference) { + $new[$key] = $columns[$key]; + } + + $new[$k] = $label; + + if ('after' === $direction && $k === $reference) { + $new[$key] = $columns[$key]; + } + } + + $columns = $new; + } + + return $columns; } /** @@ -128,7 +165,11 @@ public function modifyColumns(array $columns) */ public function populateColumns($content, $column, $term_id) { - $this->columns->populateColumn($column, [$term_id, $content]); + $callback = $this->columns->getPopulateCallback($column); + + if ($callback) { + call_user_func_array($callback, [$term_id, $content]); + } } /** @@ -139,7 +180,7 @@ public function populateColumns($content, $column, $term_id) */ public function setSortableColumns($columns) { - return $this->columns->setSortable($columns); + return array_merge($columns, $this->columns->getSortableColumns()); } /** @@ -155,7 +196,10 @@ public function sortSortableColumns($query) } $column = $query->query_vars['orderby']; + $callback = $this->columns->getSortCallback($column); - $this->columns->sortColumn($column, $query); + if ($callback) { + call_user_func_array($callback, [$query]); + } } } diff --git a/tests/Registrars/PostTypeRegistrarTest.php b/tests/Registrars/PostTypeRegistrarTest.php index eb480e2..adcc4ea 100644 --- a/tests/Registrars/PostTypeRegistrarTest.php +++ b/tests/Registrars/PostTypeRegistrarTest.php @@ -142,7 +142,7 @@ public function test_can_populate_column() public function test_can_set_sortable_columns() { $columns = new Columns; - $columns->sortable('column', function() {}); + $columns->sort('column', function() {}); $sortable = [ 'title' => 'title', diff --git a/tests/Registrars/TaxonomyRegistrarTest.php b/tests/Registrars/TaxonomyRegistrarTest.php index 15e62a9..47d0862 100644 --- a/tests/Registrars/TaxonomyRegistrarTest.php +++ b/tests/Registrars/TaxonomyRegistrarTest.php @@ -129,7 +129,7 @@ public function test_can_populate_column() public function test_can_set_sortable_columns() { $columns = new Columns; - $columns->sortable('column', function() {}); + $columns->sort('column', function() {}); $sortable = [ 'title' => 'title', From e9bd01d13644dc0aff16611d0b322b79c0b79fe3 Mon Sep 17 00:00:00 2001 From: jjgrainger Date: Tue, 16 Dec 2025 13:59:33 +0000 Subject: [PATCH 3/7] update columns method names --- src/Columns.php | 68 +++++++++++----------- tests/ColumnsTest.php | 8 +-- tests/Registrars/PostTypeRegistrarTest.php | 2 +- tests/Registrars/TaxonomyRegistrarTest.php | 2 +- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/Columns.php b/src/Columns.php index e442f6b..82c39fa 100644 --- a/src/Columns.php +++ b/src/Columns.php @@ -8,11 +8,11 @@ class Columns { /** - * Columns to add. + * Columns keys and labels. * * @var array */ - protected $columns = []; + protected $labels = []; /** * Columns to remove. @@ -22,7 +22,7 @@ class Columns protected $remove = []; /** - * Columns to set. + * Columns whitelist. * * @var array */ @@ -49,36 +49,13 @@ class Columns */ protected $sortCallbacks = []; - /** - * Add a column object. - * - * @param ColumnContract $column - * @return void - */ - public function column(ColumnContract $column): void - { - $this->add($column->name(), $column->label()); - - $this->populate($column->name(), [$column, 'populate']); - - if (!is_null($column->position())) { - [$direction, $reference] = $column->position(); - - $this->position($column->name(), $direction, $reference); - } - - if ($column->isSortable()) { - $this->sort($column->name(), [$column, 'sort']); - } - } - /** * Create a new Column. * * @param string $key * @return ColumnBuilder */ - public function create(string $key): ColumnBuilder + public function add(string $key): ColumnBuilder { return new ColumnBuilder($this, $key); } @@ -91,19 +68,30 @@ public function create(string $key): ColumnBuilder */ public function modify(string $key): ColumnBuilder { - return $this->create($key); + return $this->add($key); } /** - * Add a column. + * Add a column object. * - * @param string $key - * @param string $label + * @param ColumnContract $column * @return void */ - public function add(string $key, string $label): void + public function column(ColumnContract $column): void { - $this->columns[$key] = $label; + $this->label($column->name(), $column->label()); + + $this->populate($column->name(), [$column, 'populate']); + + if (!is_null($column->position())) { + [$direction, $reference] = $column->position(); + + $this->position($column->name(), $direction, $reference); + } + + if ($column->isSortable()) { + $this->sort($column->name(), [$column, 'sort']); + } } /** @@ -128,6 +116,18 @@ public function only(array $keys): void $this->only = array_merge($this->only, $keys); } + /** + * Set the label for a column. + * + * @param string $key + * @param string $label + * @return void + */ + public function label(string $key, string $label): void + { + $this->labels[$key] = $label; + } + /** * Set column position. * @@ -177,7 +177,7 @@ public function sort(string $key, callable $callback): void */ public function getColumns(): array { - return $this->columns; + return $this->labels; } /** diff --git a/tests/ColumnsTest.php b/tests/ColumnsTest.php index b0818ad..6e0ae0f 100644 --- a/tests/ColumnsTest.php +++ b/tests/ColumnsTest.php @@ -7,11 +7,11 @@ class ColumnsTest extends TestCase { - public function test_can_add_column() + public function test_can_label_column() { $columns = new Columns; - $columns->add('column', 'Test Column'); + $columns->label('column', 'Test Column'); $output = $columns->getColumns(); @@ -45,11 +45,11 @@ public function test_can_add_column_with_column_class() $this->assertIsCallable($sortable); } - public function test_create_returns_column_builder() + public function test_add_returns_column_builder() { $columns = new Columns; - $builder = $columns->create('new_column'); + $builder = $columns->add('new_column'); $this->assertInstanceOf(ColumnBuilder::class, $builder); } diff --git a/tests/Registrars/PostTypeRegistrarTest.php b/tests/Registrars/PostTypeRegistrarTest.php index adcc4ea..5dd0658 100644 --- a/tests/Registrars/PostTypeRegistrarTest.php +++ b/tests/Registrars/PostTypeRegistrarTest.php @@ -80,7 +80,7 @@ public function test_can_modify_columns() ]; $columns = new Columns; - $columns->add('date', 'Date', function() {}); + $columns->label('date', 'Date'); $stub = $this->getMockBuilder(PostType::class) ->getMock(); diff --git a/tests/Registrars/TaxonomyRegistrarTest.php b/tests/Registrars/TaxonomyRegistrarTest.php index 47d0862..a341a4f 100644 --- a/tests/Registrars/TaxonomyRegistrarTest.php +++ b/tests/Registrars/TaxonomyRegistrarTest.php @@ -68,7 +68,7 @@ public function test_can_modify_columns() ]; $columns = new Columns; - $columns->add('popularity', 'Popularity', function() {}); + $columns->label('popularity', 'Popularity'); $stub = $this->getMockBuilder(Taxonomy::class) ->getMock(); From 23baeb3d4e2197e2a5fef5ab104c2255d0a32081 Mon Sep 17 00:00:00 2001 From: jjgrainger Date: Tue, 16 Dec 2025 15:17:29 +0000 Subject: [PATCH 4/7] update column method and integrations --- src/Column.php | 36 ++++++++++++++-------- src/Columns.php | 10 +++--- src/Contracts/ColumnContract.php | 21 ++++--------- src/Registrars/TaxonomyRegistrar.php | 1 - tests/ColumnTest.php | 5 ++- tests/ColumnsTest.php | 6 ++-- tests/Registrars/PostTypeRegistrarTest.php | 2 +- tests/Registrars/TaxonomyRegistrarTest.php | 2 +- 8 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/Column.php b/src/Column.php index 7bdace6..662d580 100644 --- a/src/Column.php +++ b/src/Column.php @@ -26,12 +26,11 @@ public function label(): string /** * Populate the column. * - * @param integer $objectId - * @return void + * @return callable|bull */ - public function populate(int $objectId): void + public function populate(): ?callable { - return; + return null; } /** @@ -45,23 +44,34 @@ public function position(): ?array } /** - * Handle sorting the column. + * Return the sort callback for the column. + * + * @return callable|null + */ + public function sort(): ?callable + { + return null; + } + + /** + * Return the before position array structure. * - * @param \WP_Query|\WP_Term_Query $query - * @return void + * @param string $reference + * @return array */ - public function sort($query): void + protected function before(string $reference): array { - return; + return ['before', $reference]; } /** - * Can the column be sorted. + * Return the after position array structure. * - * @return boolean + * @param string $reference + * @return array */ - public function isSortable(): bool + protected function after(string $reference): array { - return false; + return ['after', $reference]; } } diff --git a/src/Columns.php b/src/Columns.php index 82c39fa..709622d 100644 --- a/src/Columns.php +++ b/src/Columns.php @@ -81,16 +81,18 @@ public function column(ColumnContract $column): void { $this->label($column->name(), $column->label()); - $this->populate($column->name(), [$column, 'populate']); - if (!is_null($column->position())) { [$direction, $reference] = $column->position(); $this->position($column->name(), $direction, $reference); } - if ($column->isSortable()) { - $this->sort($column->name(), [$column, 'sort']); + if ($callback = $column->populate()) { + $this->populate($column->name(), $callback); + } + + if ($callback = $column->sort()) { + $this->sort($column->name(), $callback); } } diff --git a/src/Contracts/ColumnContract.php b/src/Contracts/ColumnContract.php index 73edd25..12fa9c1 100644 --- a/src/Contracts/ColumnContract.php +++ b/src/Contracts/ColumnContract.php @@ -18,14 +18,6 @@ public function name(): string; */ public function label(): string; - /** - * Populate the column. - * - * @param integer $objectId - * @return void - */ - public function populate(int $objectId): void; - /** * Set the column position. * @@ -34,17 +26,16 @@ public function populate(int $objectId): void; public function position(): ?array; /** - * Handle sorting the column. + * Populate the column. * - * @param \WP_Query|\WP_Term_Query $query - * @return void + * @return callable|null */ - public function sort($query): void; + public function populate(): ?callable; /** - * Can the column be sorted. + * Handle sorting the column. * - * @return boolean + * @return callable|null */ - public function isSortable(): bool; + public function sort(): ?callable; } diff --git a/src/Registrars/TaxonomyRegistrar.php b/src/Registrars/TaxonomyRegistrar.php index ec04262..d6244e8 100644 --- a/src/Registrars/TaxonomyRegistrar.php +++ b/src/Registrars/TaxonomyRegistrar.php @@ -127,7 +127,6 @@ public function modifyColumns(array $columns) $columns = array_intersect_key($columns, array_flip($only)); } - foreach ($this->columns->getPositions() as $key => $position) { [$direction, $reference] = $position; diff --git a/tests/ColumnTest.php b/tests/ColumnTest.php index ab7e5bd..bc86be8 100644 --- a/tests/ColumnTest.php +++ b/tests/ColumnTest.php @@ -15,9 +15,8 @@ public function test_column_returns_defaults() $this->assertEquals('price', $stub->name()); $this->assertEquals('Price', $stub->label()); - $this->assertEquals(null, $stub->populate(1)); + $this->assertEquals(null, $stub->populate()); $this->assertEquals(null, $stub->position()); - $this->assertEquals(null, $stub->sort(true)); - $this->assertEquals(false, $stub->isSortable()); + $this->assertEquals(null, $stub->sort()); } } diff --git a/tests/ColumnsTest.php b/tests/ColumnsTest.php index 6e0ae0f..aa6ede4 100644 --- a/tests/ColumnsTest.php +++ b/tests/ColumnsTest.php @@ -26,14 +26,15 @@ public function test_can_add_column_with_column_class() $stub->method('name')->willReturn('column'); $stub->method('label')->willReturn('Column'); $stub->method('position')->willReturn(['after', 'title']); - $stub->method('isSortable')->willReturn(true); - $stub->method('sort')->willReturnCallback(function () {}); + $stub->method('populate')->willReturn(function () {}); + $stub->method('sort')->willReturn(function () {}); $columns = new Columns; $columns->column($stub); $output = $columns->getColumns(); $positions = $columns->getPositions(); + $populate = $columns->getPopulateCallback('column'); $sortable = $columns->getSortCallback('column'); $this->assertArrayHasKey('column', $output); @@ -42,6 +43,7 @@ public function test_can_add_column_with_column_class() $this->assertArrayHasKey('column', $positions); $this->assertSame(['after', 'title'], $positions['column']); + $this->assertIsCallable($populate); $this->assertIsCallable($sortable); } diff --git a/tests/Registrars/PostTypeRegistrarTest.php b/tests/Registrars/PostTypeRegistrarTest.php index 5dd0658..0ac3db1 100644 --- a/tests/Registrars/PostTypeRegistrarTest.php +++ b/tests/Registrars/PostTypeRegistrarTest.php @@ -119,7 +119,7 @@ public function test_can_populate_column() $stub->expects($this->once()) ->method('populate') - ->will($this->returnValue(true)); + ->willReturnCallback(function() {}); $columns->column($stub); diff --git a/tests/Registrars/TaxonomyRegistrarTest.php b/tests/Registrars/TaxonomyRegistrarTest.php index a341a4f..697b0f7 100644 --- a/tests/Registrars/TaxonomyRegistrarTest.php +++ b/tests/Registrars/TaxonomyRegistrarTest.php @@ -106,7 +106,7 @@ public function test_can_populate_column() $stub->expects($this->once()) ->method('populate') - ->will($this->returnValue(true)); + ->willReturnCallback(function() {}); $columns->column($stub); From 8361735ee30081497e87cdfb878d325faaa4f63f Mon Sep 17 00:00:00 2001 From: jjgrainger Date: Tue, 16 Dec 2025 15:17:35 +0000 Subject: [PATCH 5/7] update examples --- examples/Genres.php | 18 ++++++------------ examples/Price.php | 22 +++++++++++----------- examples/books.php | 20 ++++++++++++-------- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/examples/Genres.php b/examples/Genres.php index 5086a7a..1d46939 100644 --- a/examples/Genres.php +++ b/examples/Genres.php @@ -20,21 +20,15 @@ public function posttypes(): array { } public function columns( Columns $columns ): Columns { - $columns->remove(['posts']); + $columns->remove( [ 'posts' ] ); - $columns->add( - 'popularity', - __( 'Popularity', 'post-types' ), - function( $term_id ) { - echo get_term_meta( $term_id, 'popularity', true ); - } - ); + $columns->label( 'popularity', __( 'Popularity', 'post-types' ) ); - $columns->order( [ - 'popularity' => 2, - ] ); + $columns->populate( 'popularity', function( $term_id ) { + echo get_term_meta( $term_id, 'popularity', true ); + } ); - $columns->sortable( 'popularity', function( $query ) { + $columns->sort( 'popularity', function( $query ) { $query->query_vars['orderby'] = 'meta_value'; $query->query_vars['meta_key'] = 'popularity'; } ); diff --git a/examples/Price.php b/examples/Price.php index 6246a79..f161c1e 100644 --- a/examples/Price.php +++ b/examples/Price.php @@ -12,20 +12,20 @@ public function label(): string { return __( 'Price', 'post-types' ); } - public function order(): int { - return 2; + public function position(): array { + return $this->after( 'title' ); } - public function populate( int $post_id ): void { - echo '£' . get_post_meta( $post_id, 'price', true ); + public function populate(): callable { + return function( int $post_id ) { + echo '£' . get_post_meta( $post_id, 'price', true ); + }; } - public function isSortable(): bool { - return true; - } - - public function sort( $query ): void { - $query->set('orderby', 'meta_value_num'); - $query->set('meta_key', 'price'); + public function sort(): callable { + return function( $query ) { + $query->set( 'orderby', 'meta_value_num' ); + $query->set( 'meta_key', 'price' ); + }; } } diff --git a/examples/books.php b/examples/books.php index a3c5e32..4fb1851 100644 --- a/examples/books.php +++ b/examples/books.php @@ -70,23 +70,27 @@ public function columns( Columns $columns ): Columns { $columns->column( new Price ); - $columns->add( 'rating', __( 'Rating', 'post-types' ) ); + $columns->label( 'rating', __( 'Rating', 'post-types' ) ); $columns->populate( 'rating', function( $post_id ) { echo get_post_meta( $post_id, 'rating', true ); } ); - $columns->sortable( 'rating', function( $query ) { + $columns->sort( 'rating', function( $query ) { $query->set('orderby', 'meta_value_num'); $query->set('meta_key', 'rating'); } ); - $columns->order( [ - 'price' => 4, - 'rating' => 5, - 'taxonomy-genre' => 2, - 'tags' => 3, - ] ); + $columns->add( 'rating' ) + ->after( 'price' ) + ->label( __( 'Rating', 'post-types' ) ) + ->populate( function( $post_id ) { + echo get_post_meta( $post_id, 'rating', true ); + } ) + ->sort( function( $query ) { + $query->set('orderby', 'meta_value_num'); + $query->set('meta_key', 'rating'); + } ); return $columns; } From ba2605aa3fb3ac65a56969db80d779b2aa71c819 Mon Sep 17 00:00:00 2001 From: jjgrainger Date: Tue, 16 Dec 2025 18:53:26 +0000 Subject: [PATCH 6/7] update documentation for columns --- docs/post-types/Creating-columns.md | 29 +++++++++++++++------------- docs/post-types/Modifying-columns.md | 15 ++++++-------- docs/taxonomies/Modifying-columns.md | 8 +++----- examples/books.php | 2 ++ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/docs/post-types/Creating-columns.md b/docs/post-types/Creating-columns.md index 6561bba..ba9f030 100644 --- a/docs/post-types/Creating-columns.md +++ b/docs/post-types/Creating-columns.md @@ -34,35 +34,38 @@ class PriceColumn extends Column } /** - * Populate column callback. + * Position a column before/after another. * - * @return void + * @return array */ - public function populate( int $post_id ): void + public function position(): array { - echo '$' . get_post_meta( $post_id, '_price', true ); + return $this->after( 'title' ); } /** - * Set the column can be sorted. + * Populate column callback. * - * @return boolean + * @return callable */ - public function isSortable(): bool + public function populate(): callable { - return true; + return function( int $post_id ) { + echo '$' . get_post_meta( $post_id, '_price', true ); + }; } /** * Handle sorting the column by modifying the admin query. * - * @param $query \WP_Query - * @return void + * @return callable */ - public function sort(\WP_Query $query): void + public function sort(): callable { - $query->set( 'meta_key', '_price' ); - $query->set( 'orderby', 'meta_value_num' ); + return function( \WP_Query $query ) { + $query->set( 'meta_key', '_price' ); + $query->set( 'orderby', 'meta_value_num' ); + }; } } ``` diff --git a/docs/post-types/Modifying-columns.md b/docs/post-types/Modifying-columns.md index 362e300..0f10f3d 100644 --- a/docs/post-types/Modifying-columns.md +++ b/docs/post-types/Modifying-columns.md @@ -4,7 +4,7 @@ To modify a post types admin columns use the `column()` method. This method acce ## Adding Columns -To add columns to the admin edit screen pass an array of column slugs and labels to the `add()` method. +To add a column to the admin edit screen pass a column ket and label to the `label()` method. ```php use PostTypes\PostType; @@ -22,7 +22,7 @@ class Books extends PostType public function columns( Columns $column ): Columns { // Add a new price column. - $columns->add( 'price', __( 'Price', 'my-text-domain' ) ); + $columns->label( 'price', __( 'Price', 'my-text-domain' ) ); // Populate the price column with post meta. $columns->populate( 'price', function( $post_id ) { @@ -125,9 +125,9 @@ class Books extends PostType } ``` -## Column Order +## Column Positions -To rearrange columns pass an array of column slugs and position to the `order()` method. Only olumns you want to reorder need to be set, not all columns. +To rearrange columns pass an array of column slugs and position to the `position()` method. Only olumns you want to reorder need to be set, not all columns. ```php @@ -145,11 +145,8 @@ class Books extends PostType */ public function columns( Columns $column ): Columns { - // Order the new Rating and Genre columns. - $columns->order( [ - 'rating' => 2, - 'genre' => 4, - ] ); + // Position the rating column after the title column. + $columns->position( 'rating', 'after', 'title' ); return $columns; } diff --git a/docs/taxonomies/Modifying-columns.md b/docs/taxonomies/Modifying-columns.md index 0a5d1a3..be6d72f 100644 --- a/docs/taxonomies/Modifying-columns.md +++ b/docs/taxonomies/Modifying-columns.md @@ -22,7 +22,7 @@ class Genres extends Taxonomy public function columns( Columns $column ): Columns { // Add a new Popularity column. - $columns->add( 'popularity', __( 'Popularity', 'my-text-domain' ) ); + $columns->label( 'popularity', __( 'Popularity', 'my-text-domain' ) ); // Populate the popularity column with term meta. $columns->populate( 'popularity', function( $term_id ) { @@ -147,10 +147,8 @@ class Genres extends Taxonomy */ public function columns( Columns $column ): Columns { - // Order the new Popularity column. - $columns->order( [ - 'popularity' => 2, - ] ); + // Position the new Popularity column. + $columns->position( 'popularity', 'after', 'title' ); return $columns; } diff --git a/examples/books.php b/examples/books.php index 4fb1851..13d2b9a 100644 --- a/examples/books.php +++ b/examples/books.php @@ -72,6 +72,8 @@ public function columns( Columns $columns ): Columns { $columns->label( 'rating', __( 'Rating', 'post-types' ) ); + $columns->position( 'rating', 'after', 'price' ); + $columns->populate( 'rating', function( $post_id ) { echo get_post_meta( $post_id, 'rating', true ); } ); From 538602530841e6867a029a3d8d78549a71fd043a Mon Sep 17 00:00:00 2001 From: jjgrainger Date: Wed, 17 Dec 2025 17:45:19 +0000 Subject: [PATCH 7/7] update columns reference --- src/ColumnBuilder.php | 16 ++++++------ tests/ColumBuilderTest.php | 52 +++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/ColumnBuilder.php b/src/ColumnBuilder.php index be599b5..5dc823d 100644 --- a/src/ColumnBuilder.php +++ b/src/ColumnBuilder.php @@ -9,7 +9,7 @@ class ColumnBuilder * * @var Columns */ - protected $manager; + protected $columns; /** * Column key. @@ -21,12 +21,12 @@ class ColumnBuilder /** * Constructor. * - * @param Columns $manager + * @param Columns $columns * @param string $key */ - public function __construct(Columns $manager, string $key) + public function __construct(Columns $columns, string $key) { - $this->manager = $manager; + $this->columns = $columns; $this->key = $key; } @@ -38,7 +38,7 @@ public function __construct(Columns $manager, string $key) */ public function label(string $label): ColumnBuilder { - $this->manager->add($this->key, $label); + $this->columns->label($this->key, $label); return $this; } @@ -52,7 +52,7 @@ public function label(string $label): ColumnBuilder */ public function position(string $direction, string $reference): ColumnBuilder { - $this->manager->position($this->key, $direction, $reference); + $this->columns->position($this->key, $direction, $reference); return $this; } @@ -87,7 +87,7 @@ public function before(string $reference): ColumnBuilder */ public function populate(callable $callback): ColumnBuilder { - $this->manager->populate($this->key, $callback); + $this->columns->populate($this->key, $callback); return $this; } @@ -100,7 +100,7 @@ public function populate(callable $callback): ColumnBuilder */ public function sort(callable $callback): ColumnBuilder { - $this->manager->sort($this->key, $callback); + $this->columns->sort($this->key, $callback); return $this; } diff --git a/tests/ColumBuilderTest.php b/tests/ColumBuilderTest.php index e5b3558..daed557 100644 --- a/tests/ColumBuilderTest.php +++ b/tests/ColumBuilderTest.php @@ -8,28 +8,28 @@ class ColumnBuilderTest extends TestCase { public function test_label_sets_column_label() { - $manager = $this->createMock(Columns::class); + $columns = $this->createMock(Columns::class); - $manager->expects($this->once()) - ->method('add') + $columns->expects($this->once()) + ->method('label') ->with('price', 'Price Label'); - $builder = new ColumnBuilder($manager, 'price'); + $builder = new ColumnBuilder($columns, 'price'); $result = $builder->label('Price Label'); - $this->assertSame($builder, $result); // fluent + $this->assertSame($builder, $result); } public function test_position_sets_position_correctly() { - $manager = $this->createMock(Columns::class); + $columns = $this->createMock(Columns::class); - $manager->expects($this->once()) + $columns->expects($this->once()) ->method('position') ->with('price', 'after', 'title'); - $builder = new ColumnBuilder($manager, 'price'); + $builder = new ColumnBuilder($columns, 'price'); $result = $builder->position('after', 'title'); @@ -38,13 +38,13 @@ public function test_position_sets_position_correctly() public function test_after_sets_position_after_reference() { - $manager = $this->createMock(Columns::class); + $columns = $this->createMock(Columns::class); - $manager->expects($this->once()) + $columns->expects($this->once()) ->method('position') ->with('price', 'after', 'title'); - $builder = new ColumnBuilder($manager, 'price'); + $builder = new ColumnBuilder($columns, 'price'); $result = $builder->after('title'); @@ -53,13 +53,13 @@ public function test_after_sets_position_after_reference() public function test_before_sets_position_before_reference() { - $manager = $this->createMock(Columns::class); + $columns = $this->createMock(Columns::class); - $manager->expects($this->once()) + $columns->expects($this->once()) ->method('position') ->with('price', 'before', 'title'); - $builder = new ColumnBuilder($manager, 'price'); + $builder = new ColumnBuilder($columns, 'price'); $result = $builder->before('title'); @@ -70,13 +70,13 @@ public function test_populate_sets_populate_callback() { $callback = function () {}; - $manager = $this->createMock(Columns::class); + $columns = $this->createMock(Columns::class); - $manager->expects($this->once()) + $columns->expects($this->once()) ->method('populate') ->with('price', $callback); - $builder = new ColumnBuilder($manager, 'price'); + $builder = new ColumnBuilder($columns, 'price'); $result = $builder->populate($callback); @@ -87,13 +87,13 @@ public function test_sort_sets_sort_callback() { $callback = function () {}; - $manager = $this->createMock(Columns::class); + $columns = $this->createMock(Columns::class); - $manager->expects($this->once()) + $columns->expects($this->once()) ->method('sort') ->with('price', $callback); - $builder = new ColumnBuilder($manager, 'price'); + $builder = new ColumnBuilder($columns, 'price'); $result = $builder->sort($callback); @@ -102,14 +102,14 @@ public function test_sort_sets_sort_callback() public function test_builder_fluency_all_methods_chain() { - $manager = $this->createMock(Columns::class); + $columns = $this->createMock(Columns::class); - $manager->expects($this->once())->method('add')->with('price', 'Price'); - $manager->expects($this->once())->method('position')->with('price', 'after', 'title'); - $manager->expects($this->once())->method('populate'); - $manager->expects($this->once())->method('sort'); + $columns->expects($this->once())->method('label')->with('price', 'Price'); + $columns->expects($this->once())->method('position')->with('price', 'after', 'title'); + $columns->expects($this->once())->method('populate'); + $columns->expects($this->once())->method('sort'); - $builder = new ColumnBuilder($manager, 'price'); + $builder = new ColumnBuilder($columns, 'price'); $result = $builder ->label('Price')