Completed
Push — master ( a394db...779b37 )
by Paul
09:04
created

Portlet_forthcoming::getPhoto()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 14
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 29
rs 8.439
1
<?php
2
//-------------------------------------------------------------------------
3
// OVIDENTIA http://www.ovidentia.org
4
// Ovidentia is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2, or (at your option)
7
// any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
// See the GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17
// USA.
18
//-------------------------------------------------------------------------
19
/**
20
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
21
 * @copyright Copyright (c) 2012 by CANTICO ({@link http://www.cantico.fr})
22
 */
23
require_once dirname(__FILE__).'/functions.php';
24
require_once dirname(__FILE__).'/utilit/agent.class.php';
25
require_once dirname(__FILE__).'/utilit/entry.class.php';
26
require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
27
bab_Functionality::includeoriginal('PortletBackend');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class bab_functionality as the method includeoriginal() does only exist in the following sub-classes of bab_functionality: Func_Archive, Func_Archive_Zip, Func_Archive_Zip_ZipArchive, Func_Archive_Zip_Zlib, Func_CalendarBackend, Func_CalendarBackend_Ovi, Func_ContextActions, Func_ContextActions_Article, Func_ContextActions_ArticleTopic, Func_Home, Func_Home_Ovidentia, Func_Icons, Func_Icons_Default, Func_Ovml, Func_Ovml_Container, Func_Ovml_Container_Addon, Func_Ovml_Container_Article, Func_Ovml_Container_ArticleCategories, Func_Ovml_Container_ArticleCategory, Func_Ovml_Container_ArticleCategoryNext, Func_Ovml_Container_ArticleCategoryPrevious, Func_Ovml_Container_ArticleFiles, Func_Ovml_Container_ArticleNext, Func_Ovml_Container_ArticlePrevious, Func_Ovml_Container_ArticleTopic, Func_Ovml_Container_ArticleTopicNext, Func_Ovml_Container_ArticleTopicPrevious, Func_Ovml_Container_ArticleTopics, Func_Ovml_Container_Articles, Func_Ovml_Container_ArticlesHomePages, Func_Ovml_Container_CalendarCategories, Func_Ovml_Container_CalendarEventDomains, Func_Ovml_Container_CalendarEvents, Func_Ovml_Container_CalendarGroupEvents, Func_Ovml_Container_CalendarResourceEvents, Func_Ovml_Container_CalendarUserEvents, Func_Ovml_Container_Calendars, Func_Ovml_Container_DbDirectories, Func_Ovml_Container_DbDirectory, Func_Ovml_Container_DbDirectoryAcl, Func_Ovml_Container_DbDirectoryEntry, Func_Ovml_Container_DbDirectoryEntryFields, Func_Ovml_Container_DbDirectoryFields, Func_Ovml_Container_DbDirectoryMemberFields, Func_Ovml_Container_DbDirectoryMembers, Func_Ovml_Container_Delegation, Func_Ovml_Container_DelegationAdministrators, Func_Ovml_Container_DelegationItems, Func_Ovml_Container_DelegationManaged, Func_Ovml_Container_Delegations, Func_Ovml_Container_DelegationsCategories, Func_Ovml_Container_DelegationsCategory, Func_Ovml_Container_DelegationsManaged, Func_Ovml_Container_Faq, Func_Ovml_Container_FaqNext, Func_Ovml_Container_FaqPrevious, Func_Ovml_Container_FaqQuestion, Func_Ovml_Container_FaqQuestionNext, Func_Ovml_Container_FaqQuestionPrevious, Func_Ovml_Container_FaqQuestions, Func_Ovml_Container_FaqSubCategories, Func_Ovml_Container_FaqSubCategory, Func_Ovml_Container_Faqs, Func_Ovml_Container_File, Func_Ovml_Container_FileFields, Func_Ovml_Container_FileNext, Func_Ovml_Container_FilePrevious, Func_Ovml_Container_Files, Func_Ovml_Container_Folder, Func_Ovml_Container_FolderNext, Func_Ovml_Container_FolderPrevious, Func_Ovml_Container_Folders, Func_Ovml_Container_Forum, Func_Ovml_Container_ForumNext, Func_Ovml_Container_ForumPrevious, Func_Ovml_Container_Forums, Func_Ovml_Container_IfEqual, Func_Ovml_Container_IfGreaterThan, Func_Ovml_Container_IfGreaterThanOrEqual, Func_Ovml_Container_IfIsSet, Func_Ovml_Container_IfLessThan, Func_Ovml_Container_IfLessThanOrEqual, Func_Ovml_Container_IfNotEqual, Func_Ovml_Container_IfNotIsSet, Func_Ovml_Container_IfUserMemberOfGroups, Func_Ovml_Container_Multipages, Func_Ovml_Container_ObjectsInfo, Func_Ovml_Container_OrgPathToEntity, Func_Ovml_Container_OrgUserEntities, Func_Ovml_Container_OvmlArray, Func_Ovml_Container_OvmlArrayFields, Func_Ovml_Container_OvmlSoap, Func_Ovml_Container_ParentsArticleCategory, Func_Ovml_Container_Post, Func_Ovml_Container_PostFiles, Func_Ovml_Container_RecentArticles, Func_Ovml_Container_RecentComments, Func_Ovml_Container_RecentFaqQuestions, Func_Ovml_Container_RecentFiles, Func_Ovml_Container_RecentPosts, Func_Ovml_Container_RecentThreads, Func_Ovml_Container_SitemapCustomNode, Func_Ovml_Container_SitemapEntries, Func_Ovml_Container_SitemapEntry, Func_Ovml_Container_SitemapPath, Func_Ovml_Container_Soap, Func_Ovml_Container_SubFolders, Func_Ovml_Container_Tags, Func_Ovml_Container_Thread, Func_Ovml_Container_TmProjects, Func_Ovml_Container_TmSpaces, Func_Ovml_Container_TmTaskFields, Func_Ovml_Container_TmTasks, Func_Ovml_Container_WaitingArticles, Func_Ovml_Container_WaitingComments, Func_Ovml_Container_WaitingFiles, Func_Ovml_Container_WaitingPosts, Func_Ovml_Function, Func_Ovml_Function_AOAddition, Func_Ovml_Function_AODivision, Func_Ovml_Function_AOModulus, Func_Ovml_Function_AOMultiplication, Func_Ovml_Function_AOSubtraction, Func_Ovml_Function_AddStyleSheet, Func_Ovml_Function_Addon, Func_Ovml_Function_Ajax, Func_Ovml_Function_ArticleTree, Func_Ovml_Function_CurrentNode, Func_Ovml_Function_FileTree, Func_Ovml_Function_Get, Func_Ovml_Function_GetCookie, Func_Ovml_Function_GetCsrfProtectToken, Func_Ovml_Function_GetCurrentAdmGroup, Func_Ovml_Function_GetLanguage, Func_Ovml_Function_GetPageTitle, Func_Ovml_Function_GetPath, Func_Ovml_Function_GetSelectedSkinPath, Func_Ovml_Function_GetSessionVar, Func_Ovml_Function_GetVar, Func_Ovml_Function_Header, Func_Ovml_Function_IfNotIsSet, Func_Ovml_Function_Include, Func_Ovml_Function_NextArticle, Func_Ovml_Function_Post, Func_Ovml_Function_PreviousArticle, Func_Ovml_Function_PreviousOrNextArticle, Func_Ovml_Function_PutArray, Func_Ovml_Function_PutSoapArray, Func_Ovml_Function_PutVar, Func_Ovml_Function_Recurse, Func_Ovml_Function_Request, Func_Ovml_Function_SetCookie, Func_Ovml_Function_SetSessionVar, Func_Ovml_Function_SitemapCustomNodeId, Func_Ovml_Function_SitemapMenu, Func_Ovml_Function_SitemapPosition, Func_Ovml_Function_SitemapUrl, Func_Ovml_Function_Translate, Func_Ovml_Function_UrlContent, Func_Ovml_Function_WebStat, Func_PortalAuthentication, Func_PortalAuthentication_AuthOvidentia, Func_PwdComplexity, Func_PwdComplexity_DefaultPortal, Func_SearchUi, Func_SitemapDynamicNode, Func_SitemapDynamicNode_Topic, Func_UserEditor, Func_WorkingHours, Func_WorkingHours_Ovidentia, Ovml_Container_Sitemap, bab_ArithmeticOperator, bab_Ovml_Container_Operator, bab_rgp. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
28
bab_Functionality::includeoriginal('Icons');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class bab_functionality as the method includeoriginal() does only exist in the following sub-classes of bab_functionality: Func_Archive, Func_Archive_Zip, Func_Archive_Zip_ZipArchive, Func_Archive_Zip_Zlib, Func_CalendarBackend, Func_CalendarBackend_Ovi, Func_ContextActions, Func_ContextActions_Article, Func_ContextActions_ArticleTopic, Func_Home, Func_Home_Ovidentia, Func_Icons, Func_Icons_Default, Func_Ovml, Func_Ovml_Container, Func_Ovml_Container_Addon, Func_Ovml_Container_Article, Func_Ovml_Container_ArticleCategories, Func_Ovml_Container_ArticleCategory, Func_Ovml_Container_ArticleCategoryNext, Func_Ovml_Container_ArticleCategoryPrevious, Func_Ovml_Container_ArticleFiles, Func_Ovml_Container_ArticleNext, Func_Ovml_Container_ArticlePrevious, Func_Ovml_Container_ArticleTopic, Func_Ovml_Container_ArticleTopicNext, Func_Ovml_Container_ArticleTopicPrevious, Func_Ovml_Container_ArticleTopics, Func_Ovml_Container_Articles, Func_Ovml_Container_ArticlesHomePages, Func_Ovml_Container_CalendarCategories, Func_Ovml_Container_CalendarEventDomains, Func_Ovml_Container_CalendarEvents, Func_Ovml_Container_CalendarGroupEvents, Func_Ovml_Container_CalendarResourceEvents, Func_Ovml_Container_CalendarUserEvents, Func_Ovml_Container_Calendars, Func_Ovml_Container_DbDirectories, Func_Ovml_Container_DbDirectory, Func_Ovml_Container_DbDirectoryAcl, Func_Ovml_Container_DbDirectoryEntry, Func_Ovml_Container_DbDirectoryEntryFields, Func_Ovml_Container_DbDirectoryFields, Func_Ovml_Container_DbDirectoryMemberFields, Func_Ovml_Container_DbDirectoryMembers, Func_Ovml_Container_Delegation, Func_Ovml_Container_DelegationAdministrators, Func_Ovml_Container_DelegationItems, Func_Ovml_Container_DelegationManaged, Func_Ovml_Container_Delegations, Func_Ovml_Container_DelegationsCategories, Func_Ovml_Container_DelegationsCategory, Func_Ovml_Container_DelegationsManaged, Func_Ovml_Container_Faq, Func_Ovml_Container_FaqNext, Func_Ovml_Container_FaqPrevious, Func_Ovml_Container_FaqQuestion, Func_Ovml_Container_FaqQuestionNext, Func_Ovml_Container_FaqQuestionPrevious, Func_Ovml_Container_FaqQuestions, Func_Ovml_Container_FaqSubCategories, Func_Ovml_Container_FaqSubCategory, Func_Ovml_Container_Faqs, Func_Ovml_Container_File, Func_Ovml_Container_FileFields, Func_Ovml_Container_FileNext, Func_Ovml_Container_FilePrevious, Func_Ovml_Container_Files, Func_Ovml_Container_Folder, Func_Ovml_Container_FolderNext, Func_Ovml_Container_FolderPrevious, Func_Ovml_Container_Folders, Func_Ovml_Container_Forum, Func_Ovml_Container_ForumNext, Func_Ovml_Container_ForumPrevious, Func_Ovml_Container_Forums, Func_Ovml_Container_IfEqual, Func_Ovml_Container_IfGreaterThan, Func_Ovml_Container_IfGreaterThanOrEqual, Func_Ovml_Container_IfIsSet, Func_Ovml_Container_IfLessThan, Func_Ovml_Container_IfLessThanOrEqual, Func_Ovml_Container_IfNotEqual, Func_Ovml_Container_IfNotIsSet, Func_Ovml_Container_IfUserMemberOfGroups, Func_Ovml_Container_Multipages, Func_Ovml_Container_ObjectsInfo, Func_Ovml_Container_OrgPathToEntity, Func_Ovml_Container_OrgUserEntities, Func_Ovml_Container_OvmlArray, Func_Ovml_Container_OvmlArrayFields, Func_Ovml_Container_OvmlSoap, Func_Ovml_Container_ParentsArticleCategory, Func_Ovml_Container_Post, Func_Ovml_Container_PostFiles, Func_Ovml_Container_RecentArticles, Func_Ovml_Container_RecentComments, Func_Ovml_Container_RecentFaqQuestions, Func_Ovml_Container_RecentFiles, Func_Ovml_Container_RecentPosts, Func_Ovml_Container_RecentThreads, Func_Ovml_Container_SitemapCustomNode, Func_Ovml_Container_SitemapEntries, Func_Ovml_Container_SitemapEntry, Func_Ovml_Container_SitemapPath, Func_Ovml_Container_Soap, Func_Ovml_Container_SubFolders, Func_Ovml_Container_Tags, Func_Ovml_Container_Thread, Func_Ovml_Container_TmProjects, Func_Ovml_Container_TmSpaces, Func_Ovml_Container_TmTaskFields, Func_Ovml_Container_TmTasks, Func_Ovml_Container_WaitingArticles, Func_Ovml_Container_WaitingComments, Func_Ovml_Container_WaitingFiles, Func_Ovml_Container_WaitingPosts, Func_Ovml_Function, Func_Ovml_Function_AOAddition, Func_Ovml_Function_AODivision, Func_Ovml_Function_AOModulus, Func_Ovml_Function_AOMultiplication, Func_Ovml_Function_AOSubtraction, Func_Ovml_Function_AddStyleSheet, Func_Ovml_Function_Addon, Func_Ovml_Function_Ajax, Func_Ovml_Function_ArticleTree, Func_Ovml_Function_CurrentNode, Func_Ovml_Function_FileTree, Func_Ovml_Function_Get, Func_Ovml_Function_GetCookie, Func_Ovml_Function_GetCsrfProtectToken, Func_Ovml_Function_GetCurrentAdmGroup, Func_Ovml_Function_GetLanguage, Func_Ovml_Function_GetPageTitle, Func_Ovml_Function_GetPath, Func_Ovml_Function_GetSelectedSkinPath, Func_Ovml_Function_GetSessionVar, Func_Ovml_Function_GetVar, Func_Ovml_Function_Header, Func_Ovml_Function_IfNotIsSet, Func_Ovml_Function_Include, Func_Ovml_Function_NextArticle, Func_Ovml_Function_Post, Func_Ovml_Function_PreviousArticle, Func_Ovml_Function_PreviousOrNextArticle, Func_Ovml_Function_PutArray, Func_Ovml_Function_PutSoapArray, Func_Ovml_Function_PutVar, Func_Ovml_Function_Recurse, Func_Ovml_Function_Request, Func_Ovml_Function_SetCookie, Func_Ovml_Function_SetSessionVar, Func_Ovml_Function_SitemapCustomNodeId, Func_Ovml_Function_SitemapMenu, Func_Ovml_Function_SitemapPosition, Func_Ovml_Function_SitemapUrl, Func_Ovml_Function_Translate, Func_Ovml_Function_UrlContent, Func_Ovml_Function_WebStat, Func_PortalAuthentication, Func_PortalAuthentication_AuthOvidentia, Func_PwdComplexity, Func_PwdComplexity_DefaultPortal, Func_SearchUi, Func_SitemapDynamicNode, Func_SitemapDynamicNode_Topic, Func_UserEditor, Func_WorkingHours, Func_WorkingHours_Ovidentia, Ovml_Container_Sitemap, bab_ArithmeticOperator, bab_Ovml_Container_Operator, bab_rgp. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
29
30
/**
31
 * 
32
 */
