Skip to content

Commit 0e49fce

Browse files
committed
Fix CreateTemplatedPage & add UpdateTemplatedPage.
1 parent 3ebebb7 commit 0e49fce

File tree

6 files changed

+277
-22
lines changed

6 files changed

+277
-22
lines changed

src/Config.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use ProcessWire\WireData;
66
use ProcessWire\ProcessGraphQL;
7+
use ProcessWire\Fieldgroup;
78
use ProcessWire\GraphQL\Utils;
89

910
class Config extends WireData {
@@ -115,6 +116,13 @@ protected function getLegalCreateTemplates() {
115116
}
116117
}
117118

119+
// prevent creation of pages without required fields
120+
foreach ($templates as $template) {
121+
if (!self::allFieldsAreLegal($template->fields->find("required=1"))) {
122+
$templates->remove($template);
123+
}
124+
}
125+
118126
return $templates;
119127
}
120128

@@ -124,4 +132,13 @@ protected function getLegalFields()
124132
return Utils::fields()->getAll()->find("name=" . implode('|', $legalFields));
125133
}
126134

135+
public static function allFieldsAreLegal(Fieldgroup $fields)
136+
{
137+
$legalFields = Utils::moduleConfig()->legalFields;
138+
foreach ($fields as $field) {
139+
if (!$legalFields->has($field)) return false;
140+
}
141+
return true;
142+
}
143+
127144
}

src/Field/Mutation/CreateTemplatedPage.php

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
use ProcessWire\GraphQL\Utils;
2020
use ProcessWire\GraphQL\Type\Object\TemplatedPageType;
21-
use ProcessWire\GraphQL\Type\Input\TemplatedPageInputType;
21+
use ProcessWire\GraphQL\Type\Input\TemplatedPage\CreateInputType;
2222

