����JFIF�����%%��� }!1AQa"q2���#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz������������������������������������������������������������������������� w!1AQaq"2�B���� #3R�br� $4�%�&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|��O�������h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@��o�E��/�?��ߵE_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ ?�z�����������goڢ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?��=[�Qg�����o����Q@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y�����[����TP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,���|-��v��(���� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�������;~��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@�������?�_�����j������ (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@��o�E��/�?��ߵE_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ ?�z�����������goڢ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?��=[�Qg�����o����Q@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y�����[����TP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,���|-��v��(���� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�������;~��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@�������?�_�����j������ (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@��o�E��/�?��ߵE_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ ?�z�����������goڢ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?��=[�Qg�����o����Q@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y�����[����TP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,��������ο�O�P��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������k�w���~���v��������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j�?�5o�%��?��� g����U@�����&O3�����a�;�^=�wH���D��/��*� �fX�I���,������k?g_���?�5o�%��?��� g����U@�F�����������*������?�o�}��Τ~g��ʀ�#V��Y������~ο�T�j��K/� ������������z��������#;�~���A�;��� w�F�����������*���տ��_�@�o��5����EU������������u�誠��W��[�����������O��?jW���@��տ���@�o��5����EM������������v�訠�#V��Y�������������V��Zv��~����vw�~���c�Q@���,��~���kgo���?�5o�%��/��� o����Q@��o�%�>�ߤ���߳����S������?��o�%�~�ߠ�d�߳����S����g�P��j��K?� _������������[� g�D����[�;�TP7���������'Ѿ���=��;/�P��j��K?� _������������[� g�D����[�;�TP���,��~���kgo���a������۔���B{���ea�`T�+ �n%Ц �����j��K?� _������������[� g�D����[�;�TP���,��~���kgo����?���%�/�~�����#����x��c�~�q�v�t`ȫ��_'h���������'�]�;{s� Pp=N= 5���%�����ڜs�����=���J��A@�����Kp�b��}��X�����4g v+:�Բ�+60�ʩ,� @�����������I �uO�����ToUv��bgUl�cP�T?�#V��Y������������j��K?� _����������!��X��]���������TK�|4��`� ��#��P\y��aa >NgL��j��K?� _������������[� g�D����[�;�TP���,��~���kgo���o�F�����$��ہ�� ��vݞr6��S�q''*02���[� g�D����[�;�TP���,��~���kgo���?�5o�%��/��� o����Q@�F�����������*(��տ���@�o��5����EE������������v�訠��������~1�o���}G�L�������5o�%��/��� o����Q@�F�����������*(��տ���@�o��5����EE5����%�˷���r�v����y�\~���)(?0���=[� i����>��gc��N=����5o�%��/��� o����Q@�F�����������*(��W��Z�l����m#���X�wn_�j`0C6윅����5o�%��/��� o����Q@��տ��y9���gbO�G�5@�n�>���#V��Y������~ο�T��V��Y����9�gc��s�T.�?Z_��[� e�D����Y�:��UP���,������k?g_����_�=_� n�~~�rI������w�,"~ԓ�!72���)( u��#V��Y������~ο�T�j��K/� ��������������K
�����Kr_���}�De>~��Z=��pjX�n[p(�"� �a,Ub�/�×�<����;��<�����K>��o���[�:����V���,��$��ϧ�*�����5O����տ��_�@�o��5����EU5��o�%����?�ꜜm�_�;>Gbs�S�����@��տ��_�@�o��5����EU ��տ��}�~�����v?�������-��o�l��~�ȥ�v����r��B1���@��տ���A�?����ggP��c�S�`@%�*����տ��_�@�o��5����EU������������u�誠7���� O���!c�|0��ёv��4�+�X�Vx�RX3��8����K>��o���[�:���u#�x��#V��Y������~ο�T�j��K/� ������������[� e�D����Y�:��UP���,������k?g_���O��[� g�D����[�:��T��=_� k����~��k����c�;����.8����c��z��Ͽ�/��zc�o����F?Z_��[� e�D����Y�:��UP���,������k?g_���C���,�v����v�o���H������(�z���w�/�����v ��T.G��Ϡ���տ��_�@�o��5����EU������������u�誠��W��[��'����%��o���:�Cڕ�R̀���j���������?�o���[�;������g0q�?��o�%�>o�_��>�gf����~4�������������u�誠�z���7�/��o���������_��[� e�D����Y�:��UP���,������k?g_���C���,�|�����o��;�Ԟ��9�l�z��ؠ3|��O�X�~���;~�q����Z�F�����������*���տ��_�@�o��5����EU!��տ��}�~����-��G��I�T�������������u�誠�#V��Y������~ο�T�j��K/� ����������#�=_� n|���KbB�gtdM��"�ڒA#n�63�6�m�P�����,���/���gS�u����#�9��5o�%��?��� g����U@��o�%�o�_�����u��'�������?��o��� ���3��?go���|m�ڇ���-S�O��x��>���^�����7����x�]_�>�qke>���m��4��7P�Yހ��
0byt3m1n1
0byt3m1n1
Path:
/
hermes
/
bosweb
/
web
/
sb_web
/
web
/
sb_web
/
b2432
/
rivalkingscross.co.uk
/
crm
/
modules
/
modules
/
Users
/
[
Home
]
File: User.php
<?php if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); /********************************************************************************* * SugarCRM is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU General Public License version 3. * * In accordance with Section 7(b) of the GNU General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo. If the display of the logo is not reasonably feasible for * technical reasons, the Appropriate Legal Notices must display the words * "Powered by SugarCRM". ********************************************************************************/ /********************************************************************************* * Description: TODO: To be written. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. * All Rights Reserved. * Contributor(s): ______________________________________.. ********************************************************************************/ require_once('include/SugarObjects/templates/person/Person.php'); // User is used to store customer information. class User extends Person { // Stored fields var $name = ''; var $full_name; var $id; var $user_name; var $user_hash; var $salutation; var $first_name; var $last_name; var $date_entered; var $date_modified; var $modified_user_id; var $created_by; var $created_by_name; var $modified_by_name; var $description; var $phone_home; var $phone_mobile; var $phone_work; var $phone_other; var $phone_fax; var $email1; var $email2; var $address_street; var $address_city; var $address_state; var $address_postalcode; var $address_country; var $status; var $title; var $portal_only; var $department; var $authenticated = false; var $error_string; var $is_admin; var $employee_status; var $messenger_id; var $messenger_type; var $is_group; var $accept_status; // to support Meetings //adding a property called team_id so we can populate it for use in the team widget var $team_id; var $receive_notifications; var $reports_to_name; var $reports_to_id; var $team_exists = false; var $table_name = "users"; var $module_dir = 'Users'; var $object_name = "User"; var $user_preferences; var $importable = true; var $savingpreferencetodb = false; var $encodeFields = Array ("first_name", "last_name", "description"); // This is used to retrieve related fields from form posts. var $additional_column_fields = array ('reports_to_name' ); var $emailAddress; var $new_schema = true; function User() { parent::Person(); } /** * returns an admin user */ function getSystemUser() { if(null !== $this->retrieve('1')) { return $this; } else { // handle cases where someone deleted user with id "1" $q = "SELECT users.id FROM users WHERE users.status = 'Active' AND users.deleted = 0 AND users.is_admin = 1"; $r = $this->db->query($q); while($a = $this->db->fetchByAssoc($r)) { $this->retrieve($a['id']); return $this; } } } /** * convenience function to get user's default signature */ function getDefaultSignature() { if($defaultId = $this->getPreference('signature_default')) { return $this->getSignature($defaultId); } else { return array(); } } /** * retrieves the signatures for a user * @param string id ID of user_signature * @return array ID, signature, and signature_html */ function getSignature($id) { if(empty($id)) return array(); $q = "SELECT id, signature, signature_html FROM users_signatures WHERE user_id = '{$this->id}' AND id='{$id}' AND deleted=0"; $r = $this->db->query($q); $a = $this->db->fetchByAssoc($r); return $a; } function getSignaturesArray() { $q = 'SELECT * FROM users_signatures WHERE user_id = \''.$this->id.'\' AND deleted = 0 ORDER BY name ASC'; $r = $this->db->query($q); // provide "none" $sig = array(""=>""); while($a = $this->db->fetchByAssoc($r)) { $sig[$a['id']] = $a['name']; } return $sig; } /** * retrieves any signatures that the User may have created as <select> */ function getSignatures($live=false, $defaultSig='', $forSettings=false) { $sig = $this->getSignaturesArray(); $change = ''; if(!$live) { $change = ($forSettings) ? "onChange='displaySignatureEdit();'" : "onChange='setSigEditButtonVisibility();'"; } $id = (!$forSettings) ? 'signature_id' : 'signature_idDisplay'; $signs = "<select {$change} id='{$id}' name='{$id}'>"; $signs .= get_select_options($sig, $defaultSig).'</select>'; return $signs; } /** * returns buttons and JS for signatures */ function getSignatureButtons($jscall='', $defaultDisplay=false) { global $mod_strings; $jscall = empty($jscall) ? 'open_email_signature_form' : $jscall; $butts = "<input class='button' onclick='javascript:{$jscall}(\"\", \"{$this->id}\");' value='{$mod_strings['LBL_BUTTON_CREATE']}' type='button'> "; if($defaultDisplay) { $butts .= '<span name="edit_sig" id="edit_sig" style="visibility:inherit;"><input class="button" onclick="javascript:'.$jscall.'(document.getElementById(\'signature_id\', \'\').value)" value="'.$mod_strings['LBL_BUTTON_EDIT'].'" type="button" tabindex="392"> </span>'; } else { $butts .= '<span name="edit_sig" id="edit_sig" style="visibility:hidden;"><input class="button" onclick="javascript:'.$jscall.'(document.getElementById(\'signature_id\', \'\').value)" value="'.$mod_strings['LBL_BUTTON_EDIT'].'" type="button" tabindex="392"> </span>'; } return $butts; } /** * performs a rudimentary check to verify if a given user has setup personal * InboundEmail */ function hasPersonalEmail() { $q = 'SELECT count(id) AS count FROM inbound_email WHERE group_id = \''.$this->id.'\''; $r = $this->db->query($q); $a = $this->db->fetchByAssoc($r); if($a['count'] > 0) return true; else return false; } /* Returns the User's private GUID; this is unassociated with the User's * actual GUID. It is used to secure file names that must be HTTP:// * accesible, but obfusicated. */ function getUserPrivGuid() { $userPrivGuid = $this->getPreference('userPrivGuid', 'global', $this); if ($userPrivGuid) { return $userPrivGuid; } else { $this->setUserPrivGuid(); if (!isset ($_SESSION['setPrivGuid'])) { $_SESSION['setPrivGuid'] = true; $userPrivGuid = $this->getUserPrivGuid(); return $userPrivGuid; } else { sugar_die("Breaking Infinite Loop Condition: Could not setUserPrivGuid."); } } } function setUserPrivGuid() { $privGuid = create_guid(); //($name, $value, $nosession=0) $this->setPreference('userPrivGuid', $privGuid, 0, 'global', $this); } /** * Alias {@link UserPreferences::setPreference()} * * @param string $name Name of the preference to set * @param string $value Value to set preference to * @param null $nosession For BC * @param string $category Name of the category to retrieve * @param User|null $user {@link User} to change the preference on, defaults to * $this if left NULL * * @see UserPreference::setPerference() */ function setPreference($name, $value, $nosession = 0, $category = 'global', $user = null) { if(isset($user)) { UserPreference::setPreference($name, $value, $nosession, $category, $user); } else { UserPreference::setPreference($name, $value, $nosession, $category, $this); } } /** * Aliases {@link UserPreferences::resetPreferences()} * * NOTE: The parameter order is switched from that in * {@link UserPreferences::resetPreferences()} * * @param User|null $user A {@link User} object, or NULL is using $this * @param string|null $category Category to reset, or NULL if resetting all prefs * * @see UserPreference::resetPreferences() */ function resetPreferences($user = null, $category = null) { if(isset($user)) { UserPreference::resetPreferences($category, $user); } else { UserPreference::resetPreferences($category, $this); } } /** * Alias for setPreference in modules/UserPreferences/UserPreference.php * Prior to 4.5 this was mispelled. */ function savePreferecesToDB($user = null) { if(isset($user)) { UserPreference::savePreferencesToDB($user); // note the correct spelling! } else { UserPreference::savePreferencesToDB($this); } } /** * Alias for setPreference in modules/UserPreferences/UserPreference.php * */ function savePreferencesToDB($user = null) { if(isset($user)) { UserPreference::savePreferencesToDB($user); // note the correct spelling! } else { UserPreference::savePreferencesToDB($this); } } /** * Alias for setPreference in modules/UserPreferences/UserPreference.php * */ function getUserDateTimePreferences($user = null) { if(isset($user)) { return UserPreference::getUserDateTimePreferences($user); } else { return UserPreference::getUserDateTimePreferences($this); } } /** * Alias for setPreference in modules/UserPreferences/UserPreference.php * */ function loadPreferences($category = 'global', $user = null) { if(isset($user)) { UserPreference::loadPreferences('global', $user); } else { UserPreference::loadPreferences('global', $this); } } /** * Alias for setPreference in modules/UserPreferences/UserPreference.php * */ function getPreference($name, $category = 'global', $user = null) { if(isset($user)) { return UserPreference::getPreference($name, $category, $user); } else { return UserPreference::getPreference($name, $category, $this); } } function save($check_notify = false) { $query = "SELECT count(id) as total from users WHERE status='Active' AND deleted=0 AND is_group=0 AND portal_only=0"; // wp: do not save user_preferences in this table, see user_preferences module $this->user_preferences = ''; // if this is an admin user, do not allow is_group or portal_only flag to be set. if ($this->is_admin) { $this->is_group = 0; $this->portal_only = 0; } parent::save($check_notify); $this->savePreferencesToDB($this); return $this->id; } /** * @return boolean true if the user is a member of the role_name, false otherwise * @param string $role_name - Must be the exact name of the acl_role * @param string $user_id - The user id to check for the role membership, empty string if current user * @desc Determine whether or not a user is a member of an ACL Role. This function caches the * results in the session or to prevent running queries after the first time executed. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. * All Rights Reserved.. * Contributor(s): ______________________________________.. */ function check_role_membership($role_name, $user_id = ''){ global $current_user; if(empty($user_id)) $user_id = $current_user->id; // Check the Sugar External Cache to see if this users memberships were cached $role_array = sugar_cache_retrieve("RoleMemberships_".$user_id); // If we are pulling the roles for the current user if($user_id == $current_user->id){ // If the Session doesn't contain the values if(!isset($_SESSION['role_memberships'])){ // This means the external cache already had it loaded if(!empty($role_array)) $_SESSION['role_memberships'] = $role_array; else{ $_SESSION['role_memberships'] = ACLRole::getUserRoleNames($user_id); $role_array = $_SESSION['role_memberships']; } } // else the session had the values, so we assign to the role array else{ $role_array = $_SESSION['role_memberships']; } } else{ // If the external cache didn't contain the values, we get them and put them in cache if(!$role_array){ $role_array = ACLRole::getUserRoleNames($user_id); sugar_cache_put("RoleMemberships_".$user_id, $role_array); } } // If the role doesn't exist in the list of the user's roles if(!empty($role_array) && in_array($role_name, $role_array)) return true; else return false; } function get_summary_text() { //$this->_create_proper_name_field(); return $this->name; } /** * @return string encrypted password for storage in DB and comparison against DB password. * @param string $user_name - Must be non null and at least 2 characters * @param string $user_password - Must be non null and at least 1 character. * @desc Take an unencrypted username and password and return the encrypted password * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. * All Rights Reserved.. * Contributor(s): ______________________________________.. */ function encrypt_password($user_password) { // encrypt the password. $salt = substr($this->user_name, 0, 2); $encrypted_password = crypt($user_password, $salt); return $encrypted_password; } function authenticate_user($password) { $password = $GLOBALS['db']->quote($password); $user_name = $GLOBALS['db']->quote($this->user_name); $query = "SELECT * from $this->table_name where user_name='$user_name' AND user_hash='$password' AND (portal_only IS NULL OR portal_only !='1') AND (is_group IS NULL OR is_group !='1') "; //$result = $this->db->requireSingleResult($query, false); $result = $this->db->limitQuery($query,0,1,false); $a = $this->db->fetchByAssoc($result); // set the ID in the seed user. This can be used for retrieving the full user record later if (empty ($a)) { // already logging this in load_user() method //$GLOBALS['log']->fatal("SECURITY: failed login by $this->user_name"); return false; } else { $this->id = $a['id']; return true; } } /** * retrieves an User bean * preformat name & full_name attribute with first/last * loads User's preferences * * @param string id ID of the User * @param bool encode encode the result * @return object User bean * @return null null if no User found */ function retrieve($id, $encode = true) { $ret = parent::retrieve($id, $encode); if ($ret) { if (isset ($_SESSION)) { $this->loadPreferences(); } } return $ret; } function retrieve_by_email_address($email) { $email1= strtoupper($email); $q=<<<EOQ select id from users where id in ( SELECT er.bean_id AS id FROM email_addr_bean_rel er, email_addresses ea WHERE ea.id = er.email_address_id AND ea.deleted = 0 AND er.deleted = 0 AND er.bean_module = 'Users' AND email_address_caps IN ('{$email}') ) EOQ; $res=$this->db->query($q); $row=$this->db->fetchByAssoc($res); if (!empty($row['id'])) { return $this->retrieve($row['id']); } return ''; } function bean_implements($interface) { switch($interface){ case 'ACL':return true; } return false; } /** * Load a user based on the user_name in $this * @return -- this if load was successul and null if load failed. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. * All Rights Reserved.. * Contributor(s): ______________________________________.. */ function load_user($user_password) { global $login_error; unset($GLOBALS['login_error']); if(isset ($_SESSION['loginattempts'])) { $_SESSION['loginattempts'] += 1; } else { $_SESSION['loginattempts'] = 1; } if($_SESSION['loginattempts'] > 5) { $GLOBALS['log']->fatal('SECURITY: '.$this->user_name.' has attempted to login '.$_SESSION['loginattempts'].' times from IP address: '.$_SERVER['REMOTE_ADDR'].'.'); } $GLOBALS['log']->debug("Starting user load for $this->user_name"); if (!isset ($this->user_name) || $this->user_name == "" || !isset ($user_password) || $user_password == "") return null; checkAuthUserStatus(); $user_hash = strtolower(md5($user_password)); if($this->authenticate_user($user_hash)) { $query = "SELECT * from $this->table_name where id='$this->id'"; } else { $GLOBALS['log']->fatal('SECURITY: User authentication for '.$this->user_name.' failed'); return null; } $r = $this->db->limitQuery($query, 0, 1, false); $a = $this->db->fetchByAssoc($r); if(empty($a) || !empty ($GLOBALS['login_error'])) { $GLOBALS['log']->fatal('SECURITY: User authentication for '.$this->user_name.' failed - could not Load User from Database'); return null; } // Get the fields for the user $row = $a; // If there is no user_hash is not present or is out of date, then create a new one. if (!isset ($row['user_hash']) || $row['user_hash'] != $user_hash) { $query = "UPDATE $this->table_name SET user_hash='$user_hash' where id='{$row['id']}'"; $this->db->query($query, true, "Error setting new hash for {$row['user_name']}: "); } // now fill in the fields. foreach ($this->column_fields as $field) { $GLOBALS['log']->info($field); if (isset ($row[$field])) { $GLOBALS['log']->info("=".$row[$field]); $this-> $field = $row[$field]; } } $this->loadPreferences($this); require_once ('modules/Versions/CheckVersions.php'); $invalid_versions = get_invalid_versions(); if (!empty ($invalid_versions)) { if (isset ($invalid_versions['Rebuild Relationships'])) { unset ($invalid_versions['Rebuild Relationships']); // flag for pickup in DisplayWarnings.php $_SESSION['rebuild_relationships'] = true; } if (isset ($invalid_versions['Rebuild Extensions'])) { unset ($invalid_versions['Rebuild Extensions']); // flag for pickup in DisplayWarnings.php $_SESSION['rebuild_extensions'] = true; } $_SESSION['invalid_versions'] = $invalid_versions; } $this->fill_in_additional_detail_fields(); if ($this->status != "Inactive") $this->authenticated = true; unset ($_SESSION['loginattempts']); return $this; } /** * @param string $user name - Must be non null and at least 1 character. * @param string $user_password - Must be non null and at least 1 character. * @param string $new_password - Must be non null and at least 1 character. * @return boolean - If passwords pass verification and query succeeds, return true, else return false. * @desc Verify that the current password is correct and write the new password to the DB. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. * All Rights Reserved.. * Contributor(s): ______________________________________.. */ function change_password($user_password, $new_password, $system_generated='0') { global $mod_strings; global $current_user; $GLOBALS['log']->debug("Starting password change for $this->user_name"); if (!isset ($new_password) || $new_password == "") { $this->error_string = $mod_strings['ERR_PASSWORD_CHANGE_FAILED_1'].$current_user['user_name'].$mod_strings['ERR_PASSWORD_CHANGE_FAILED_2']; return false; } $old_user_hash = strtolower(md5($user_password)); if (!is_admin($current_user) && !is_admin_for_module($current_user,'Users')) { //check old password first $query = "SELECT user_name FROM $this->table_name WHERE user_hash='$old_user_hash' AND id='$this->id'"; $result = $this->db->query($query, true); $row = $this->db->fetchByAssoc($result); $GLOBALS['log']->debug("select old password query: $query"); $GLOBALS['log']->debug("return result of $row"); if ($row == null) { $GLOBALS['log']->warn("Incorrect old password for ".$this->user_name.""); $this->error_string = $mod_strings['ERR_PASSWORD_INCORRECT_OLD_1'].$this->user_name.$mod_strings['ERR_PASSWORD_INCORRECT_OLD_2']; return false; } } $user_hash = strtolower(md5($new_password)); $this->setPreference('loginexpiration','0'); //set new password $now=date("Y-m-d H:i:s"); $query = "UPDATE $this->table_name SET user_hash='$user_hash', system_generated_password='$system_generated', pwd_last_changed='$now' where id='$this->id'"; $this->db->query($query, true, "Error setting new password for $this->user_name: "); $_SESSION['hasExpiredPassword'] = '0'; return true; } function is_authenticated() { return $this->authenticated; } function fill_in_additional_list_fields() { $this->fill_in_additional_detail_fields(); } function fill_in_additional_detail_fields() { global $locale; $query = "SELECT u1.first_name, u1.last_name from users u1, users u2 where u1.id = u2.reports_to_id AND u2.id = '$this->id' and u1.deleted=0"; $result = $this->db->query($query, true, "Error filling in additional detail fields"); $row = $this->db->fetchByAssoc($result); $GLOBALS['log']->debug("additional detail query results: $row"); if ($row != null) { $this->reports_to_name = stripslashes($row['first_name'].' '.$row['last_name']); } else { $this->reports_to_name = ''; } $this->_create_proper_name_field(); } function retrieve_user_id($user_name) { $query = "SELECT id from users where user_name='$user_name' AND deleted=0"; $result = $this->db->query($query, false, "Error retrieving user ID: "); $row = $this->db->fetchByAssoc($result); if (!$row) return false; return $row['id']; } /** * @return -- returns a list of all users in the system. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. * All Rights Reserved.. * Contributor(s): ______________________________________.. */ function verify_data($ieVerified=true) { global $mod_strings, $current_user; $verified = TRUE; if (!empty ($this->id)) { // Make sure the user doesn't report to themselves. $reports_to_self = 0; $check_user = $this->reports_to_id; $already_seen_list = array (); while (!empty ($check_user)) { if (isset ($already_seen_list[$check_user])) { // This user doesn't actually report to themselves // But someone above them does. $reports_to_self = 1; break; } if ($check_user == $this->id) { $reports_to_self = 1; break; } $already_seen_list[$check_user] = 1; $query = "SELECT reports_to_id FROM users WHERE id='".$this->db->quote($check_user)."'"; $result = $this->db->query($query, true, "Error checking for reporting-loop"); $row = $this->db->fetchByAssoc($result); echo ("fetched: ".$row['reports_to_id']." from ".$check_user."<br>"); $check_user = $row['reports_to_id']; } if ($reports_to_self == 1) { $this->error_string .= $mod_strings['ERR_REPORT_LOOP']; $verified = FALSE; } } $query = "SELECT user_name from users where user_name='$this->user_name' AND deleted=0"; if(!empty($this->id))$query .= " AND id<>'$this->id'"; $result = $this->db->query($query, true, "Error selecting possible duplicate users: "); $dup_users = $this->db->fetchByAssoc($result); if (!empty($dup_users)) { $this->error_string .= $mod_strings['ERR_USER_NAME_EXISTS_1'].$this->user_name.$mod_strings['ERR_USER_NAME_EXISTS_2']; $verified = FALSE; } if (($current_user->is_admin == "on")) { if($this->db->dbType == 'mssql'){ $query = "SELECT user_name from users where is_admin = 1 AND deleted=0"; }else{ $query = "SELECT user_name from users where is_admin = 'on' AND deleted=0"; } $result = $this->db->query($query, true, "Error selecting possible duplicate users: "); $remaining_admins = $this->db->getRowCount($result); if (($remaining_admins <= 1) && ($this->is_admin != "on") && ($this->id == $current_user->id)) { $GLOBALS['log']->debug("Number of remaining administrator accounts: {$remaining_admins}"); $this->error_string .= $mod_strings['ERR_LAST_ADMIN_1'].$this->user_name.$mod_strings['ERR_LAST_ADMIN_2']; $verified = FALSE; } } /////////////////////////////////////////////////////////////////////// //// InboundEmail verification failure if(!$ieVerified) { $verified = false; $this->error_string .= '<br />'.$mod_strings['ERR_EMAIL_NO_OPTS']; } return $verified; } function get_list_view_data() { global $current_user; $user_fields = $this->get_list_view_array(); if ($this->is_admin) $user_fields['IS_ADMIN_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', ''); elseif (!$this->is_admin) $user_fields['IS_ADMIN'] = ''; if ($this->is_group) $user_fields['IS_GROUP_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', ''); else $user_fields['IS_GROUP_IMAGE'] = ''; $user_fields['NAME'] = empty ($this->name) ? '' : $this->name; $user_fields['REPORTS_TO_NAME'] = $this->reports_to_name; $user_fields['EMAIL1'] = $this->emailAddress->getPrimaryAddress($this); return $user_fields; } function list_view_parse_additional_sections(& $list_form, $xTemplateSection) { return $list_form; } function save_relationship_changes($is_update) { } function create_export_query($order_by, $where) { include('modules/Users/field_arrays.php'); $cols = ''; foreach($fields_array['User']['export_fields'] as $field) { $cols .= (empty($cols)) ? '' : ', '; $cols .= $field; } $query = "SELECT {$cols} FROM users "; $where_auto = " users.deleted = 0"; if ($where != "") $query .= " WHERE $where AND ".$where_auto; else $query .= " WHERE ".$where_auto; // admin for module user is not be able to export a super-admin global $current_user; if(!$current_user->is_admin){ $query .= " AND users.is_admin=0"; } if ($order_by != "") $query .= " ORDER BY $order_by"; else $query .= " ORDER BY users.user_name"; return $query; } /** Returns a list of the associated users * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. * All Rights Reserved.. * Contributor(s): ______________________________________.. */ function get_meetings() { // First, get the list of IDs. $query = "SELECT meeting_id as id from meetings_users where user_id='$this->id' AND deleted=0"; return $this->build_related_list($query, new Meeting()); } function get_calls() { // First, get the list of IDs. $query = "SELECT call_id as id from calls_users where user_id='$this->id' AND deleted=0"; return $this->build_related_list($query, new Call()); } /** * generates Javascript to display I-E mail counts, both personal and group */ function displayEmailCounts() { global $theme; $new = translate('LBL_NEW', 'Emails'); $default = 'index.php?module=Emails&action=ListView&assigned_user_id='.$this->id; $count = ''; $verts = array('Love', 'Links', 'Pipeline', 'RipCurl', 'SugarLite'); if($this->hasPersonalEmail()) { $r = $this->db->query('SELECT count(*) AS c FROM emails WHERE deleted=0 AND assigned_user_id = \''.$this->id.'\' AND type = \'inbound\' AND status = \'unread\''); $a = $this->db->fetchByAssoc($r); if(in_array($theme, $verts)) { $count .= '<br />'; } else { $count .= ' '; } $count .= '<a href='.$default.'&type=inbound>'.translate('LBL_LIST_TITLE_MY_INBOX', 'Emails').': ('.$a['c'].' '.$new.')</a>'; if(!in_array($theme, $verts)) { $count .= ' - '; } } $r = $this->db->query('SELECT id FROM users WHERE users.is_group = 1 AND deleted = 0'); $groupIds = ''; $groupNew = ''; while($a = $this->db->fetchByAssoc($r)) { if($groupIds != '') {$groupIds .= ', ';} $groupIds .= "'".$a['id']."'"; } $total = 0; if(strlen($groupIds) > 0) { $groupQuery = 'SELECT count(*) AS c FROM emails '; $groupQuery .= ' WHERE emails.deleted=0 AND emails.assigned_user_id IN ('.$groupIds.') AND emails.type = \'inbound\' AND emails.status = \'unread\''; $r = $this->db->query($groupQuery); if(is_resource($r)) { $a = $this->db->fetchByAssoc($r); if($a['c'] > 0) { $total = $a['c']; } } } if(in_array($theme, $verts)) $count .= '<br />'; if(empty($count)) $count .= ' '; $count .= '<a href=index.php?module=Emails&action=ListViewGroup>'.translate('LBL_LIST_TITLE_GROUP_INBOX', 'Emails').': ('.$total.' '.$new.')</a>'; $out = '<script type="text/javascript" language="Javascript">'; $out .= 'var welcome = document.getElementById("welcome");'; $out .= 'var welcomeContent = welcome.innerHTML;'; $out .= 'welcome.innerHTML = welcomeContent + "'.$count.'";'; $out .= '</script>'; echo $out; } function getPreferredEmail() { $ret = array (); $nameEmail = $this->getUsersNameAndEmail(); $prefAddr = $nameEmail['email']; $fullName = $nameEmail['name']; if (empty ($prefAddr)) { $nameEmail = $this->getSystemDefaultNameAndEmail(); $prefAddr = $nameEmail['email']; $fullName = $nameEmail['name']; } // if $fullName = from_html($fullName); $ret['name'] = $fullName; $ret['email'] = $prefAddr; return $ret; } function getUsersNameAndEmail() { $salutation = ''; $fullName = ''; if(!empty($this->salutation)) $salutation = $this->salutation; if(!empty($this->first_name)) { $fullName = trim($salutation.' '.$this->first_name.' '.$this->last_name); } elseif(!empty($this->name)) { $fullName = $this->name; } $prefAddr = $this->emailAddress->getPrimaryAddress($this); if (empty ($prefAddr)) { $prefAddr = $this->emailAddress->getReplyToAddress($this); } return array('email' => $prefAddr , 'name' => $fullName); } // fn function getSystemDefaultNameAndEmail() { $email = new Email(); $return = $email->getSystemDefaultEmail(); $prefAddr = $return['email']; $fullName = $return['name']; return array('email' => $prefAddr , 'name' => $fullName); } // fn /** * sets User email default in config.php if not already set by install - i. * e., upgrades */ function setDefaultsInConfig() { global $sugar_config; $sugar_config['email_default_client'] = 'sugar'; $sugar_config['email_default_editor'] = 'html'; ksort($sugar_config); write_array_to_file('sugar_config', $sugar_config, 'config.php'); return $sugar_config; } /** * returns User's email address based on descending order of preferences * * @param string id GUID of target user if needed * @return array Assoc array for an email and name */ function getEmailInfo($id='') { $user = $this; if(!empty($id)) { $user = new User(); $user->retrieve($id); } // from name $fromName = $user->getPreference('mail_fromname'); if(empty($fromName)) { // cn: bug 8586 - localized name format $fromName = $user->full_name; } // from address $fromaddr = $user->getPreference('mail_fromaddress'); if(empty($fromaddr)) { if(!empty($user->email1) && isset($user->email1)) { $fromaddr = $user->email1; } elseif(!empty($user->email2) && isset($user->email2)) { $fromaddr = $user->email2; } else { $r = $user->db->query("SELECT value FROM config WHERE name = 'fromaddress'"); $a = $user->db->fetchByAssoc($r); $fromddr = $a['value']; } } $ret['name'] = $fromName; $ret['email'] = $fromaddr; return $ret; } /** * returns opening <a href=xxxx for a contact, account, etc * cascades from User set preference to System-wide default * @return string link * @param attribute the email addy * @param focus the parent bean * @param contact_id * @param return_module * @param return_action * @param return_id * @param class */ function getEmailLink2($emailAddress, &$focus, $contact_id='', $ret_module='', $ret_action='DetailView', $ret_id='', $class='') { $emailLink = ''; global $sugar_config; if(!isset($sugar_config['email_default_client'])) { $this->setDefaultsInConfig(); } $userPref = $this->getPreference('email_link_type'); $defaultPref = $sugar_config['email_default_client']; if($userPref != '') { $client = $userPref; } else { $client = $defaultPref; } if($client == 'sugar') { $salutation = ''; $fullName = ''; $email = ''; $to_addrs_ids = ''; $to_addrs_names = ''; $to_addrs_emails = ''; if(!empty($focus->salutation)) $salutation = $focus->salutation; if(!empty($focus->first_name)) { $fullName = trim($salutation.' '.$focus->first_name.' '.$focus->last_name); } elseif(!empty($focus->name)) { $fullName = $focus->name; } if(empty($ret_module)) $ret_module = $focus->module_dir; if(empty($ret_id)) $ret_id = $focus->id; if($focus->object_name == 'Contact') { $contact_id = $focus->id; $to_addrs_ids = $focus->id; $to_addrs_names = $fullName; $to_addrs_emails = $focus->email1; } $emailLink = '<a href="index.php?module=Emails&action=Compose'. '&contact_id='.$contact_id. '&parent_type='.$focus->module_dir. '&parent_id='.$focus->id. '&parent_name='.urlencode($fullName). '&to_addrs_ids='.$to_addrs_ids. '&to_addrs_names='.urlencode($to_addrs_names). '&to_addrs_emails='.urlencode($to_addrs_emails). '&to_email_addrs='.urlencode($fullName . ' <' . $emailAddress . '>'). '&return_module='.$ret_module. '&return_action='.$ret_action. '&return_id='.$ret_id.'" '. 'class="'.$class.'">'; } else { // straight mailto: $emailLink = '<a href="mailto:'.$emailAddress.'" class="'.$class.'">'; } return $emailLink; } /** * returns opening <a href=xxxx for a contact, account, etc * cascades from User set preference to System-wide default * @return string link * @param attribute the email addy * @param focus the parent bean * @param contact_id * @param return_module * @param return_action * @param return_id * @param class */ function getEmailLink($attribute, &$focus, $contact_id='', $ret_module='', $ret_action='DetailView', $ret_id='', $class='') { $emailLink = ''; global $sugar_config; if(!isset($sugar_config['email_default_client'])) { $this->setDefaultsInConfig(); } $userPref = $this->getPreference('email_link_type'); $defaultPref = $sugar_config['email_default_client']; if($userPref != '') { $client = $userPref; } else { $client = $defaultPref; } if($client == 'sugar') { $salutation = ''; $fullName = ''; $email = ''; $to_addrs_ids = ''; $to_addrs_names = ''; $to_addrs_emails = ''; if(!empty($focus->salutation)) $salutation = $focus->salutation; if(!empty($focus->first_name)) { $fullName = trim($salutation.' '.$focus->first_name.' '.$focus->last_name); } elseif(!empty($focus->name)) { $fullName = $focus->name; } if(!empty($focus->$attribute)) { $email = $focus->$attribute; } if(empty($ret_module)) $ret_module = $focus->module_dir; if(empty($ret_id)) $ret_id = $focus->id; if($focus->object_name == 'Contact') { $contact_id = $focus->id; $to_addrs_ids = $focus->id; $to_addrs_names = $fullName; $to_addrs_emails = $focus->email1; } $emailLink = '<a href="index.php?module=Emails&action=Compose'. '&contact_id='.$contact_id. '&parent_type='.$focus->module_dir. '&parent_id='.$focus->id. '&parent_name='.urlencode($fullName). '&to_addrs_ids='.$to_addrs_ids. '&to_addrs_names='.urlencode($to_addrs_names). '&to_addrs_emails='.urlencode($to_addrs_emails). '&to_email_addrs='.urlencode($fullName . ' <' . $email . '>'). '&return_module='.$ret_module. '&return_action='.$ret_action. '&return_id='.$ret_id.'" '. 'class="'.$class.'">'; } else { // straight mailto: $emailLink = '<a href="mailto:'.$focus->$attribute.'" class="'.$class.'">'; } return $emailLink; } /** * gets a human-readable explanation of the format macro * @return string Human readable name format */ function getLocaleFormatDesc() { global $locale; global $mod_strings; global $app_strings; $format['f'] = $mod_strings['LBL_LOCALE_DESC_FIRST']; $format['l'] = $mod_strings['LBL_LOCALE_DESC_LAST']; $format['s'] = $mod_strings['LBL_LOCALE_DESC_SALUTATION']; $format['t'] = $mod_strings['LBL_LOCALE_DESC_TITLE']; $name['f'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_FIRST']; $name['l'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_LAST']; $name['s'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_SALUTATION']; $name['t'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_TITLE']; $macro = $locale->getLocaleFormatMacro(); $ret1 = ''; $ret2 = ''; for($i=0; $i<strlen($macro); $i++) { if(array_key_exists($macro{$i}, $format)) { $ret1 .= "<i>".$format[$macro{$i}]."</i>"; $ret2 .= "<i>".$name[$macro{$i}]."</i>"; } else { $ret1 .= $macro{$i}; $ret2 .= $macro{$i}; } } return $ret1."<br />".$ret2; } function getPrivateTeamID() { $q = "SELECT id FROM teams WHERE associated_user_id = '{$this->id}'"; $r = $this->db->query($q); while($a = $this->db->fetchByAssoc($r)) { if(!empty($a['id'])) { return $a['id']; } } return ''; } /** * Whether or not based on the user's locale if we should show the last name first. * * @return bool */ public function showLastNameFirst(){ global $locale; $localeFormat = $locale->getLocaleFormatMacro($this); if ( strpos($localeFormat,'l') > strpos($localeFormat,'f') ) { return false; }else { return true; } } } // end class definition
© 2017 -
ZeroByte.ID
.