33
class Func_PortletBackend_Absences extends Func_PortletBackend
34
{
35
	public function getDescription()
36
	{
37
		return absences_translate("Absences");
38
	}
39
	
40
	public function select($category = null)
41
	{
42
		if (isset($category) && $category !== 'absences')
43
		{
44
			return array();
45
		}
46
		
47
		$portlets = array(
48
		    'absences_forthcoming' => $this->Portlet_forthcoming()
49
		);
50
		
51
		if (bab_isAccessValid('absences_public_planning_groups', 1))
52
		{
53
		    $portlets['absences_publicPlanning'] = $this->Portlet_publicPlanning();
54
		}
55
		
56
		return $portlets;
57
	}
58
	
59
	
60
	
61
	/**
62
	 * Get portlet definition instance
63
	 * @param	string	$portletId			portlet definition ID
64
	 *
65
	 * @return portlet_PortletDefinitionInterface
66
	 */
67
	public function getPortletDefinition($portletId)
68
	{
69
		$name = str_replace('absences_', '', $portletId);
70
		
71
		switch($name)
72
		{
73
			case 'forthcoming':
74
				return $this->Portlet_forthcoming();
75
				
76
			case 'publicPlanning':
77
				return $this->Portlet_publicPlanning();
78
		}
79
		
80
		return null;
81
	}
82
83
84
	public function Portlet_forthcoming()
85
	{
86
		return new PortletDefinition_forthcoming();
87
	}
88
	
89
	public function Portlet_publicPlanning()
90
	{
91
		return new absences_PublicPlanningDefinition();
92
	}
93
	
94
	
95
	/**
96
	 * get a list of categories supported by the backend
97
	 * @return Array 
98
	 */
99
	public function getCategories()
100
	{
101
102
		return array(
103
			'absences' => absences_translate('Absences')
104
		);
105
	}
106
}
107
108
109
/////////////////////////////////////////
110
111
112
113
114
class absences_PublicPlanningDefinition implements portlet_PortletDefinitionInterface
115
{
116
117
	private $id;
118
	private $name;
119
	private $description;
120
121 View Code Duplication
	public function __construct()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
	{
123
		$this->id = 'absences_publicPlanning';
124
		$this->name = absences_translate('Absences planning');
125
		$this->description = absences_translate('Public planning for absences');
126
		$this->addon = bab_getAddonInfosInstance('absences');
0 ignored issues
show
Bug introduced by
The property addon does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
127
	}
128
129
	public function getId()
130
	{
131
		return $this->id;
132
	}
133
134
135
	public function getName()
136
	{
137
		return $this->name;
138
	}
139
140
141
	public function getDescription()
142
	{
143
		return $this->description;
144
	}
145
146
147
	public function getPortlet()
148
	{
149
		return new Portlet_publicPlanning;
150
	}
151
152
	/**
153
	 * Returns the widget rich icon URL.
154
	 *
155
	 *
156
	 * @return string
157
	 */
158
	public function getRichIcon()
159
	{
160
		return $this->addon->getImagesPath() . 'icon.png';
161
	}
162
163
164
	/**
165
	 * Returns the widget icon URL.
166
	 *
167
	 *
168
	 * @return string
169
	 */
170
	public function getIcon()
171
	{
172
		return $this->addon->getImagesPath() . 'icon.png';
173
	}
174
175
	/**
176
	 * Get thumbnail URL
177
	 * max 120x60
178
	 */
179
	public function getThumbnail()
180
	{
181
		return null;
182
	}
183
184
	public function getConfigurationActions()
185
	{
186
		return array();
187
	}
188
189
	public function getPreferenceFields()
190
	{
191
		return array(
192
			array(
193
					'label' => absences_translate('Start date shifted in months'),
194
					'type' => 'int',
195
					'name' => 'shiftmonth',
196
					'default' => 0
197
			),
198
				
199
			array(
200
					'label' => absences_translate('Display the legend'),
201
					'type' => 'boolean',
202
					'name' => 'legend',
203
					'default' => true
204
			)
205
		);
206
	}
207
}
208
209
210
211
212
213
214
215
class Portlet_publicPlanning extends Widget_Item implements portlet_PortletInterface
216
{
217
218
	private $options = array();
219
220
221
222
	/**
223
	 * @param Widget_Canvas	$canvas
224
	 */
225
	public function display(Widget_Canvas $canvas)
226
	{
227
		global $babDB;
228
		$W = bab_Widgets();
229
		require_once dirname(__FILE__).'/utilit/planningincl.php';
230
		
231
		$nbmonth = (int) bab_rp('nbmonth', 1);
232
		
233
		if (!bab_isAccessValid('absences_public_planning_groups', 1))
234
		{
235
		    return '';
236
		}
237
		
238
		// preload the 30 first users
239
		$initusers = absences_getSearchLimit($nbmonth);
240
		
241
		$users = array();
242
		$res = absences_publicCalendarUsers(bab_rp('keyword', null), bab_rp('departments', null), bab_rp('searchtype'), bab_rp('dateb'), bab_rp('datee'), bab_rp('date'));
243
		
244
		$i = 0;
245 View Code Duplication
		while ($arr = $babDB->db_fetch_assoc($res))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
246
		{
247
			$users[] = $arr['id'];
248
			if ($i > $initusers)
249
			{
250
				break;
251
			}
252
		
253
			$i++;
254
		}
255
		
256
		if (empty($users) && '' === bab_rp('keyword') && '' === bab_rp('dateb') && '' === bab_rp('datee') && '' === bab_rp('date'))
257
		{
258
			return $canvas->span(null, array(), array(absences_translate('No employees found, the public planning is empty')));
259
		}
260
		
261
		$shiftmonth = isset($this->options['shiftmonth']) ? $this->options['shiftmonth'] : 0;
262
		$legend = isset($this->options['legend']) ? (bool) $this->options['legend'] : true;
263
		
264
		
265
		$search = bab_rp('search'); // button clicked
266
		$month = (int) bab_rp('month');
267
		$year = (int) bab_rp('year');
268
		$searchDate = bab_rp('dateb');
269
		if (empty($searchDate)) {
270
		    $searchDate = bab_rp('date');
271
		}
272
		
273
		if (!empty($searchDate) && $search) {
274
		    // try to replace month/year by elements from searchDate
275
		    list($searchYear, $searchMmonth) = explode('-', $W->DatePicker()->getISODate($searchDate));
276
		    $searchYear = (int) $searchYear;
277
		    $searchMmonth = (int) $searchMmonth;
278
		    
279
		    if ($searchYear !== $year) {
280
		        $_REQUEST['year'] = $searchYear;
281
		    }
282
		    
283
		    if ($searchMmonth !== $month) {
284
		        $_REQUEST['month'] = $searchMmonth;
285
		    }
286
		}
287
		
288
		
289
		$cls = new absences_viewVacationCalendarCls($users, false, true, $nbmonth, true, $shiftmonth, $legend);
290
		$cls->publiccalendar($babDB->db_num_rows($res));
291
292
		$widget = $W->Html($cls->getHtml());
293
		
294
295
		return $widget->display($canvas)
296
			.$canvas->loadScript($widget->getId(), absences_addon()->getTemplatePath().'calendar.jquery.js')
297
			.$canvas->loadStyleSheet(absences_addon()->getStylePath().'vacation.css');
298
	}
299
300
301
	public function getName()
302
	{
303
		return get_class($this);
304
	}
305
306
	public function getPortletDefinition()
307
	{
308
		return new absences_PublicPlanningDefinition();
309
	}
310
311
	/**
312
	 * receive current user configuration from portlet API
313
	 */
314
	public function setPreferences(array $configuration)
315
	{
316
		$this->options = $configuration;
317
	}
318
319
	public function setPreference($name, $value)
320
	{
321
		$this->options[$name] = $value;
322
	}
323
324
	public function setPortletId($id)
325
	{
326
327
	}
328
}
329
330
331
332
333
334
335
336
337
class PortletDefinition_forthcoming implements portlet_PortletDefinitionInterface
338
{
339
	
340
	private $id;
341
	private $name;
342
	private $description;
343
	
344 View Code Duplication
	public function __construct()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
345
	{
346
		$this->id = 'absences_forthcoming';
347
		$this->name = absences_translate('Forthcomming absences');
348
		$this->description = absences_translate('Forthcomming absences for users in the same department or for all personel members');
349
		$this->addon = bab_getAddonInfosInstance('absences');
0 ignored issues
show
Bug introduced by
The property addon does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
350
	}
351
352
	public function getId()
353
	{
354
		return $this->id; 
355
	}
356
	
357
	
358
	public function getName()
359
	{
360
		return $this->name;
361
	}
362
363
364
	public function getDescription()
365
	{
366
		return $this->description;	
367
	}
368
369
370
	public function getPortlet()
371
	{		
372
		return new Portlet_forthcoming;
373
	}
374
375
	/**
376
	 * Returns the widget rich icon URL.
377
	 * 
378
	 *
379
	 * @return string
380
	 */
381
	public function getRichIcon()
382
	{
383
		return $this->addon->getImagesPath() . 'icon.png';
384
	}
385
386
387
	/**
388
	 * Returns the widget icon URL.
389
	 * 
390
	 *
391
	 * @return string
392
	 */
393
	public function getIcon()
394
	{
395
		return $this->addon->getImagesPath() . 'icon.png';
396
	}
397
	
398
	/**
399
	 * Get thumbnail URL
400
	 * max 120x60
401
	 */
402
	public function getThumbnail()
403
	{
404
		return null;
405
	}
406
	
407
	public function getConfigurationActions()
408
	{
409
		return array();
410
	}
411
	
412
	public function getPreferenceFields()
413
	{
414
		
415
		
416
		$pop_options = array(
417
			array('value' => 'me', 'label' 	=> absences_translate('Me only')),
418
			array('value' =>'all', 'label' 	=> absences_translate('All users'))
419
		);
420
		
421
		
422
		try {
423
			$agent = absences_Agent::getCurrentUser();
424
			if (null !== $entity = $agent->getMainEntity())
425
			{
426
				$pop_options[] = array('value' =>'department', 'label' 	=> $entity['name']);
427
			}
428
		
429
		} catch (Exception $e)
430
		{
431
			// user not logged in
432
		}
433
		
434
		
435
		
436
		return array(
437
			array(
438
				'label' => absences_translate('Number of days in future'), 
439
				'type' => 'int', 
440
				'name' => 'days'
441
			),
442
			array(
443
				'label' => absences_translate('Display absences for'), 
444
				'type' => 'list', 
445
				'name' => 'population', 
446
				'options' => $pop_options
447
			),
448
			array(
449
				'label' => absences_translate('Long dates format'),
450
				'type' => 'boolean',
451
				'name' => 'longdates'		
452
			),
453
			array(
454
				'label' => absences_translate('Display request status'),
455
				'type' => 'boolean',
456
				'name' => 'viewstatus'		
457
			)
458
		);
459
	}
460
}
461
462
463
464
465
class Portlet_forthcoming extends Widget_Item implements portlet_PortletInterface
466
{
467
468
	private $options = array();
469
	
470
471
	
472
	/**
473
	 * @return array
474
	 */
475
	private function getDepartmentMembers()
476
	{
477
		global $babDB;
478
		
479
		try {
480
			$agent = absences_Agent::getCurrentUser();
481
			$entity = $agent->getMainEntity();
482
		
483
		} catch(Exception $e)
484
		{
485
			return null;
486
		}
487
		
488
		if (null === $entity)
489
		{
490
			return null;
491
		}
492
		
493
		$members = array();
494
		$res = bab_OCSelectEntityCollaborators($entity['id'], true);
495
		
496
		while ($arr = $babDB->db_fetch_assoc($res))
497
		{
498
			if (isset($arr['id_user']))
499
			{
500
				$members[] = (int) $arr['id_user'];
501
			} else {
502
				trigger_error('Missing id_user key, need ovidentia 8.0.97 version at least');
503
				return null;
504
			}
505
		}
506
		
507
		return $members;
508
	}
509
		
510
511
	/**
512
	 * @param Widget_Canvas	$canvas
513
	 * @ignore
514
	 */
515
	public function display(Widget_Canvas $canvas)
516
	{
517
		$W = bab_Widgets();
518
		
519
		
520
		
521
		
522
		$population = empty($this->options['population']) ? 'me' : $this->options['population'];
523
		$days = empty($this->options['days']) ? 7 : $this->options['days'];
524
		
525
		$to = BAB_DateTime::now();
526
		$to->add($days, BAB_DATETIME_DAY);
527
		
528
		
529
		$users = null;
530
		
531
		if ($population === 'department')
532
		{
533
			$users = $this->getDepartmentMembers();
534
			if (null === $users)
535
			{
536
				$population = 'me';
537
			}
538
		}
539
		
540
		
541
		if ($population === 'me')
542
		{
543
			$users = array(bab_getUserId());
544
		}
545
		
546
		
547
		$I = new absences_EntryIterator();
548
		$I->users = $users;
0 ignored issues
show
Documentation Bug introduced by
It seems like $users can be null. However, the property $users is declared as array. Maybe change the type of the property to array|null or add a type check?

Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.

To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.

function aContainsB(array $needle = null, array  $haystack) {
    if (!$needle) {
        return false;
    }

    return array_intersect($haystack, $needle) == $haystack;
}

The function can be called with either null or an array for the parameter $needle but will only accept an array as $haystack.

Loading history...
549
		$I->from = date('Y-m-d H:i:s');
550
		$I->to = $to->getIsoDateTime();
551
		$I->status = array('', 'Y');
552
		
553
		$I->orderby = 'date_begin ASC';
554
		
555
		$list = $W->VBoxLayout()->addClass(Func_Icons::ICON_LEFT_32);
556
557
		foreach($I as $entry)
558
		{
559
			$list->addItem($this->getEntryWidget($entry));
560
		}
561
		
562
		return '
563
		<style type="text/css" scoped>
564
			.icon-left-32 .icon {
565
			    min-height: 15px;
566
			    min-width: 0;
567
			    padding: 1em 8px 1em 36px;
568
			}
569
			
570
			.widget-small {
571
				color:rgba(0,0,0,.5);
572
			}
573
			
574
			.absences-portlet-forthcoming-entry {
575
				border-bottom:rgba(0,0,0,.19) 2px dotted;
576
				padding-bottom:.8em;
577
				margin-bottom:.8em;
578
			}
579
		</style>
580
		'.
581
		$list->display($canvas);
582
	}
583
	
584
	/**
585
	 * @return string|false
586
	 */
587
	private function getPhoto($id_user)
588
	{
589
		$T = bab_functionality::get('Thumbnailer');
590
		/*@var $T Func_Thumbnailer */
591
		
592
		if (false === $T)
593
		{
594
			return false;
595
		}
596
		
597
		
598
		$direntry = bab_getDirEntry($id_user, BAB_DIR_ENTRY_ID_USER);
599
		if (!$direntry || !isset($direntry['jpegphoto']['photo']))
0 ignored issues
show
Bug Best Practice introduced by
The expression $direntry of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
600
		{
601
			return false;
602
		}
603
		
604
		$photo = $direntry['jpegphoto']['photo'];
605
		$data = $photo->getData();
606
		
607
		if (null !== $data && '' !== $data)
608
		{
609
			$T->setSourceBinary($data, $photo->lastUpdate());
610
			$T->setResizeMode(Func_Thumbnailer::CROP_CENTER);
611
			return $T->getThumbnail(32, 32);
612
		}
613
		
614
		return false;
615
	}
616
	
617
	
618
	/**
619
	 * @return Widget_DisplayableInterface
620
	 */
621
	private function getEntryWidget(absences_Entry $entry)
622
	{
623
		$W = bab_Widgets();
624
625
		$icon = $W->Icon(null, Func_Icons::OBJECTS_USER);
626
		if ($photo = $this->getPhoto($entry->id_user))
627
		{
628
			$icon->setImageUrl($photo);
629
		}
630
			
631
		
632
		
633
		$url = bab_getUserDirEntryLink($entry->id_user, BAB_DIR_ENTRY_ID_USER);
0 ignored issues
show
Documentation introduced by
$entry->id_user is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
634
		if (false === $url)
635
		{
636
			$user = $W->Label(bab_getUserName($entry->id_user));
637
		} else {
638
			$user = $W->Link(bab_getUserName($entry->id_user), $url)->setOpenMode(Widget_Link::OPEN_POPUP);
639
		}
640
		
641
		$datefunc = !empty($this->options['longdates']) ? 'bab_longDate' : 'bab_shortDate';
642
		$period = $W->Label(absences_DateTimePeriod($entry->date_begin, $entry->date_end, $datefunc));
643
		
644
		$status = null;
645
		if (!empty($this->options['viewstatus']))
646
		{
647
			$status = $W->Label($entry->getStatusStr())->addClass('widget-small');
648
		}
649
		
650
		$layout = $W->HBoxItems($icon, $W->VBoxItems($user, $period, $status))->setVerticalAlign('top');
651
		
652
		return $W->Frame(null, $layout)->addClass('absences-portlet-forthcoming-entry');
653
	}
654
	
655
656
	public function getName()
657
	{
658
		return get_class($this);
659
	}
660
661
	public function getPortletDefinition()
662
	{
663
		return new PortletDefinition_forthcoming();
664
	}
665
	
666
	/**
667
	 * Get the title defined in preferences or a default title for the widget frame
668
	 * @return string
669
	 */
670
	public function getPreferenceTitle()
671
	{
672
		if (!empty($this->options['_blockTitle']))
673
		{
674
			return $this->options['_blockTitle'];
675
		}
676
		
677
		$days = empty($this->options['days']) ? 7 : $this->options['days'];
678
		
679
		return sprintf(absences_translate('Absences in the next %d days'), $days);
680
	}
681
	
682
	/**
683
	 * receive current user configuration from portlet API
684
	 */
685
	public function setPreferences(array $configuration)
686
	{
687
		$this->options = $configuration;
688
	}
689
	
690
	public function setPreference($name, $value)
691
	{
692
		$this->options[$name] = $value;
693
	}
694
	
695
	public function setPortletId($id)
696
	{
697
		
698
	}
699
}
700
701