2323
class CreateTemplatedPage extends AbstractField {
2424

@@ -50,7 +50,7 @@ public function build(FieldConfig $config)
5050
{
5151
$config->addArgument(new InputField([
5252
'name' => 'page',
53-
'type' => new NonNullType(new TemplatedPageInputType($this->template)),
53+
'type' => new NonNullType(new CreateInputType($this->template)),
5454
]));
5555
}
5656

@@ -69,21 +69,28 @@ public function resolve($value, array $args, ResolveInfo $info)
6969
\*********************************************/
7070
// can new pages be created for this template?
7171
if ($this->template->noParents === 1) throw new ValidationException("No new pages can be created for the template `{$this->template->name}`.");
72+
7273
// if there could be only one page is there already a page with this template
7374
if ($this->template->noParents === -1 && !$pages->get("template={$this->template}") instanceof NullPage) throw new ValidationException("Only one page with template `{$this->template->name}` can be created.");
74-
// find the parent, make sure it exists
75+
76+
// find the parent
7577
$parentSelector = $values['parent'];
7678
$parent = $pages->get($sanitizer->selectorValue($parentSelector));
79+
7780
// if no parent then no good. No child should born without a parent!
7881
if (!$parent || $parent instanceof NullPage) throw new ValidationException("Could not find the parent: '$parentSelector'.");
82+
7983
// make sure user is allowed to add children to this parent
8084
$legalAddTemplates = Utils::moduleConfig()->legalAddTemplates;
8185
if (!$legalAddTemplates->has($parent->template)) throw new ValidationException("You are not allowed to add children to the parent: '$parentSelector'.");
82-
// make sure it is allowed as a parent
86+
87+
// make sure parent is allowed as a parent for this page
8388
$parentTemplates = $this->template->parentTemplates;
8489
if (count($parentTemplates) && !in_array($parent->template->id, $parentTemplates)) throw new ValidationException("`parent` is not allowed as a parent.");
90+
8591
// make sure parent is allowed to have children
8692
if ($parent->template->noChildren === 1) throw new ValidationException("`parent` is not allowed to have children.");
93+
8794
// make sure the page is allowed as a child for parent
8895
$childTemplates = $parent->template->childTemplates;
8996
if (count($childTemplates) && !in_array($this->template->id, $childTemplates)) throw new ValidationException("not allowed to be a child for `parent`.");
@@ -108,14 +115,8 @@ public function resolve($value, array $args, ResolveInfo $info)
108115
foreach ($values as $fieldName => $value) {
109116
$field = $fields->get($fieldName);
110117
if (!$field instanceof Field) continue;
111-
switch ($field->type->className()) {
112-
case 'FieldtypePage':
113-
$p->setFieldValue($fieldName, implode('|', $value));
114-
break;
115-
default:
116-
$p->setFieldValue($fieldName, $value);
117-
break;
118-
}
118+
if ($field->type->className() === 'FieldtypePage') $value = implode('|', $value);
119+
$p->$fieldName = $value;
119120
}
120121

121122
// save the page to db
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
3+
namespace ProcessWire\GraphQL\Field\Mutation;
4+
5+
use Youshido\GraphQL\Field\AbstractField;
6+
use Youshido\GraphQL\Execution\ResolveInfo;
7+
use Youshido\GraphQL\Exception\ValidationException;
8+
use Youshido\GraphQL\Exception\ResolveException;
9+
use Youshido\GraphQL\Config\Field\FieldConfig;
10+
use Youshido\GraphQL\Field\InputField;
11+
use Youshido\GraphQL\Type\Scalar\IntType;
12+
use Youshido\GraphQL\Type\NonNullType;
13+
14+
use ProcessWire\Template;
15+
use ProcessWire\Page;
16+
use ProcessWire\NullPage;
17+
use ProcessWire\Field;
18+
use ProcessWire\FieldtypePage;
19+
20+
use ProcessWire\GraphQL\Type\Object\TemplatedPageType;
21+
use ProcessWire\GraphQL\Type\Input\TemplatedPage\UpdateInputType;
22+
23+
class UpdateTemplatedPage extends AbstractField {
24+
25+
protected $template;
26+
27+
public function __construct(Template $template)
28+
{
29+
$this->template = $template;
30+
parent::__construct([]);
31+
}
32+
33+
public function getName()
34+
{
35+
$typeName = ucfirst(TemplatedPageType::normalizeName($this->template->name));
36+
return "update{$typeName}";
37+
}
38+
39+
public function getType()
40+
{
41+
return new TemplatedPageType($this->template);
42+
}
43+
44+
public function getDescription()
45+
{
46+
return "Allows you to update Pages with template `{$this->template->name}`.";
47+
}
48+
49+
public function build(FieldConfig $config)
50+
{
51+
$config->addArgument(new InputField([
52+
'name' => 'id',
53+
'type' => new NonNullType(new IntType()),
54+
]));
55+
56+
$config->addArgument(new InputField([
57+
'name' => 'page',
58+
'type' => new NonNullType(new UpdateInputType($this->template)),
59+
]));
60+
}
61+
62+
public function resolve($value, array $args, ResolveInfo $info)
63+
{
64+
// prepare neccessary variables
65+
$pages = \ProcessWire\wire('pages');
66+
$sanitizer = \ProcessWire\wire('sanitizer');
67+
$fields = \ProcessWire\wire('fields');
68+
$values = (array) $args['page'];
69+
$id = (integer) $args['id'];
70+
$p = $pages->get($id);
71+
$p->of(false);
72+
73+
/*********************************************\
74+
* *
75+
* Don't ever take sides against the family! *
76+
* *
77+
\*********************************************/
78+
if (isset($values['parent'])) {
79+
80+
// find the parent
81+
$parentSelector = $values['parent'];
82+
$parent = $pages->find($sanitizer->selectorValue($parentSelector))->first();
83+
84+
// if no parent then no good. No child should born without a parent!
85+
if (!$parent || $parent instanceof NullPage) throw new ValidationException("Could not find the `parent` page with `$parentSelector`.");
86+
87+
// make sure user is allowed to add children to this parent
88+
$legalAddTemplates = Utils::moduleConfig()->legalAddTemplates;
89+
if (!$legalAddTemplates->has($parent->template)) throw new ValidationException("You are not allowed to add children to the parent: '$parentSelector'.");
90+
91+
// make sure parent is allowed as a parent for this page
92+
$parentTemplates = $this->template->parentTemplates;
93+
if (count($parentTemplates) && !in_array($parent->template->id, $parentTemplates)) throw new ValidationException("`parent` is not allowed as a parent.");
94+
95+
// make sure parent is allowed to have children
96+
if ($parent->template->noChildren === 1) throw new ValidationException("`parent` is not allowed to have children.");
97+
98+
// make sure the page is allowed as a child for parent
99+
$childTemplates = $parent->template->childTemplates;
100+
if (count($childTemplates) && !in_array($this->template->id, $childTemplates)) throw new ValidationException("not allowed to be a child for `parent`.");
101+
}
102+
103+
if (isset($values['name'])) {
104+
105+
// check if the name is valid
106+
$name = $sanitizer->pageName($values['name']);
107+
if (!$name) throw new ValidationException('value for `name` field is invalid,');
108+
109+
// find out if the name is taken
110+
$taken = $pages->find("parent=$parent, name=$name")->count();
111+
if ($taken) throw new ValidationException('`name` is already taken.');
112+
}
113+
114+
// update the values from client
115+
foreach ($values as $fieldName => $value) {
116+
$field = $fields->get($fieldName);
117+
if (!$field instanceof Field) continue;
118+
if ($field->type->className() === 'FieldtypePage') $value = implode('|', $value);
119+
$p->$fieldName = $value;
120+
}
121+
122+
// save the page to db
123+
if ($p->save()) return $pages->get("$p");
124+
125+
// If we did not return till now then no good!
126+
throw new ResolveException("Could not create page `$name` with template `{$this->template->name}`");
127+
}
128+
129+
}

src/Schema.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use ProcessWire\GraphQL\Field\Auth\LogoutField;
1111
use ProcessWire\GraphQL\Field\User\UserField;
1212
use ProcessWire\GraphQL\Field\Mutation\CreateTemplatedPage;
13+
use ProcessWire\GraphQL\Field\Mutation\UpdateTemplatedPage;
1314
use ProcessWire\GraphQL\Field\LanguageField;
1415

1516
class Schema extends AbstractSchema {
@@ -69,6 +70,11 @@ public function build(SchemaConfig $config)
6970
$mutation->addField(new CreateTemplatedPage($template));
7071
}
7172

73+
// UpdatePage
74+
foreach ($moduleConfig->legalEditTemplates as $template) {
75+
$mutation->addField(new UpdateTemplatedPage($template));
76+
}
77+
7278
}
7379

