Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
62.50% covered (warning)
62.50%
40 / 64
42.86% covered (danger)
42.86%
3 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
helper
62.50% covered (warning)
62.50%
40 / 64
42.86% covered (danger)
42.86%
3 / 7
35.09
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 get_template_vars
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 get_user_avatar
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 get_group_avatar
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 get_avatar
72.73% covered (warning)
72.73%
24 / 33
0.00% covered (danger)
0.00%
0 / 1
7.99
 get_no_avatar_source
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 get_avatar_html
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3 *
4 * This file is part of the phpBB Forum Software package.
5 *
6 * @copyright (c) phpBB Limited <https://www.phpbb.com>
7 * @license GNU General Public License, version 2 (GPL-2.0)
8 *
9 * For full copyright and license information, please see
10 * the docs/CREDITS.txt file.
11 *
12 */
13
14namespace phpbb\avatar;
15
16use phpbb\avatar\driver\driver_interface;
17use phpbb\config\config;
18use phpbb\event\dispatcher;
19use phpbb\language\language;
20use phpbb\path_helper;
21use phpbb\user;
22
23/**
24 * Avatar helper object.
25 *
26 * Generates avatars and their variables for display.
27 */
28class helper
29{
30    /** @var config */
31    protected $config;
32
33    /** @var dispatcher */
34    protected $dispatcher;
35
36    /** @var language */
37    protected $language;
38
39    /** @var manager */
40    protected $manager;
41
42    /** @var path_helper */
43    protected $path_helper;
44
45    /** @var user */
46    protected $user;
47
48    /**
49     * Constructor.
50     *
51     * @param config        $config            Config object
52     * @param dispatcher    $dispatcher        Event dispatcher object
53     * @param language        $language        Language object
54     * @param manager        $manager        Avatar manager object
55     * @param path_helper    $path_helper    Path helper object
56     * @param user            $user            User object
57     */
58    public function __construct(
59        config $config,
60        dispatcher $dispatcher,
61        language $language,
62        manager $manager,
63        path_helper $path_helper,
64        user $user
65    )
66    {
67        $this->config        = $config;
68        $this->dispatcher    = $dispatcher;
69        $this->language        = $language;
70        $this->manager        = $manager;
71        $this->path_helper    = $path_helper;
72        $this->user            = $user;
73    }
74
75    /**
76     * Get an avatar's template variables.
77     *
78     * @param array        $avatar            The avatar's data
79     * @param string    $prefix            The variables' prefix
80     * @return array                    The avatar's template variables
81     */
82    public function get_template_vars(array $avatar, string $prefix = ''): array
83    {
84        $prefix = $prefix && substr($prefix, -1) !== '_' ? "{$prefix}_" : $prefix;
85
86        return [
87            "{$prefix}AVATAR"            => $avatar,
88
89            "{$prefix}AVATAR_SOURCE"    => $avatar['src'],
90            "{$prefix}AVATAR_TITLE"        => $avatar['title'],
91            "{$prefix}AVATAR_TYPE"        => $avatar['type'],
92
93            "{$prefix}AVATAR_WIDTH"        => $avatar['width'],
94            "{$prefix}AVATAR_HEIGHT"    => $avatar['height'],
95
96            "{$prefix}AVATAR_LAZY"        => $avatar['lazy'],
97            "{$prefix}AVATAR_HTML"        => $avatar['html'],
98        ];
99    }
100
101    /**
102     * Get user avatar data.
103     *
104     * @param array        $row            The user's table row
105     * @param string    $title            Optional language string/key for the title
106     * @param bool        $ignore_config    Ignores the config setting, to still be able to view the avatar in the UCP
107     * @param bool        $lazy            Indicator whether the avatar should be lazy loaded (requires JS) or not
108     * @return array                    The avatar data array
109     */
110    public function get_user_avatar(array $row, string $title = 'USER_AVATAR', bool $ignore_config = false, bool $lazy = false): array
111    {
112        $row = manager::clean_row($row, 'user');
113
114        return $this->get_avatar($row, $title, $ignore_config, $lazy);
115    }
116
117    /**
118     * Get group avatar data.
119     *
120     * @param array        $row            The group's table row
121     * @param string    $title            Optional language string/key for the title
122     * @param bool        $ignore_config    Ignores the config setting, to still be able to view the avatar in the UCP
123     * @param bool        $lazy            Indicator whether the avatar should be lazy loaded (requires JS) or not
124     * @return array                    The avatar data array
125     */
126    public function get_group_avatar(array $row, string $title = 'GROUP_AVATAR', bool $ignore_config = false, bool $lazy = false): array
127    {
128        $row = manager::clean_row($row, 'group');
129
130        return $this->get_avatar($row, $title, $ignore_config, $lazy);
131    }
132
133    /**
134     * Get avatar data.
135     *
136     * @param array        $row            The cleaned table row
137     * @param string    $title            Optional language string/key for the title
138     * @param bool        $ignore_config    Ignores the config setting, to still be able to view the avatar in the UCP
139     * @param bool        $lazy            Indicator whether the avatar should be lazy loaded (requires JS) or not
140     * @return array                    The avatar data array
141     */
142    public function get_avatar(array $row, string $title, bool $ignore_config = false, bool $lazy = false): array
143    {
144        if (!$this->config['allow_avatar'] && !$ignore_config)
145        {
146            return [
147                'html'        => '',
148                'lazy'        => false,
149                'src'        => '',
150                'title'        => '',
151                'type'        => '',
152                'width'        => 0,
153                'height'    => 0,
154            ];
155        }
156
157        $data = [
158            'src'        => $row['avatar'],
159            'width'        => $row['avatar_width'],
160            'height'    => $row['avatar_height'],
161            'title'        => $this->language->lang($title),
162            'lazy'        => $lazy,
163            'type'        => '',
164            'html'        => '',
165        ];
166
167        /** @var driver_interface $driver */
168        $driver = $this->manager->get_driver($row['avatar_type'], !$ignore_config);
169
170        if ($driver !== null)
171        {
172            $data = array_merge($data, $driver->get_data($row), [
173                'type'    => $driver->get_name(),
174                'html'    => $driver->get_custom_html($this->user, $row, $title),
175            ]);
176
177            /**
178             * The type is used in the template to determine what driver is used,
179             * and potentially to add an additional class to the avatar <img> element.
180             *
181             * While it's possible to str_replace('avatar.driver.', '', $data['type'])
182             * for all the core drivers, this will be awkward for extensions' avatar drivers.
183             * As they will most likely want to adjust the type in the event below,
184             * and then have to search for a different definition than they used in their services.yml
185             *
186             * For example, 'ext.vendor.avatar.driver.custom_driver'
187             * They will then have to look for: 'ext.vendor.custom_driver'
188             *
189             * So only remove 'avatar.driver.' if it is at the beginning of the driver's name.
190             */
191            if (strpos($data['type'], 'avatar.driver.') === 0)
192            {
193                $data['type'] = substr($data['type'], strlen('avatar.driver.'));
194            }
195        }
196        else
197        {
198            $data['src'] = '';
199        }
200
201        if (empty($data['html']) && !empty($data['src']))
202        {
203            $data['html'] = $this->get_avatar_html($data);
204        }
205
206        /**
207         * Event to modify avatar data array
208         *
209         * @event core.avatar_helper_get_avatar
210         * @var    array    row                The cleaned table row
211         * @var    string    title            The language string/key for the title
212         * @var    bool    ignore_config    Ignores the config setting, to still be able to view the avatar in the UCP
213         * @var bool    lazy            Indicator whether the avatar should be lazy loaded (requires JS) or not
214         * @var    array    data            The avatar data array
215         * @since 4.0.0
216         */
217        $vars = ['row', 'title', 'ignore_config', 'lazy', 'data'];
218        extract($this->dispatcher->trigger_event('core.avatar_helper_get_avatar', compact($vars)));
219
220        return $data;
221    }
222
223    /**
224     * Get the "no avatar" source string.
225     *
226     * @return string                    The "no avatar" source string
227     */
228    public function get_no_avatar_source(): string
229    {
230        /**
231         * We need to correct the phpBB root path in case this is called from a controller,
232         * because the web path will be incorrect otherwise.
233         */
234        $web_path    = $this->path_helper->get_web_root_path();
235        $style_path    = rawurlencode($this->user->style['style_path']);
236
237        return "{$web_path}styles/{$style_path}/theme/images/no_avatar.gif";
238    }
239
240    /**
241     * Get an avatar's HTML <img> element.
242     *
243     * Created for Backwards Compatibility (BC).
244     * Styles should generate their own HTML element instead.
245     *
246     * @deprecated 4.1.0                After admin style is reworked aswell
247     *
248     * @param array        $data            The avatar data array
249     * @return string                    The avatar's HTML <img> element
250     */
251    private function get_avatar_html(array $data): string
252    {
253        if ($data['lazy'])
254        {
255            $data['src'] = $this->get_no_avatar_source() . '" data-src="' . $data['src'];
256        }
257
258        $src = ' src="' . $data['src'] . '"';
259        $alt = ' alt="' . $data['title'] . '"';
260
261        $width = $data['width'] ? ' width="' . $data['width'] . '"' : '';
262        $height = $data['height'] ? ' height="' . $data['height'] . '"' : '';
263
264        return '<img class="avatar"' . $src . $width . $height . $alt . ' />';
265    }
266}