����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
/
b1705
/
choosetheright.us
/
blog
/
inc
/
MODEL
/
files
/
[
Home
]
File: _file.class.php
<?php /** * This file implements the File class. * * This file is part of the evoCore framework - {@link http://evocore.net/} * See also {@link http://sourceforge.net/projects/evocms/}. * * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/} * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}. * * {@internal License choice * - If you have received this file as part of a package, please find the license.txt file in * the same folder or the closest folder above for complete license terms. * - If you have received this file individually (e-g: from http://cvs.sourceforge.net/viewcvs.py/evocms/) * then you must choose one of the following licenses before using the file: * - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php * - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php * }} * * {@internal Open Source relicensing agreement: * Daniel HAHLER grants Francois PLANQUE the right to license * Daniel HAHLER's contributions to this file and the b2evolution project * under any OSI approved OSS license (http://www.opensource.org/licenses/). * }} * * @package evocore * * {@internal Below is a list of authors who have contributed to design/coding of this file: }} * @author blueyed: Daniel HAHLER. * @author fplanque: Francois PLANQUE. * * @version $Id: _file.class.php,v 1.15.2.3.2.1 2007/04/25 22:17:49 fplanque Exp $ * */ if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' ); /** * Represents a file or folder on disk. Optionnaly stores meta data from DB. * * Use {@link FileCache::get_by_path()} to create an instance. * This is based on {@link DataObject} for the meta data. * * @package evocore */ class File extends DataObject { /** * Have we checked for meta data in the DB yet? * @var string */ var $meta = 'unknown'; /** * Meta data: Long title * @var string */ var $title; /** * Meta data: ALT text for images * @var string */ var $alt; /** * Meta data: Description * @var string */ var $desc; /** * FileRoot of this file * @var Fileroot * @access protected */ var $_FileRoot; /** * Posix subpath for this file/folder, relative the associated root (No trailing slash) * @var string * @access protected */ var $_rdfp_rel_path; /** * Full path for this file/folder, WITHOUT trailing slash. * @var string * @access protected */ var $_adfp_full_path; /** * Directory path for this file/folder, including trailing slash. * @var string * @see get_dir() * @access protected */ var $_dir; /** * Name of this file/folder, without path. * @var string * @see get_name() * @access protected */ var $_name; /** * MD5 hash of full pathname. * * This is useful to refer to files in hidden form fields, but might be replaced by the root_ID+relpath. * * @todo fplanque>> get rid of it * * @var string * @see get_md5_ID() * @access protected */ var $_md5ID; /** * Does the File/folder exist on disk? * @var boolean * @see exists() * @access protected */ var $_exists; /** * Is the File a directory? * @var boolean * @see is_dir() * @access protected */ var $_is_dir; /** * File size in bytes. * @var integer * @see get_size() * @access protected */ var $_size; /** * UNIX timestamp of last modification on disk. * @var integer * @see get_lastmod_ts() * @see get_lastmod_formatted() * @access protected */ var $_lastmod_ts; /** * Filesystem file permissions. * @var integer * @see get_perms() * @access protected */ var $_perms; /** * File owner. * @var string|NULL * @see get_fsowner_name() * @access protected */ var $_fsowner_name; /** * File group. * @var string|NULL * @see get_fsgroup_name() * @access protected */ var $_fsgroup_name; /** * Is the File an image? * @var NULL|boolean * @see is_image() * @access protected */ var $_is_image; /** * Extension, Mime type, icon, viewtype and 'allowed extension' of the file * @var Filetype object */ var $Filetype; /** * Constructor, not meant to be called directly. Use {@link FileCache::get_by_path()} * instead, which provides caching and checks that only one object for * a unique file exists (references). * * @param string Root type: 'user', 'group', 'collection' or 'absolute' * @param integer ID of the user, the group or the collection the file belongs to... * @param string Posix subpath for this file/folder, relative to the associated root (no trailing slash) * @param boolean check for meta data? * @return mixed false on failure, File object on success */ function File( $root_type, $root_ID, $rdfp_rel_path, $load_meta = false ) { global $FileRootCache, $Debuglog, $FiletypeCache; $Debuglog->add( "new File( $root_type, $root_ID, $rdfp_rel_path, load_meta=$load_meta)", 'files' ); // Call parent constructor parent::DataObject( 'T_files', 'file_', 'file_ID', '', '', '', '' ); $this->delete_restrictions = array( array( 'table'=>'T_links', 'fk'=>'link_file_ID', 'msg'=>T_('%d linked items') ), ); // Memorize filepath: $this->_FileRoot = & $FileRootCache->get_by_type_and_ID( $root_type, $root_ID ); $this->_rdfp_rel_path = no_trailing_slash(str_replace( '\\', '/', $rdfp_rel_path )); $this->_adfp_full_path = $this->_FileRoot->ads_path.$this->_rdfp_rel_path; $this->_name = basename( $this->_adfp_full_path ); $this->_dir = dirname( $this->_adfp_full_path ).'/'; $this->_md5ID = md5( $this->_adfp_full_path ); // Create the filetype with the extension of the file if the extension exist in database if( $ext = $this->get_ext() ) { // The file has an extension, load filetype object $this->Filetype = & $FiletypeCache->get_by_extension( strtolower( $ext ), false ); } // Initializes file properties (type, size, perms...) $this->load_properties(); if( $load_meta ) { // Try to load DB meta info: $this->load_meta(); } } /** * Attempt to load meta data. * * Will attempt only once and cache the result. * * @param boolean create meta data in DB if it doesn't exist yet? (generates a $File->ID) * @param object database row containing all fields needed to initialize meta data * @return boolean true if meta data has been loaded/initialized. */ function load_meta( $force_creation = false, $row = NULL ) { global $DB, $Debuglog, $FileCache; if( $this->meta == 'unknown' ) { // We haven't tried loading yet: if( is_null( $row ) ) { // No DB data has been provided: $row = $DB->get_row( ' SELECT * FROM T_files WHERE file_root_type = "'.$this->_FileRoot->type.'" AND file_root_ID = '.$this->_FileRoot->in_type_ID.' AND file_path = '.$DB->quote($this->_rdfp_rel_path), OBJECT, 0, 'Load file meta data' ); } if( $row ) { // We found meta data $Debuglog->add( "Loaded metadata for {$this->_FileRoot->ID}:{$this->_rdfp_rel_path}", 'files' ); $this->meta = 'loaded'; $this->ID = $row->file_ID; $this->title = $row->file_title; $this->alt = $row->file_alt; $this->desc = $row->file_desc; // Store this in the FileCache: $FileCache->add( $this ); } else { // No meta data... $Debuglog->add( "No metadata could be loaded for {$this->_FileRoot->ID}:$this->_rdfp_rel_path", 'files' ); $this->meta = 'notfound'; if( $force_creation ) { // No meta data, we have to create it now! $this->dbinsert(); } } } return ($this->meta == 'loaded'); } /** * Create the file/folder on disk, if it does not exist yet. * * Also sets file permissions. * Also inserts meta data into DB (if file/folder was successfully created). * * @param string type ('dir'|'file') * @param string optional permissions (octal format), otherwise the default from {@link $Settings} gets used * @return boolean true if file/folder was created, false on failure */ function create( $type = 'file', $chmod = NULL ) { if( $type == 'dir' ) { // Create an empty directory: $success = @mkdir( $this->_adfp_full_path ); $this->_is_dir = true; // used by chmod } else { // Create an empty file: $success = touch( $this->_adfp_full_path ); $this->_is_dir = false; // used by chmod } $this->chmod( $chmod ); // uses $Settings for NULL if( $success ) { // The file/folder has been successfully created: // Initializes file properties (type, size, perms...) $this->load_properties(); // If there was meta data for this file in the DB: // (maybe the file had existed before?) // Let's recycle it! : if( ! $this->load_meta() ) { // No meta data could be loaded, let's make sure localization info gets recorded: $this->set( 'root_type', $this->_FileRoot->type ); $this->set( 'root_ID', $this->_FileRoot->in_type_ID ); $this->set( 'path', $this->_rdfp_rel_path ); } // Record to DB: $this->dbsave(); } return $success; } /** * Initializes or refreshes file properties (type, size, perms...) */ function load_properties() { // Unset values that will be determined (and cached) upon request $this->_is_image = NULL; $this->_exists = file_exists( $this->_adfp_full_path ); if( is_dir( $this->_adfp_full_path ) ) { // The File is a directory: $this->_is_dir = true; $this->_size = NULL; } else { // The File is a regular file: $this->_is_dir = false; $this->_size = @filesize( $this->_adfp_full_path ); } // for files and dirs: $this->_lastmod_ts = @filemtime( $this->_adfp_full_path ); $this->_perms = @fileperms( $this->_adfp_full_path ); } /** * Does the File/folder exist on disk? * * @return boolean true, if the file or dir exists; false if not */ function exists() { return $this->_exists; } /** * Is the File a directory? * * @return boolean true if the object is a directory, false if not */ function is_dir() { return $this->_is_dir; } /** * Is the File an image? * * Tries to determine if it is and caches the info. * * @return boolean true if the object is an image, false if not */ function is_image() { if( is_null( $this->_is_image ) ) { // We don't know yet $this->_is_image = ( $this->get_image_size() !== false ); } return $this->_is_image; } /** * Get the File's ID (MD5 of path and name) * * @return string */ function get_md5_ID() { return $this->_md5ID; } /** * Get the File's name. * * @return string */ function get_name() { return $this->_name; } /** * Get the name prefixed either with "Directory" or "File". * * Returned string is localized. * * @return string */ function get_prefixed_name() { if( $this->is_dir() ) { return sprintf( T_('Directory «%s»'), $this->_name ); } else { return sprintf( T_('File «%s»'), $this->_name ); } } /** * Get the File's directory. * * @return string */ function get_dir() { return $this->_dir; } /** * Get the file posix path relative to it's root (no trailing /) * * @return string full path */ function get_rdfp_rel_path() { return $this->_rdfp_rel_path; } /** * Get the file path relative to it's root, WITH trailing slash. * * @return string full path */ function get_rdfs_rel_path() { return $this->_rdfp_rel_path.( $this->_is_dir ? '/' : '' ); } /** * Get the full path (directory and name) to the file. * * If the File is a directory, the Path ends with a / * * @return string full path */ function get_full_path() { return $this->_adfp_full_path.( $this->_is_dir ? '/' : '' ); } /** * Get the absolute file url if the file is public * Get the getfile.php url if we need to check permission before delivering the file */ function get_url() { global $public_access_to_media, $htsrv_url; if( $this->is_dir() ) { // Directory if( $public_access_to_media ) { // Public access: full path $url = $this->get_rdfs_rel_path(); } else { // No Access debug_die( 'Private directory! '); } } else { // File if( $public_access_to_media ) { // Public Access : full path $url = $this->_FileRoot->ads_url.$this->_rdfp_rel_path; } else { // Private Access: doesn't show the full path $root = $this->_FileRoot->ID; $url = $htsrv_url.'getfile.php/'.rawurlencode( $this->_name ).'?root='.$root.'&path='.$this->_rdfp_rel_path; } } return $url; } /** * Get location of file with its root (for display) */ function get_root_and_rel_path() { return $this->_FileRoot->name.':'.$this->get_rdfs_rel_path(); } /** * Get the File's FileRoot. * * @return FileRoot */ function & get_FileRoot() { return $this->_FileRoot; } /** * Get the file's extension. * * @return string the extension */ function get_ext() { if( preg_match('/\.([^.]+)$/', $this->_name, $match) ) { return $match[1]; } else { return ''; } } /** * Get the file type as a descriptive localized string. * * @return string localized type name or 'Directory' or 'Unknown' */ function get_type() { if( isset( $this->_type ) ) { // The type is already cached for this object: return $this->_type; } if( $this->is_dir() ) { $this->_type = T_('Directory'); return $this->_type; } if( isset( $this->Filetype->mimetype ) ) { $this->_type = $this->Filetype->name; return $this->_type; } $this->_type = T_('Unknown'); return $this->_type; } /** * Get file size in bytes. * * @return integer bytes */ function get_size() { return $this->_size; } /** * Get timestamp of last modification. * * @return integer Timestamp */ function get_lastmod_ts() { return $this->_lastmod_ts; } /** * Get date/time of last modification, formatted. * $ @param string date format or 'date' or 'time' for default locales. * @return string locale formatted date/time */ function get_lastmod_formatted( $format = '#' ) { switch( $format ) { case '#': $format = locale_datefmt().' '.locale_timefmt(); break; case 'date': $format = locale_datefmt(); break; case 'time': $format = locale_timefmt(); break; } return date_i18n( $format, $this->_lastmod_ts ); } /** * Get permissions * * Possible return formats are: * - 'raw'=integer * - 'lsl'=string like 'ls -l' * - 'octal'=3 digits * * Default value: * - 'r'/'r+w' for windows * - 'octal' for other OS * * @param string type, see desc above. * @return mixed permissions */ function get_perms( $type = NULL ) { switch( $type ) { case 'raw': return $this->_perms; case 'lsl': $sP = ''; if(($this->_perms & 0xC000) == 0xC000) // Socket $sP = 's'; elseif(($this->_perms & 0xA000) == 0xA000) // Symbolic Link $sP = 'l'; elseif(($this->_perms & 0x8000) == 0x8000) // Regular $sP = '−'; elseif(($this->_perms & 0x6000) == 0x6000) // Block special $sP = 'b'; elseif(($this->_perms & 0x4000) == 0x4000) // Directory $sP = 'd'; elseif(($this->_perms & 0x2000) == 0x2000) // Character special $sP = 'c'; elseif(($this->_perms & 0x1000) == 0x1000) // FIFO pipe $sP = 'p'; else // UNKNOWN $sP = 'u'; // owner $sP .= (($this->_perms & 0x0100) ? 'r' : '−') . (($this->_perms & 0x0080) ? 'w' : '−') . (($this->_perms & 0x0040) ? (($this->_perms & 0x0800) ? 's' : 'x' ) : (($this->_perms & 0x0800) ? 'S' : '−')); // group $sP .= (($this->_perms & 0x0020) ? 'r' : '−') . (($this->_perms & 0x0010) ? 'w' : '−') . (($this->_perms & 0x0008) ? (($this->_perms & 0x0400) ? 's' : 'x' ) : (($this->_perms & 0x0400) ? 'S' : '−')); // world $sP .= (($this->_perms & 0x0004) ? 'r' : '−') . (($this->_perms & 0x0002) ? 'w' : '−') . (($this->_perms & 0x0001) ? (($this->_perms & 0x0200) ? 't' : 'x' ) : (($this->_perms & 0x0200) ? 'T' : '−')); return $sP; case NULL: if( is_windows() ) { if( $this->_perms & 0x0080 ) { return 'r+w'; } else return 'r'; } case 'octal': return substr( sprintf('%o', $this->_perms), -3 ); } return false; } /** * Get the owner name of the file. * * @todo Can this be fixed for windows? filegroup() might only return 0 or 1 nad posix_getgrgid() is not available.. * @return NULL|string */ function get_fsgroup_name() { if( ! isset( $this->_fsgroup_name ) ) { $gid = @filegroup( $this->_adfp_full_path ); // might spit a warning for a dangling symlink if( $gid !== false && function_exists( 'posix_getgrgid' ) ) // func does not exist on windows { $posix_group = posix_getgrgid( $gid ); if( is_array($posix_group) ) { $this->_fsgroup_name = $posix_group['name']; } } } return $this->_fsgroup_name; } /** * Get the owner name of the file. * * @todo Can this be fixed for windows? fileowner() might only return 0 or 1 nad posix_getpwuid() is not available.. * @return NULL|string */ function get_fsowner_name() { if( ! isset( $this->_fsowner_name ) ) { $uid = @fileowner( $this->_adfp_full_path ); // might spit a warning for a dangling symlink if( $uid !== false && function_exists( 'posix_getpwuid' ) ) // func does not exist on windows { $posix_user = posix_getpwuid( $uid ); if( is_array($posix_user) ) { $this->_fsowner_name = $posix_user['name']; } } } return $this->_fsowner_name; } /** * Get icon for this file. * * Looks at the file's extension. * * @uses $map_iconfiles * @return string img tag */ function get_icon() { if( $this->is_dir() ) { // Directory icon: $icon = 'folder'; } elseif( isset( $this->Filetype->icon ) && $this->Filetype->icon ) { // Return icon for known type of the file return $this->Filetype->get_icon(); } else { // Icon for unknown file type: $icon = 'file_unknown'; } // Return Icon for a directory or unknown type file: return get_icon( $icon, 'imgtag', array( 'alt'=>$this->get_ext(), 'title'=>$this->get_type() ) ); } /** * Get size of an image or false if not an image * * @todo cache this data (NOTE: we have different params here! - imgsize() does caching already!) * * @uses imgsize() * @param string {@link imgsize()} * @return false|mixed false if the File is not an image, the requested data otherwise */ function get_image_size( $param = 'widthxheight' ) { return imgsize( $this->_adfp_full_path, $param ); } /** * Get size of the file, formatted to nearest unit (kb, mb, etc.) * * @uses bytesreadable() * @return string size as b/kb/mb/gd; or '<dir>' */ function get_size_formatted() { if( $this->_size === NULL ) { return /* TRANS: short for '<directory>' */ T_('<dir>'); } else { return bytesreadable( $this->_size ); } } /** * Get a complete tag (IMG or A HREF) pointing to this file. */ function get_tag( $before_image = '<div class="image_block">', $before_image_legend = '<div class="image_legend">', $after_image_legend = '</div>', $after_image = '</div>' ) { if( $this->is_dir() ) { // We can't reference a directory return ''; } $this->load_meta(); if( $this->is_image() ) { // Make an IMG link: $r = $before_image .'<img src="'.$this->get_url().'" ' .'alt="'.$this->dget('alt', 'htmlattr').'" ' .'title="'.$this->dget('title', 'htmlattr').'" ' .$this->get_image_size( 'string' ).' />'; $desc = $this->dget('desc'); if( !empty($desc) ) { $r .= $before_image_legend .$this->dget('desc') .$after_image_legend; } $r .= $after_image; } else { // Make an A HREF link: $r = '<a href="'.$this->get_url() .'" title="'.$this->dget('desc', 'htmlattr').'">' .$this->dget('title').'</a>'; } return $r; } /** * Internally sets the file/directory size * * This is used when the FileList wants to set the recursive size of a directory! * * @todo pass a param to the constructor telling it we want to store a recursive size for the direcrory. * @todo store the recursive size separately (in another member), to avoid confusion * * @access public * @param integer */ function setSize( $bytes ) { $this->_size = $bytes; } /** * Rename the file in its current directory on disk. * * Also update meta data in DB. * * @access public * @param string new name (without path!) * @return boolean true on success, false on failure */ function rename_to( $newname ) { // echo "newname= $newname "; // rename() will fail if newname already exists on windows // if it doesn't work that way on linux we need the extra check below // but then we have an integrity issue!! :( if( file_exists($this->_dir.$newname) ) { return false; } // Note: what happens if someone else creates $newname right at this moment here? if( ! @rename( $this->_adfp_full_path, $this->_dir.$newname ) ) { // Rename will fail if $newname already exists (at least on windows) return false; } // Get Meta data (before we change name) (we may need to update it later): $this->load_meta(); $this->_name = $newname; $rel_dir = dirname( $this->_rdfp_rel_path ).'/'; if( $rel_dir == './' ) { $rel_dir = ''; } $this->_rdfp_rel_path = $rel_dir.$this->_name; $this->_adfp_full_path = $this->_dir.$this->_name; $this->_md5ID = md5( $this->_adfp_full_path ); if( $this->meta == 'loaded' ) { // We have meta data, we need to deal with it: // unchanged : $this->set( 'root_type', $this->_FileRoot->type ); // unchanged : $this->set( 'root_ID', $this->_FileRoot->in_type_ID ); $this->set( 'path', $this->_rdfp_rel_path ); // Record to DB: $this->dbupdate(); } else { // There might be some old meta data to *recycle* in the DB... // This can happen if there has been a file in the same location in the past and if that file // has been manually deleted or moved since then. When the new file arrives here, we'll recover // the zombie meta data and we don't reset it on purpose. Actually, we consider that the meta data // has been *accidentaly* lost and that the user is attempting to recover it by putting back the // file where it was before. Of course the logical way would be to put back the file manually, but // experience proves that users are inconsistent! $this->load_meta(); } return true; } /** * Move the file to another location * * Also updates meta data in DB * * @param string Root type: 'user', 'group', 'collection' or 'absolute' * @param integer ID of the user, the group or the collection the file belongs to... * @param string Subpath for this file/folder, relative the associated root (no trailing slash) * @return boolean true on success, false on failure */ function move_to( $root_type, $root_ID, $rdfp_rel_path ) { global $FileRootCache; // echo "relpath= $rel_path "; $rdfp_rel_path = str_replace( '\\', '/', $rdfp_rel_path ); $adfp_posix_path = $FileRootCache->get_root_dir( $root_type, $root_ID ).$rdfp_rel_path; if( ! @rename( $this->_adfp_full_path, $adfp_posix_path ) ) { return false; } // Get Meta data (before we change name) (we may need to update it later): $this->load_meta(); // Memorize new filepath: $this->_FileRoot = & $FileRootCache->get_by_type_and_ID( $root_type, $root_ID ); $this->_rdfp_rel_path = $rdfp_rel_path; $this->_adfp_full_path = $adfp_posix_path; $this->_name = basename( $this->_adfp_full_path ); $this->_dir = dirname( $this->_adfp_full_path ).'/'; $this->_md5ID = md5( $this->_adfp_full_path ); if( $this->meta == 'loaded' ) { // We have meta data, we need to deal with it: $this->set( 'root_type', $this->_FileRoot->type ); $this->set( 'root_ID', $this->_FileRoot->in_type_ID ); $this->set( 'path', $this->_rdfp_rel_path ); // Record to DB: $this->dbupdate(); } else { // There might be some old meta data to *recycle* in the DB... // This can happen if there has been a file in the same location in the past and if that file // has been manually deleted or moved since then. When the new file arrives here, we'll recover // the zombie meta data and we don't reset it on purpose. Actually, we consider that the meta data // has been *accidentaly* lost and that the user is attempting to recover it by putting back the // file where it was before. Of course the logical way would be to put back the file manually, but // experience proves that users are inconsistent! $this->load_meta(); } return true; } /** * Copy this file to a new location * * Also copy meta data in Object * * @param File the target file (expected to not exist) * @return boolean true on success, false on failure */ function copy_to( & $dest_File ) { if( ! $this->exists() || $dest_File->exists() ) { return false; } // Note: what happens if someone else creates the destination file right at this moment here? if( ! @copy( $this->get_full_path(), $dest_File->get_full_path() ) ) { // Note: unlike rename() (at least on Windows), copy() will not fail if destination already exists // this is probably a permission problem return false; } // Initializes file properties (type, size, perms...) $dest_File->load_properties(); // Meta data...: if( $this->load_meta() ) { // We have source meta data, we need to copy it: // Try to load DB meta info for destination file: $dest_File->load_meta(); // Copy meta data: $dest_File->set( 'title', $this->title ); $dest_File->set( 'alt' , $this->alt ); $dest_File->set( 'desc' , $this->desc ); // Save meta data: $dest_File->dbsave(); } return true; } /** * Unlink/Delete the file or folder from disk. * * Also removes meta data from DB. * * @access public * @return boolean true on success, false on failure */ function unlink() { global $DB; $DB->begin(); // Check if there is meta data to be removed: if( $this->load_meta() ) { // remove meta data from DB: $this->dbdelete(); } if( $this->is_dir() ) { $unlinked = @rmdir( $this->_adfp_full_path ); } else { $unlinked = @unlink( $this->_adfp_full_path ); } if( !$unlinked ) { $DB->rollback(); return false; } $this->_exists = false; $DB->commit(); return true; } /** * Change file permissions on disk. * * @access public * @param string|NULL chmod (octal three-digit-format, eg '777'), uses {@link $Settings} for NULL * (fm_default_chmod_dir, fm_default_chmod_file) * @return mixed new permissions on success (octal format), false on failure */ function chmod( $chmod = NULL ) { if( $chmod === NULL ) { global $Settings; $chmod = $this->is_dir() ? $Settings->get( 'fm_default_chmod_dir' ) : $Settings->get( 'fm_default_chmod_file' ); } $chmod = octdec( $chmod ); if( @chmod( $this->_adfp_full_path, $chmod ) ) { clearstatcache(); // update current entry $this->_perms = fileperms( $this->_adfp_full_path ); return $this->_perms; } else { return false; } } /** * Insert object into DB based on previously recorded changes * * @return boolean true on success, false on failure */ function dbinsert( ) { global $Debuglog; if( $this->meta == 'unknown' ) { debug_die( 'cannot insert File if meta data has not been checked before' ); } if( ($this->ID != 0) || ($this->meta != 'notfound') ) { debug_die( 'Existing file object cannot be inserted!' ); } $Debuglog->add( 'Inserting meta data for new file into db', 'files' ); // Let's make sure the bare minimum gets saved to DB: $this->set_param( 'root_type', 'string', $this->_FileRoot->type ); $this->set_param( 'root_ID', 'integer', $this->_FileRoot->in_type_ID ); $this->set_param( 'path', 'string', $this->_rdfp_rel_path ); // Let parent do the insert: $r = parent::dbinsert(); // We can now consider the meta data has been loaded: $this->meta = 'loaded'; return $r; } /** * Update the DB based on previously recorded changes * * @return boolean true on success, false on failure / no changes */ function dbupdate( ) { if( $this->meta == 'unknown' ) { debug_die( 'cannot update File if meta data has not been checked before' ); } // Let parent do the update: return parent::dbupdate(); } /** * Get URL to view the file (either with viewer of with browser, etc...) */ function get_view_url() { global $htsrv_url; // Get root code $root_ID = $this->_FileRoot->ID; if( $this->is_dir() ) { // Directory // fp>> Note: we MUST NOT clear mode, especially when mode=upload, or else the IMG button disappears when entering a subdir return regenerate_url( 'root,path', 'root='.$root_ID.'&path='.$this->get_rdfs_rel_path() ); } else { // File if( !isset( $this->Filetype->viewtype ) ) { return NULL; } switch( $this->Filetype->viewtype ) { case 'image': return $htsrv_url.'viewfile.php?root='.$root_ID.'&path='.$this->_rdfp_rel_path.'&viewtype=image'; case 'text': return $htsrv_url.'viewfile.php?root='.$root_ID.'&path='.$this->_rdfp_rel_path.'&viewtype=text'; case 'download': // will NOT open a popup and will insert a Content-disposition: attachment; header return $htsrv_url.'getfile.php?root='.$root_ID.'&path='.$this->_rdfp_rel_path; case 'browser': // will open a popup case 'external': // will NOT open a popup default: return $this->get_url(); } } } /** * Get Link to view the file (either with viewer of with browser, etc...) */ function get_view_link( $text = NULL, $title = NULL, $no_access_text = NULL ) { if( is_null( $text ) ) { // Use file root+relpath+name by default $text = $this->get_root_and_rel_path(); } if( is_null( $title ) ) { // Default link title $this->load_meta(); $title = $this->title; } if( is_null( $no_access_text ) ) { // Default text when no access: $no_access_text = $text; } $url = $this->get_view_url(); if( empty($url) ) { return $no_access_text; } if( isset($this->Filetype) && in_array( $this->Filetype->viewtype, array( 'external', 'download' ) ) ) { // Link to open in the curent window return '<a href="'.$url.'" title="'.$title.'">'.$text.'</a>'; } else { // Link to open in a new window $target = 'evo_fm_'.$this->get_md5_ID(); // onclick: we unset target attrib and return the return value of pop_up_window() to make the browser not follow the regular href link (at least FF 1.5 needs the target reset) return '<a href="'.$url.'" target="'.$target.'" title="'.T_('Open in a new window').'" onclick="' ."this.target = ''; return pop_up_window( '$url', '$target', '" .'width='.( ( $width = $this->get_image_size( 'width' ) ) ? ( $width + 100 ) : 800 ).',' .'height='.( ( $height = $this->get_image_size( 'height' ) ) ? ( $height + 150 ) : 800 ).',' ."scrollbars=yes,status=yes,resizable=yes' );" .'">'.$text.'</a>'; } } /** * Template function. Display link to edit file. * * @param integer ID of item to link to => will open the FM in link mode * @param string link text * @param string link title * @param string text to display if access denied * @param string page url for the edit action */ function edit_link( $link_itm_ID = NULL, $text = NULL, $title = NULL, $no_access_text = NULL, $actionurl = 'admin.php?ctrl=files' ) { if( is_null( $text ) ) { // Use file root+relpath+name by default $text = $this->get_root_and_rel_path(); } if( is_null( $title ) ) { // Default link title $this->load_meta(); $title = $this->title; } if( is_null( $no_access_text ) ) { // Default text when no access: $no_access_text = $text; } if( $this->is_dir() ) { $rdfp_path = $this->_rdfp_rel_path; } else { $rdfp_path = dirname( $this->_rdfp_rel_path ); } $url_params = 'root='.$this->_FileRoot->ID.'&path='.$rdfp_path.'/'; if( ! is_null($link_itm_ID) ) { // We want to open the filemanager in link mode: $url_params .= '&fm_mode=link_item&item_ID='.$link_itm_ID; } $url = url_add_param( $actionurl, $url_params ); return '<a href="'.$url.'" title="'.$title.'">'.$text.'</a>'; } } ?>
© 2017 -
ZeroByte.ID
.