7480
public function getName()

src/Type/Input/TemplatedPageInputType.php renamed to src/Type/Input/TemplatedPage/CreateInputType.php

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
<?php
22

3-
namespace ProcessWire\GraphQL\Type\Input;
3+
namespace ProcessWire\GraphQL\Type\Input\TemplatedPage;
44

55
use Youshido\GraphQL\Type\InputObject\AbstractInputObjectType;
66
use Youshido\GraphQL\Type\NonNullType;
77
use Youshido\GraphQL\Type\Scalar\StringType;;
88
use ProcessWire\Template;
99
use ProcessWire\GraphQL\Utils;
1010

11-
class TemplatedPageInputType extends AbstractInputObjectType {
11+
class CreateInputType extends AbstractInputObjectType {
1212

1313
protected $template;
1414

15+
/**
16+
* Construct the TemplatedPageInputType.
17+
* @param Template $template The ProcessWire template that is used to generate
18+
* this's type's fields.
19+
*/
1520
public function __construct(Template $template)
1621
{
1722
$this->template = $template;
@@ -25,12 +30,12 @@ public function __construct(Template $template)
2530

2631
public function getName()
2732
{
28-
return ucfirst(self::normalizeName($this->template->name)) . 'PageInputType';
33+
return ucfirst(self::normalizeName($this->template->name)) . 'CreateInputType';
2934
}
3035

3136
public function getDescription()
3237
{
33-
return "InputType for pages with template {$this->template->name}.";
38+
return "CreateInputType for pages with template {$this->template->name}.";
3439
}
3540

3641
public function build($config)
@@ -46,23 +51,30 @@ public function build($config)
4651
'type' => new NonNullType(new StringType()),
4752
'description' => 'ProcessWire page name.',
4853
]);
49-
54+
55+
// the list of input fields we do not
56+
// for now
5057
$unsupportedFieldtypes = [
5158
'FieldtypeFile',
5259
'FieldtypeImage',
5360
];
5461

5562
$legalFieldsName = Utils::moduleConfig()->legalFields->implode('|', 'name');
56-
// the template fields
5763
foreach ($this->template->fields->find("name=$legalFieldsName") as $field) {
64+
65+
// get the field's GraphQL input class
5866
$className = $field->type->className();
5967
if (in_array($className, $unsupportedFieldtypes)) continue;
6068
$Class = "\\ProcessWire\\GraphQL\\Field\\Page\\Fieldtype\\" . $className;
69+
70+
// if we do not have a GraphQL class for a field
71+
// it means we do not support it.
6172
if (!class_exists($Class)) continue;
62-
$field = new $Class($field);
63-
$config->addField($field->getName(), [
64-
'type' => $field->getInputfieldType(),
65-
'description' => $field->getDescription(),
73+
74+
$f = new $Class($field);
75+
$config->addField($f->getName(), [
76+
'type' => $f->getInputfieldType(),
77+
'description' => $f->getDescription(),
6678
]);
6779
}
6880
}

0 commit comments

Comments
 (0)