Passed
Pull Request — master (#152)
by
unknown
03:51
created

Standard::getBody()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 8
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 34
rs 10
1
<?php
2
3
namespace Aimeos\Client\Html\Account\Profile\Account;
4
5
use Illuminate\Support\Facades\Validator;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Facades\Validator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Laravel\Fortify\Rules\Password;
0 ignored issues
show
Bug introduced by
The type Laravel\Fortify\Rules\Password was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Laravel\Jetstream\Jetstream;
0 ignored issues
show
Bug introduced by
The type Laravel\Jetstream\Jetstream was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
9
/**
10
 * Default implementation of acount profile account HTML client.
11
 *
12
 * @package Client
13
 * @subpackage Html
14
 */
15
class Standard
16
    extends \Aimeos\Client\Html\Common\Client\Summary\Base
17
    implements \Aimeos\Client\Html\Common\Client\Factory\Iface
18
{
19
20
    /** client/html/account/profile/account/subparts
21
     * List of HTML sub-clients rendered within the account profile account section
22
     *
23
     * The output of the frontend is composed of the code generated by the HTML
24
     * clients. Each HTML client can consist of serveral (or none) sub-clients
25
     * that are responsible for rendering certain sub-parts of the output. The
26
     * sub-clients can contain HTML clients themselves and therefore a
27
     * hierarchical tree of HTML clients is composed. Each HTML client creates
28
     * the output that is placed inside the container of its parent.
29
     *
30
     * At first, always the HTML code generated by the parent is printed, then
31
     * the HTML code of its sub-clients. The account of the HTML sub-clients
32
     * determines the account of the output of these sub-clients inside the parent
33
     * container. If the configured list of clients is
34
     *
35
     *  array( "subclient1", "subclient2" )
36
     *
37
     * you can easily change the account of the output by readdressing the subparts:
38
     *
39
     *  client/html/<clients>/subparts = array( "subclient1", "subclient2" )
40
     *
41
     * You can also remove one or more parts if they shouldn't be rendered:
42
     *
43
     *  client/html/<clients>/subparts = array( "subclient1" )
44
     *
45
     * As the clients only generates structural HTML, the layout defined via CSS
46
     * should support adding, removing or readdressing content by a fluid like
47
     * design.
48
     *
49
     * @param array List of sub-client names
50
     * @since 2019.07
51
     * @category Developer
52
     */
53
    private $subPartPath = 'client/html/account/profile/account/subparts';
54
    private $subPartNames = [];
55
56
    /**
57
     * Returns the list of sub-client names configured for the client.
58
     *
59
     * @return array List of HTML client names
60
     */
61
    protected function getSubClientNames() : array
62
    {
63
        return $this->getContext()->getConfig()->get( $this->subPartPath, $this->subPartNames );
64
    }
65
66
    /**
67
     * Returns the sub-client given by its name.
68
     *
69
     * @param string $type Name of the client type
70
     * @param string|null $name Name of the sub-client (Default if null)
71
     * @return \Aimeos\Client\Html\Iface Sub-client object
72
     * @throws \Aimeos\Client\Html\Exception
73
     */
74
    public function getSubClient( string $type, string $name = null ) : \Aimeos\Client\Html\Iface
75
    {
76
        /** client/html/account/profile/account/decorators/excludes
77
         * Excludes decorators added by the "common" option from the account profile account html client
78
         *
79
         * Decorators extend the functionality of a class by adding new aspects
80
         * (e.g. log what is currently done), executing the methods of the underlying
81
         * class only in certain conditions (e.g. only for logged in users) or
82
         * modify what is returned to the caller.
83
         *
84
         * This option allows you to remove a decorator added via
85
         * "client/html/common/decorators/default" before they are wrapped
86
         * around the html client.
87
         *
88
         *  client/html/account/profile/account/decorators/excludes = array( 'decorator1' )
89
         *
90
         * This would remove the decorator named "decorator1" from the list of
91
         * common decorators ("\Aimeos\Client\Html\Common\Decorator\*") added via
92
         * "client/html/common/decorators/default" to the html client.
93
         *
94
         * @param array List of decorator names
95
         * @since 2019.07
96
         * @category Developer
97
         * @see client/html/common/decorators/default
98
         * @see client/html/account/profile/account/decorators/global
99
         * @see client/html/account/profile/account/decorators/local
100
         */
101
102
        /** client/html/account/profile/account/decorators/global
103
         * Adds a list of globally available decorators only to the account profile account html client
104
         *
105
         * Decorators extend the functionality of a class by adding new aspects
106
         * (e.g. log what is currently done), executing the methods of the underlying
107
         * class only in certain conditions (e.g. only for logged in users) or
108
         * modify what is returned to the caller.
109
         *
110
         * This option allows you to wrap global decorators
111
         * ("\Aimeos\Client\Html\Common\Decorator\*") around the html client.
112
         *
113
         *  client/html/account/profile/account/decorators/global = array( 'decorator1' )
114
         *
115
         * This would add the decorator named "decorator1" defined by
116
         * "\Aimeos\Client\Html\Common\Decorator\Decorator1" only to the html client.
117
         *
118
         * @param array List of decorator names
119
         * @since 2019.07
120
         * @category Developer
121
         * @see client/html/common/decorators/default
122
         * @see client/html/account/profile/account/decorators/excludes
123
         * @see client/html/account/profile/account/decorators/local
124
         */
125
126
        /** client/html/account/profile/account/decorators/local
127
         * Adds a list of local decorators only to the account profile account html client
128
         *
129
         * Decorators extend the functionality of a class by adding new aspects
130
         * (e.g. log what is currently done), executing the methods of the underlying
131
         * class only in certain conditions (e.g. only for logged in users) or
132
         * modify what is returned to the caller.
133
         *
134
         * This option allows you to wrap local decorators
135
         * ("\Aimeos\Client\Html\Account\Decorator\*") around the html client.
136
         *
137
         *  client/html/account/profile/account/decorators/local = array( 'decorator2' )
138
         *
139
         * This would add the decorator named "decorator2" defined by
140
         * "\Aimeos\Client\Html\Account\Decorator\Decorator2" only to the html client.
141
         *
142
         * @param array List of decorator names
143
         * @since 2019.07
144
         * @category Developer
145
         * @see client/html/common/decorators/default
146
         * @see client/html/account/profile/account/decorators/excludes
147
         * @see client/html/account/profile/account/decorators/global
148
         */
149
150
        return $this->createSubClient( 'account/profile/account/' . $type, $name );
151
    }
152
153
    /**
154
     * Returns the HTML code for insertion into the body.
155
     *
156
     * @param string $uid Unique identifier for the output if the content is placed more than once on the same page
157
     * @return string HTML code
158
     * @throws \Aimeos\MW\View\Exception|\Aimeos\Client\Html\Exception
159
     */
160
    public function getBody(string $uid = ''): string
161
    {
162
        $view = $this->getView();
163
164
        $html = '';
165
        foreach( $this->getSubClients() as $subclient ) {
166
            $html .= $subclient->setView( $view )->getBody( $uid );
167
        }
168
        $view->accountBody = $html;
169
170
        /** client/html/account/profile/account/template-body
171
         * Relative path to the HTML body template of the account profile account client.
172
         *
173
         * The template file contains the HTML code and processing instructions
174
         * to generate the result shown in the body of the frontend. The
175
         * configuration string is the path to the template file relative
176
         * to the templates directory (usually in client/html/templates).
177
         *
178
         * You can overwrite the template file configuration in extensions and
179
         * provide alternative templates. These alternative templates should be
180
         * named like the default one but with the string "standard" replaced by
181
         * an unique name. You may use the name of your project for this. If
182
         * you've implemented an alternative client class as well, "standard"
183
         * should be replaced by the name of the new class.
184
         *
185
         * @param string Relative path to the template creating code for the HTML page body
186
         * @since 2019.07
187
         * @category Developer
188
         * @see client/html/account/profile/account/template-header
189
         */
190
        $tplconf = 'client/html/account/profile/account/template-body';
191
        $default = 'account/profile/account-body-standard';
192
193
        return $view->render( $view->config( $tplconf, $default ) );
194
    }
195
196
    /**
197
     * Processes the input, e.g. store given values.
198
     *
199
     * A view must be available and this method doesn't generate any output
200
     * besides setting view variables if necessary.
201
     * @throws \Aimeos\Client\Html\Exception|\Aimeos\Controller\Frontend\Exception
202
     */
203
    public function process()
204
    {
205
        $view = $this->getView();
206
207
        if( !$view->param( 'account/save' , false) ) {
208
            parent::process();
209
            return;
210
        }
211
212
        /** @var \Aimeos\Controller\Frontend\Customer\Standard $cntl */
213
        $cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' );
214
        $oldPassword = $cntl->get()->getPassword();
215
        $values = $view->param('account', []);
216
217
        $isNew = $values['customer.newpassword'] !== $values['customer.oldpassword'];
218
        $confirmed = $values['customer.newpassword'] === $values['customer.confirmnewpassword'];
219
220
        $errors = [];
221
222
        $isValid = true;
223
        try {
224
            Validator::make([
225
                'password' => $values['customer.newpassword'],
226
                'password_confirmation' => $values['customer.confirmnewpassword']
227
            ], [
228
                'password' => ['required', 'string', new Password, 'confirmed']
229
            ])->validate();
230
        } catch (\Exception $ex) {
231
            $isValid = false;
232
            $errors['passwordRules'] = "The password does not meet the password requirements!";
233
        }
234
235
        if ($isValid) {
236
            /** is the password realy new? */
237
            if (!$isNew) {
238
                $errors['isNew'] = "The given password is not new!";
239
            }
240
241
            /** does the confirm password is the same? */
242
            if (!$confirmed) {
243
                $errors["confirm"] = "New passwords doesnt match!";
244
            }
245
246
            $cntl = $cntl->add($values);
247
248
        }
249
        /** if the pasword is new and confirmed, but is not changed, the given old password must be wrong */
250
        if ($isValid && $isNew && $confirmed && $oldPassword === $cntl->get()->getPassword() ) {
251
                $errors['oldPassword'] = "Wrong password!";
252
        }
253
254
        $view->passwordChanged = count(array_keys($errors)) === 0;
255
256
        if (count(array_keys($errors)) > 0) {
257
            $view->passwordErrors = $errors;
258
        } else {
259
            $cntl->store();
260
        }
261
262
        parent::process();
263
    }
264
}
265