Skip to content
Browse files

Source code uploaded for open sourcing

  • Loading branch information...
0 parents commit 57e8e86ec9941aa1425bebe9800b47bb19c0b5bd @chandrashekharshaw committed
Showing with 9,053 additions and 0 deletions.
  1. +1 −0 Apache-LICENSE.txt
  2. +74 −0 README
  3. +112 −0 install_Linux.sh
  4. +40 −0 install_Mac.sh
  5. +20 −0 mysql_schema.sh
  6. +139 −0 schema/schema.sql
  7. +290 −0 src/assist/Auth.class
  8. +43 −0 src/assist/Connection.php
  9. +285 −0 src/assist/PageProperties.class
  10. +121 −0 src/assist/common/Conf.php
  11. +565 −0 src/assist/common/DbRegistry.php
  12. +131 −0 src/assist/common/Helpers.php
  13. +105 −0 src/assist/common/Logger.php
  14. +894 −0 src/assist/common/MVC.php
  15. +35 −0 src/assist/common/init.php
  16. +51 −0 src/assist/controllers/ApplicationController.php
  17. +82 −0 src/assist/controllers/NavigationController.php
  18. +57 −0 src/assist/db.inc
  19. +47 −0 src/assist/globals.inc
  20. +30 −0 src/assist/include.inc
  21. +20 −0 src/assist/layouts/blank.phtml
  22. +200 −0 src/assist/layouts/default.phtml
  23. BIN src/assist/lib/.DS_Store
  24. +63 −0 src/assist/lib/Connection.php
  25. BIN src/assist/lib/model/.DS_Store
  26. +75 −0 src/assist/lib/model/calendar.php
  27. +1,033 −0 src/assist/lib/model/calendarConfig.php
  28. +26 −0 src/assist/prepend.php
  29. +78 −0 src/assist/views/calendar/addedit.phtml
  30. +209 −0 src/assist/views/calendar/addedittime.phtml
  31. +267 −0 src/assist/views/calendar/calendar.phtml
  32. +215 −0 src/assist/views/calendar/list.phtml
  33. +204 −0 src/assist/views/calendar/ticketlog.phtml
  34. +45 −0 src/assist/views/shared/_messages.phtml
  35. +23 −0 src/assist/views/shared/_navigation.phtml
  36. +66 −0 src/assist/views/shared/_pagination.phtml
  37. +289 −0 src/calendar.php
  38. +19 −0 src/conf/calendar_database.ini
  39. +6 −0 src/conf/setting.ini
  40. +59 −0 src/css/buttons.css
  41. BIN src/css/calendar/active-bg.gif
  42. BIN src/css/calendar/dark-bg.gif
  43. BIN src/css/calendar/hover-bg.gif
  44. BIN src/css/calendar/menuarrow.gif
  45. BIN src/css/calendar/normal-bg.gif
  46. +102 −0 src/css/calendar/opsdb.css
  47. BIN src/css/calendar/rowhover-bg.gif
  48. BIN src/css/calendar/status-bg.gif
  49. +236 −0 src/css/calendar/theme.css
  50. BIN src/css/calendar/title-bg.gif
  51. BIN src/css/calendar/today-bg.gif
  52. +105 −0 src/css/dashboard.css
  53. +484 −0 src/css/menu.css
  54. +721 −0 src/css/panchang.css
  55. +337 −0 src/css/toolbar.css
  56. +395 −0 src/group_mgmt.php
  57. +130 −0 src/header.php
  58. BIN src/images/add.png
  59. BIN src/images/arrow.gif
  60. BIN src/images/arrow_left.png
  61. BIN src/images/arrow_right.png
  62. BIN src/images/bottom_left.gif
  63. BIN src/images/bottom_right.gif
  64. BIN src/images/busybar_1.gif
  65. BIN src/images/buttons/bt_next.gif
  66. BIN src/images/buttons/bt_prev.gif
  67. BIN src/images/buttons/bt_search.gif
  68. BIN src/images/buttons/button_left.gif
  69. BIN src/images/buttons/button_left_off.gif
  70. BIN src/images/buttons/button_right_off_wide.gif
  71. BIN src/images/buttons/button_right_wide.gif
  72. BIN src/images/calendar_add.png
  73. BIN src/images/calendar_edit.png
  74. BIN src/images/clock_edit.png
  75. BIN src/images/comment.png
  76. BIN src/images/comments_add.png
  77. BIN src/images/content_tab_bg.gif
  78. BIN src/images/content_tab_left_off.gif
  79. BIN src/images/content_tab_left_on.gif
  80. BIN src/images/content_tab_right_off.gif
  81. BIN src/images/content_tab_right_on.gif
  82. BIN src/images/cross.png
  83. BIN src/images/delete.png
  84. BIN src/images/down_arrow.gif
  85. BIN src/images/down_arrow.png
  86. BIN src/images/icons/bt_graph.gif
  87. BIN src/images/icons/flag_orange.gif
  88. BIN src/images/icons/flag_red.gif
  89. BIN src/images/icons/icon_active.gif
  90. BIN src/images/icons/icon_alert.gif
  91. BIN src/images/icons/icon_complete.gif
  92. BIN src/images/icons/icon_copy.gif
  93. BIN src/images/icons/icon_delete.gif
  94. BIN src/images/icons/icon_delete_disabled.gif
  95. BIN src/images/icons/icon_down.gif
  96. BIN src/images/icons/icon_edit.gif
  97. BIN src/images/icons/icon_edit_disabled.gif
  98. BIN src/images/icons/icon_inactive.gif
  99. BIN src/images/icons/icon_incomplete.gif
  100. BIN src/images/icons/icon_info.gif
  101. BIN src/images/icons/icon_loading.gif
  102. BIN src/images/icons/icon_mail.gif
  103. BIN src/images/icons/icon_minus.gif
  104. BIN src/images/icons/icon_mobile.gif
  105. BIN src/images/icons/icon_network.gif
  106. BIN src/images/icons/icon_new.gif
  107. BIN src/images/icons/icon_paste.gif
  108. BIN src/images/icons/icon_plus.gif
  109. BIN src/images/icons/icon_popup.gif
  110. BIN src/images/icons/icon_popup_light.gif
  111. BIN src/images/icons/icon_touched.gif
  112. BIN src/images/icons/icon_untouched.gif
  113. BIN src/images/icons/icon_up.gif
  114. BIN src/images/icons/icon_verified.gif
  115. BIN src/images/icons/report_disk.png
  116. BIN src/images/icons/server_link.png
  117. BIN src/images/icons/user.png
  118. BIN src/images/icons/user_green.png
  119. BIN src/images/icons/zoom_in.png
  120. BIN src/images/info.png
  121. BIN src/images/logo.png
  122. BIN src/images/lookback.png
  123. BIN src/images/main_0015.gif
  124. BIN src/images/map.gif
  125. BIN src/images/ops_tools_small.gif
  126. BIN src/images/page_edit.png
  127. BIN src/images/pdate.gif
  128. BIN src/images/play_arrow.gif
  129. BIN src/images/play_arrow.png
  130. BIN src/images/rc_bl.gif
  131. BIN src/images/rc_br.gif
  132. BIN src/images/rc_tl.gif
  133. BIN src/images/rc_tl_clean.gif
  134. BIN src/images/rc_tr.gif
  135. BIN src/images/rc_tr_clean.gif
  136. BIN src/images/rloading.gif
  137. BIN src/images/separator_120.gif
  138. BIN src/images/separator_50.gif
  139. BIN src/images/separator_75.gif
  140. BIN src/images/sort_down.gif
  141. BIN src/images/sort_up.gif
  142. BIN src/images/staging.png
  143. BIN src/images/status_offline.png
  144. BIN src/images/status_online.png
  145. BIN src/images/tab-left-off.gif
  146. BIN src/images/tab-left-off_purple.gif
  147. BIN src/images/tab-left-on.gif
  148. BIN src/images/tab-left-on_purple.gif
  149. BIN src/images/tab-quotebar.gif
  150. BIN src/images/tab-quotebar_purple.gif
  151. BIN src/images/tab-right-off-wide.gif
  152. BIN src/images/tab-right-off-wide_purple.gif
  153. BIN src/images/tab-right-on-wide.gif
  154. BIN src/images/tab-right-on-wide_purple.gif
  155. BIN src/images/tab-subnav-background.gif
  156. BIN src/images/tab-subnav-background_purple.gif
  157. BIN src/images/tab-subnav-separator.gif
  158. BIN src/images/tab-subnav-separator_purple.gif
  159. BIN src/images/tab_context.gif
  160. BIN src/images/tab_context_bottom.gif
  161. BIN src/images/tab_context_head.gif
  162. BIN src/images/tick.png
  163. BIN src/images/tick_in.png
  164. BIN src/images/top_left.gif
  165. BIN src/images/top_right.gif
  166. BIN src/images/unplug.gif
  167. BIN src/images/zoom_in.png
  168. +69 −0 src/index.php
  169. +128 −0 src/js/dynamic.js
  170. +127 −0 src/js/helper/calendar-en.js
  171. +200 −0 src/js/helper/calendar-setup.js
Sorry, we could not display the entire diff because it was too big.
1 Apache-LICENSE.txt
@@ -0,0 +1 @@
+Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
74 README
@@ -0,0 +1,74 @@
+ Panchang (People on Duty)
+ -------------------------
+ ~~~~~~ Installation Instruction ~~~~~~~
+
+The installation procedure depends on the base operating system:-
+
+ Linux(Fedora, CentOS, RHEL) System
+ ----------------------------------
+
+ If you have AMP stack (apache, mysql, php) running on your system then follow the
+ following steps:-
+
+ 1) Create a directory named "calendar" inside the apache root directory.
+ 2) Copy the content of "src" directory to newly created directory "calendar".
+ 3) Run the script mysql_schema.sh to create the required database schema.
+ $ ./mysql_schema.sh
+
+ Else if you want to install this package from scratch on fresh operating system
+ then start installing with these steps:-
+
+ 1) Run the script install.sh which will install and configure the AMP server then
+ install this package on proper position.
+ $ ./install_Linux.sh
+ 2) Run the script mysql_schema.sh to create the required database schema.
+ $ ./mysql_schema.sh
+
+
+ Mac OSX
+ -------
+
+ Mac OSX already comes with Apache installed and PHP bundled up with it. By default
+ both are inactive and require us to get them ready for business. This can be achieved
+ by following simple steps:
+
+ 1) Run the script install_Mac.sh which will set up the Apache server with PHP support.
+ $ ./install_Mac.sh
+
+ 2) Create a directory named "calendar" inside the apache root directory.
+
+ 3) Copy the content of "src" directory to newly created directory "calendar".
+
+ 4) Download the MySQL package for Mac OSX depending on the base machine from-
+ http://dev.mysql.com/downloads/mysql/5.1.html#macosx-dmg
+
+ 5) Install everything in the package in this order: mysql, the startup item, the
+ preference pane. Run this command
+ export PATH=${PATH}:/usr/local/mysql/bin/
+
+ 6) Run the script mysql_schema.sh to create the required database schema.
+ $ ./mysql_schema.sh
+
+
+
+ Access Panchang by opening the link :
+
+ http://localhost/calendar/index.php or http://SERVERNAME/calendar/index.php
+ --------------------------------------------------------------------------------------
+
+ NOTE: 3rd party open source packages and codes which have been used to support this
+ package along with their download location :-
+
+ * Apache web server :http://httpd.apache.org/download.cgi
+ * PHP :http://in.php.net/distributions/
+ * MySQL :http://www.mysql.com/downloads/mysql/
+ * PEAR :http://pear.php.net/package/PEAR/download
+ * PEAR-DB :http://pear.php.net/package/DB/download
+ * DB_DataObject :http://pear.php.net/package/DB_DataObject/download
+ * YUI Library :http://developer.yahoo.com/yui/
+ * Jquery :http://code.jquery.com/jquery-1.7.1.js
+ * DHTML calendar JS :http://www.dynarch.com/projects/calendar/download/
+
+
+
+ ------------------------------------------------------------------------------------------
112 install_Linux.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+
+#//+---------------------------------------------------------------------------------------------------------------------------------+
+#// /
+#// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+#// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+#// file except in compliance with the License. You may obtain a copy of the License at /
+#// /
+#// http://www.apache.org/licenses/LICENSE-2.0 /
+#// /
+#// Unless required by applicable law or agreed to in writing, software distributed under /
+#// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+#// ANY KIND, either express or implied. See the License for the specific language governing /
+#// permissions and limitations under the License. See accompanying LICENSE file. /
+#// /
+#// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+#// /
+#//+---------------------------------------------------------------------------------------------------------------------------------+
+
+##### Download Mysql packages
+
+sudo wget --progress=bar --directory-prefix=/tmp/ ftp://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.5/MySQL-server-5.5.20-1.linux2.6.i386.rpm
+
+sudo wget --progress=bar --directory-prefix=/tmp/ http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.5/MySQL-client-5.5.20-1.linux2.6.i386.rpm
+
+sudo wget --progress=bar --directory-prefix=/tmp/ http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.5/MySQL-shared-5.5.20-1.linux2.6.i386.rpm
+
+##### Download apache package
+
+sudo wget --progress=bar --directory-prefix=/tmp/ http://ftp.wayne.edu/apache//httpd/httpd-2.2.21.tar.gz
+
+#### Downlaod PHP package
+
+sudo wget --progress=bar --directory-prefix=/tmp/ http://in.php.net/distributions/php-5.3.9.tar.gz
+
+pushd .
+
+cd /tmp/
+
+sudo rpm -ivh MySQL-client-5.5.20-1.linux2.6.i386.rpm MySQL-server-5.5.20-1.linux2.6.i386.rpm MySQL-shared-5.5.20-1.linux2.6.i386.rpm
+
+sudo mysql_install_db
+
+sudo /sbin/ldconfig
+
+cd /usr/local/
+
+sudo cp /tmp/httpd-2.2.21.tar.gz ./
+
+sudo tar -xzvf httpd-2.2.21.tar.gz
+
+cd httpd-2.2.21
+
+sudo ./configure --enable-so
+
+sudo make
+
+sudo make install
+
+cd /usr/local/
+
+sudo cp /tmp/php-5.3.9.tar.gz ./
+
+sudo tar -xzvf php-5.3.9.tar.gz
+
+cd php-5.3.9
+
+sudo ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql-dir=/usr/bin/mysql --with-pdo-mysql=mysqlnd
+
+sudo make
+
+sudo make install
+
+sudo cp php.ini-development /usr/local/lib/php.ini
+
+sudo sed "s/short_open_tag = Off/short_open_tag = On/" /usr/local/lib/php.ini>~/tmp
+
+sudo mv ~/tmp /usr/local/lib/php.ini
+
+sudo sed "s/display_errors/;display_errors/" /usr/local/lib/php.ini>~/tmp
+
+sudo mv ~/tmp /usr/local/lib/php.ini
+
+sudo sed "s/short_open_tag/;short_open_tag/" /usr/local/lib/php.ini>~/tmp
+
+sudo mv ~/tmp /usr/local/lib/php.ini
+
+sudo echo "display_errors = Off">>/usr/local/lib/php.ini
+
+sudo sed "s/#LoadModule php5_module/LoadModule php5_module/" /usr/local/apache2/conf/httpd.conf>~/tmp
+
+sudo mv ~/tmp /usr/local/apache2/conf/httpd.conf
+
+sudo sed "s/DirectoryIndex index.html/DirectoryIndex index.html index.php/" /usr/local/apache2/conf/httpd.conf>~/tmp
+
+sudo mv ~/tmp /usr/local/apache2/conf/httpd.conf
+
+sudo echo "AddType application/x-httpd-php .php .phtml">>/usr/local/apache2/conf/httpd.conf
+
+sudo echo "AddType application/x-httpd-php-source .phps">>/usr/local/apache2/conf/httpd.conf
+
+sudo /etc/init.d/mysql start
+
+sudo /usr/local/apache2/bin/apachectl start
+
+popd
+
+sudo mkdir /usr/local/apache2/htdocs/calendar
+
+sudo cp -R src/* /usr/local/apache2/htdocs/calendar/
+
+
40 install_Mac.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+#//+---------------------------------------------------------------------------------------------------------------------------------+
+#// /
+#// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+#// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+#// file except in compliance with the License. You may obtain a copy of the License at /
+#// /
+#// http://www.apache.org/licenses/LICENSE-2.0 /
+#// /
+#// Unless required by applicable law or agreed to in writing, software distributed under /
+#// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+#// ANY KIND, either express or implied. See the License for the specific language governing /
+#// permissions and limitations under the License. See accompanying LICENSE file. /
+#// /
+#// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+#// /
+#//+---------------------------------------------------------------------------------------------------------------------------------+
+
+sudo apachectl start
+
+sudo sed "s/#LoadModule php5_module/LoadModule php5_module/" /etc/apache2/httpd.conf>~/tmp
+
+sudo mv ~/tmp /etc/apache2/httpd.conf
+
+sudo sed "s/DocumentRoot/#DocumentRoot/" /etc/apache2/httpd.conf>~/tmp
+
+sudo mv ~/tmp /etc/apache2/httpd.conf
+
+sudo cp /etc/php.ini.default php.ini
+
+sudo chmod 666 /etc/php.ini
+
+sudo sed "s/DirectoryIndex index.html/DirectoryIndex index.html index.php/" /etc/apache2/httpd.conf>~/tmp
+
+sudo mv ~/tmp /etc/apache2/httpd.conf
+
+sudo apachectl restart
+
+
20 mysql_schema.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+#//+---------------------------------------------------------------------------------------------------------------------------------+
+#// /
+#// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+#// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+#// file except in compliance with the License. You may obtain a copy of the License at /
+#// /
+#// http://www.apache.org/licenses/LICENSE-2.0 /
+#// /
+#// Unless required by applicable law or agreed to in writing, software distributed under /
+#// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+#// ANY KIND, either express or implied. See the License for the specific language governing /
+#// permissions and limitations under the License. See accompanying LICENSE file. /
+#// /
+#// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+#// /
+#//+---------------------------------------------------------------------------------------------------------------------------------+
+
+mysql -u root <./schema/schema.sql
139 schema/schema.sql
@@ -0,0 +1,139 @@
+/*
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+*/
+
+/* Create database */
+CREATE DATABASE opencal;
+
+/* Create required tables */
+CREATE TABLE opencal.`user` (
+ `user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `username` varchar(80) NOT NULL DEFAULT '',
+ `name` varchar(64) NOT NULL DEFAULT '',
+ `email` varchar(30) DEFAULT NULL,
+ `c_time` int(10) unsigned NOT NULL DEFAULT '0',
+ `m_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `password` varchar(50) NOT NULL DEFAULT '',
+ PRIMARY KEY (`user_id`),
+ UNIQUE KEY `username` (`username`)
+) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=latin1;
+
+CREATE TABLE opencal.`groupUser` (
+ `gu_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(64) NOT NULL DEFAULT '',
+ `description` varchar(128) NOT NULL DEFAULT '',
+ `c_time` int(10) unsigned NOT NULL DEFAULT '0',
+ `m_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ PRIMARY KEY (`gu_id`),
+ KEY `name` (`name`)
+) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=latin1;
+
+CREATE TABLE opencal.`groupUser_user` (
+ `gu_id` int(10) unsigned NOT NULL DEFAULT '0',
+ `user_id` int(10) unsigned NOT NULL DEFAULT '0',
+ `e_time` int(10) unsigned NOT NULL DEFAULT '1735718400',
+ `s_time` int(10) unsigned NOT NULL DEFAULT '0',
+ `is_admin` tinyint(4) NOT NULL DEFAULT '0',
+ UNIQUE KEY `gu_id_2` (`gu_id`,`user_id`),
+ KEY `gu_id` (`gu_id`),
+ KEY `user_id` (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+
+CREATE TABLE opencal.`backupAssigneeConfig` (
+ `assignee_id` int(10) NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) NOT NULL DEFAULT '0',
+ `assign_time` tinyint(2) NOT NULL DEFAULT '0',
+ `c_time` int(10) NOT NULL DEFAULT '0',
+ `m_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `is_active` tinyint(1) DEFAULT '1',
+ `oncall_type` tinyint(1) NOT NULL DEFAULT '0',
+ `oncall_from` date NOT NULL DEFAULT '0000-00-00',
+ `oncall_to` date NOT NULL DEFAULT '0000-00-00',
+ `team_id` int(50) NOT NULL,
+ PRIMARY KEY (`assign_time`,`oncall_type`,`oncall_from`,`oncall_to`,`team_id`),
+ UNIQUE KEY `assignee_id` (`assignee_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE opencal.`dictionary` (
+ `dict_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(32) NOT NULL DEFAULT '',
+ `description` varchar(255) NOT NULL DEFAULT '',
+ `label` varchar(32) NOT NULL DEFAULT '',
+ `parent_id` int(10) unsigned NOT NULL DEFAULT '0',
+ `order_num` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`dict_id`),
+ UNIQUE KEY `name` (`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE opencal.`backupAssigneeTime` (
+ `assigneetime_id` int(10) NOT NULL AUTO_INCREMENT,
+ `timezone_id` int(10) NOT NULL DEFAULT '0',
+ `start_time` time NOT NULL DEFAULT '00:00:00',
+ `end_time` time NOT NULL DEFAULT '00:00:00',
+ `c_time` int(10) NOT NULL DEFAULT '0',
+ `m_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `escalation_manager` varchar(80) DEFAULT NULL,
+ PRIMARY KEY (`timezone_id`),
+ UNIQUE KEY `assignee_id` (`assigneetime_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE opencal.`calendarLock` (
+ `lock_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) NOT NULL DEFAULT '0',
+ `calendar_type` char(1) NOT NULL DEFAULT '',
+ `m_time` int(10) NOT NULL DEFAULT '0',
+ `is_finished` char(1) NOT NULL DEFAULT 'N',
+ PRIMARY KEY (`lock_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+CREATE TABLE opencal.`oncallConfig_log_2012` (
+ `log_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) NOT NULL DEFAULT '0',
+ `calendar_type` varchar(20) NOT NULL DEFAULT '',
+ `change_log` longtext,
+ `m_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `is_update` char(1) NOT NULL DEFAULT 'N',
+ PRIMARY KEY (`log_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+CREATE TABLE opencal.`team` (
+ `team_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `team_name` varchar(64) NOT NULL DEFAULT '',
+ `description` varchar(128) NOT NULL DEFAULT '',
+ `user_ilist` varchar(64) NOT NULL DEFAULT '',
+ `admin_ilist` varchar(64) NOT NULL DEFAULT '',
+ PRIMARY KEY (`team_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+/* Insert Required informations*/
+INSERT INTO opencal.`user` (`username`, `name`, `email`, `password`) VALUES('admin', 'admin', 'admin@yahoo-inc.com', 'f9d4049dd6a4dc35d40e5265954b2a46');
+INSERT INTO opencal.`groupUser` (`name`, `description`) VALUES('admin', 'admin group');
+INSERT INTO opencal.`groupUser_user` (`gu_id`, `user_id`, `is_admin`) VALUES(1001, 100001, 1);
+insert into opencal.dictionary values(16, 'US', 'United State', 'US', 590,0 );
+insert into opencal.dictionary values(17, 'IN', 'India', 'IN', 590,1 );
+insert into opencal.dictionary values(20, 'userGroupType', 'User Group Type', 'UGT', 0,2 );
+insert into opencal.dictionary values(62, 'userGroupType_ilist', 'ilist user groups', 'ilist' ,20,3);
+insert into opencal.dictionary values(590, 'timezone', 'timezone for subnets', 'timezone', 94, 4);
+
+/* Grant Permission */
+GRANT SELECT ON opencal.* TO 'readonly'@'127.0.0.1' IDENTIFIED BY 'readonly';
+GRANT SELECT ON opencal.* TO 'oncall_ro'@'127.0.0.1' IDENTIFIED BY 'on1406call';
+GRANT ALL PRIVILEGES ON opencal.* TO 'oncall_rw'@'127.0.0.1' IDENTIFIED BY 'on1406call';
+
290 src/assist/Auth.class
@@ -0,0 +1,290 @@
+<?php
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+
+DEFINE("__DEBUG", 1);
+
+Class Auth {
+
+ /**
+ * username (Yahoo! user ID)
+ * @access private
+ * @var string
+ */
+ public $username;
+
+ /**
+ * OpsDB PEAR connector
+ * @access private
+ * @var resource
+ */
+ protected $_db_ops;
+
+ // {{{ Auth()
+ // +-------------------------------------------------------------------------+
+ // | Auth(): constructor. Inits class variables. Allso checks to see if the |
+ // | user has set their preferences. If they didn't, it redirects them to |
+ // | the OpsDB preferances page. It does remember the ref page to it will |
+ // | bounce them back after. |
+ // | @param integer -- reference to OpsDB PEAR connector |
+ // | @param string -- Yahoo! user ID |
+ // +-------------------------------------------------------------------------+
+ function Auth(&$db_ops, $username="")
+ {
+ // set username :
+ $this->_db_ops = $db_ops;
+ $env_byuser = $username;
+
+ if (strlen(trim($username))) {
+ $this->username = $username;
+ } else {
+ $this->username = $env_byuser;
+ }
+ // username must be present :
+ if (!strlen($this->username)) {
+ die('Auth.class::Auth():' . __LINE__ . ': no username!');
+ }
+ } // eo constructor
+ // }}}
+
+ // +-------------------------------------------------------------------------+
+ // | public isGroupMember(): determines whether the user is a member of |
+ // | (opsdb) group. See 'OpsDB User Groups' for more info on groups. |
+ // | @param mix $group -- group id (int) or group name (string) |
+ // | @param boolean $check_e_time -- whether we should check for exp date |
+ // | @return boolean true is the user is a member of a groip |
+ // +-------------------------------------------------------------------------+
+ function isGroupMember($group, $check_e_time = true)
+ {
+ // check for expiration date if needed :
+ if ($check_e_time) {
+ $ands .= " AND guu.e_time > UNIX_TIMESTAMP(NOW())";
+ }
+ // get the result :
+ $query = "SELECT COUNT(*) FROM groupUser_user AS guu
+ LEFT JOIN groupUser AS gu ON (guu.gu_id = gu.gu_id)
+ LEFT JOIN user ON (guu.user_id = user.user_id)
+ WHERE guu.gu_id = " . $this->getGroupID($group) . " AND user.username = " .
+ $this->_db_ops->quote($this->username) . $ands;
+ $count =& $this->_db_ops->getOne($query);
+ // html_debug($query);
+ if (is_numeric($count) && $count == 1) {
+ return true;
+ } else {
+ return false;
+ }
+ } // eo isGroupMember() method
+
+ // +-------------------------------------------------------------------------+
+ // | public isGroupAdmin(): checks whether user is a group admin |
+ // | @param mix $group -- group id (int) or group name (string) |
+ // | @param boolean $check_e_time -- whether we should check for exp date |
+ // | @return boolean true is the user is an admin |
+ // +-------------------------------------------------------------------------+
+ function isGroupAdmin($group, $check_e_time = true)
+ {
+ // check for expiration date if needed :
+ if ($check_e_time) {
+ $ands .= " AND guu.e_time > UNIX_TIMESTAMP(NOW())";
+ }
+ $query = "SELECT guu.is_admin FROM groupUser_user AS guu
+ LEFT JOIN user ON (guu.user_id = user.user_id)
+ WHERE guu.gu_id = " . $this->getGroupID($group) . " AND user.username = " .
+ $this->_db_ops->quote($this->username) . $ands;
+ $is_admin = $this->_db_ops->getOne($query);
+ // html_debug($query);
+ if (is_numeric($is_admin) && $is_admin == 1) {
+ return true;
+ } else {
+ return false;
+ }
+ } // eo isGroupAdmin() method
+
+ // +-------------------------------------------------------------------------+
+ // | public isGroupOwner(): checks whether user is a group owner |
+ // | @param mix $group -- group id (int) or group name (string) |
+ // | @return boolean true is the user is a group owner |
+ // +-------------------------------------------------------------------------+
+ function isGroupOwner($group)
+ {
+ $query = "SELECT user.username FROM groupUser AS gu
+ LEFT JOIN user ON (gu.user_id = user.user_id) WHERE gu_id = " . $this->getGroupID($group);
+ $group_owner = $this->_db_ops->getOne($query);
+ // html_debug($query);
+ if (strlen(trim($group_owner)) && $group_owner == $this->username) {
+ return true;
+ } else {
+ return false;
+ }
+ } // eo isGroupOwner() method
+
+ // +-------------------------------------------------------------------------+
+ // | public isSuperuser(): checks whether user is a 'superuser', i.e. he |
+ // | belongs to at least one administrative group listed below. |
+ // | @return boolean true is the user is a superuser, false otherwise |
+ // +-------------------------------------------------------------------------+
+ function isSuperuser()
+ {
+ $super_groups = array("opsdb_ynoc", "opsdb_admins");
+ foreach ($super_groups as $super_group) {
+ if ($this->isGroupMember($super_group)) {
+ return true;
+ }
+ }
+ return false;
+ } // eo isSuperuser() method
+
+ // +-------------------------------------------------------------------------+
+ // | public getGroupID() : gets user group ID based on user group name |
+ // | @param mix $group -- group id (int) or group name (string) |
+ // | @return integer group id, 0 if group doesn't exist |
+ // +-------------------------------------------------------------------------+
+ function getGroupID($group)
+ {
+ // it's NOT a static method, check that username was inited :
+ if (!strlen($this->username)) {
+ exit("Auth::isGroupMember():" . __FILE__ . ":" . __LINE__ . ": no username!");
+ }
+ // cut off '@yahoo-inc.com' if needed :
+ if (strstr($group, "@yahoo-inc.com")) {
+ $group = str_replace("@yahoo-inc.com", "", $group);
+ }
+ // get group id by group name if needed :
+ if (!is_numeric($group)) {
+ $gu_id = $this->_db_ops->getOne("SELECT gu_id FROM groupUser WHERE name = " . $this->_db_ops->quote($group));
+ } else {
+ $gu_id = $group;
+ }
+ // make sure we have group id :
+ if (is_numeric($gu_id)) {
+ return $gu_id;
+ } else {
+ return 0;
+ }
+ } // eo getGroupID() method
+
+ // +-------------------------------------------------------------------------+
+ // | public getUserID() : gets user ID based on username |
+ // | @param mix $user -- user id (int) or user name (string) |
+ // | @return integer user id, 0 if user doesn't exist |
+ // +-------------------------------------------------------------------------+
+ function getUserID($user, $status=FALSE)
+ {
+ // it's NOT a static method, check that username was inited :
+ if (!strlen($this->username)) {
+ exit("Auth::isGroupMember():" . __FILE__ . ":" . __LINE__ . ": no username!");
+ }
+ // cut off '@yahoo-inc.com' if needed :
+ if (strstr($user, "@yahoo-inc.com")) {
+ $user = str_replace("@yahoo-inc.com", "", $user);
+ }
+ if($status) {
+ // get user id by user name if needed :
+ if (!is_numeric($user)) {
+ $user_id = $this->_db_ops->getRow("SELECT user_id, is_active FROM user WHERE username = " . $this->_db_ops->quote($user));
+ } else {
+ $user_id = $this->_db_ops->getRow("SELECT user_id, is_active FROM user WHERE user_id = " . $this->_db_ops->quote($user));
+ }
+ // make sure we have user id :
+ if (is_numeric($user_id['user_id'])) {
+ return $user_id;
+ } else {
+ return 0;
+ }
+ } else {
+ // get user id by user name if needed :
+ if (!is_numeric($user)) {
+ $user_id = $this->_db_ops->getOne("SELECT user_id FROM user WHERE username = " . $this->_db_ops->quote($user));
+ } else {
+ $user_id = $user;
+ }
+ // make sure we have user id :
+ if (is_numeric($user_id)) {
+ return $user_id;
+ } else {
+ return 0;
+ }
+ }
+ } // eo getUserID () method
+
+ // +-------------------------------------------------------------------------+
+ // | public getGroupName() : Gets the group name from a group id. Returns |
+ // | '' if it doesn't exist. |
+ // +-------------------------------------------------------------------------+
+ function getGroupName($group_id)
+ {
+ $name = '';
+ // get group id by group name if needed :
+ if (is_numeric($group_id)) {
+ $name = $this->_db_ops->getOne("SELECT name FROM groupUser WHERE gu_id = " . $this->_db_ops->quotesmart($group_id));
+ }
+ return $name;
+ } // eo getGroupName() method
+
+ // +-------------------------------------------------------------------------+
+ // | public getUserName() : Gets username from a user_id. |
+ // | param: |
+ // | $user_id : numeric user_id from OpsDB |
+ // | $status : boolean. true if status of user is also required |
+ // | Returns |
+ // | (string) username ('' if it doesn't exist) if $status=FALSE |
+ // | array('username'=>username, 'is_active'=>status) if $status=TRUE |
+ // +-------------------------------------------------------------------------+
+ function getUserName($user_id, $status=FALSE)
+ {
+ if($status) {
+ $name = array();
+ if (is_numeric($user_id)) {
+ $name = $this->_db_ops->getRow("SELECT username, is_active FROM user WHERE user_id = " . $this->_db_ops->quotesmart($user_id));
+ }
+ return $name;
+ } else {
+ $name = '';
+ // get group id by group name if needed :
+ if (is_numeric($user_id)) {
+ $name = $this->_db_ops->getOne("SELECT username FROM user WHERE user_id = " . $this->_db_ops->quotesmart($user_id));
+ }
+ return $name;
+ }
+ } // eo getGroupName() method
+
+ /**
+ * &getUserRecord() get user's record including role
+ * @param str username
+ * @return int ref to the array (user record) if found, false otherwise
+ */
+ function &getUserRecord($username = NULL) {
+ if (is_null($username)) {
+ $username = $this->username;
+ }
+ $usr_rec =& $this->_db_ops->getRow(
+ "select user.username, user.name, user.email from " .
+ "user where user.username =" .
+ $this->_db_ops->quote($username));
+ if ($this->_db_ops->isError($usr_rec)) {
+ return $usr_rec;
+ } else {
+ return false;
+ }
+ } // eo getUserRecord() function
+
+ public function setDB(&$db) {
+ $this->_db_ops = $db;
+ }
+} // eo Auth() class
+
+?>
43 src/assist/Connection.php
@@ -0,0 +1,43 @@
+<?php
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+
+class CalConnection extends MyDB {
+ static $default;
+ /**
+ * @return db connection parameter
+ */
+ public static function getDSN($prefix) {
+ $host = Conf::get($prefix.'_host', 'db', 'dsn');
+ $db = Conf::get($prefix.'_db', 'db', 'dsn');
+ $user = Conf::get($prefix.'_user', 'db', 'dsn');
+ $pass = Conf::get($prefix.'_pwd', 'db', 'dsn');
+ $port = Conf::get($prefix.'_port', 'db', 'dsn');
+ $dsn = "mysql://".$user;
+ $dsn.=trim($pass)!=''?(":$pass"):'';
+ $dsn.= trim($host)!=''?("@".$host):'@localhost';
+ $dsn.= (trim($port)!='')?":$port":'';
+ $dsn.= (trim($db)!='')?"/$db":'';
+ return $dsn;
+ }
+ public function getKeyDBValue($key) {
+ $dsn = Conf::get($key, 'db', 'dsn');
+ return $dsn;
+ }
+
+}
+?>
285 src/assist/PageProperties.class
@@ -0,0 +1,285 @@
+<?php
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+
+class PageProperties {
+
+ /**
+ * _toolbar - The toolbar array, containing all the sub tabs too
+ * @access private
+ * @var array (x3)
+ */
+ var $_toolbar;
+ /**
+ * _js - Array that contains all the JS file names to be included in this file
+ * @access private
+ * @var array
+ */
+ var $_js;
+
+ /**
+ * _css - Array that contains all the CSS file names to be included in this file.
+ * @access private
+ * @var array
+ */
+ var $_css;
+
+ // {{{ PageProperties()
+ /** +-------------------------------------------------------------------------+
+ * | PageProperties(): constructor. Inits class variables. |
+ * +-------------------------------------------------------------------------+
+ */
+ function PageProperties($pageTitle = '',$auth=null) {
+ if($auth==NULL) {
+ $auth = $_SESSION['auth'];
+ }
+ $settings=parse_ini_file('conf/setting.ini', true);
+ $dbh = Connection::cal_ro();
+ $obj = new calendarConfig();
+ $this->_isTeammanager = $obj->isMember($auth->username, $dbh, $settings['manager_group']);
+ $this->_mailGroup = $settings['mail_group'];
+ $this->_bugURL = $settings['bug_url'];
+ $this->_stats = $settings['bug_url'];
+ $this->_byUser = $auth->username;
+ $this->_pageTitle = $pageTitle;
+ $this->_team = "Calendar";
+ $this->_css = array (
+ 'css/panchang.css',
+ 'css/buttons.css',
+ 'css/toolbar.css'
+ );
+
+ $this->_js = array (
+ 'js/panchang.js',
+ 'js/util.js'
+ );
+
+ if($this->_isTeammanager){
+ $this->_toolbar = array(
+ // Home Tab
+ array (
+ 'name' => 'Oncall Calendar',
+ 'link' => 'calendar.php',
+ 'tooltip' => 'Calendar',
+ 'prefix' => 'calendar_',
+ 'mouseon' => '',
+ 'mouseoff'=> '',
+ ),
+
+ array (
+ 'name' => 'Admin Section',
+ 'link' => 'team_mgmt.php',
+ 'tooltip' => 'Admin',
+ 'prefix' => 'admin_',
+ 'mouseon' => '',
+ 'mouseoff'=> '',
+ )
+
+ );
+ } // End main toolbar array
+ else{
+ $this->_toolbar = array(
+ // Home Tab
+ array (
+ 'name' => 'Oncall Calendar',
+ 'link' => 'calendar.php',
+ 'tooltip' => 'Calendar',
+ 'prefix' => 'calendar_',
+ 'mouseon' => '',
+ 'mouseoff'=> '',
+ )
+ );
+
+
+ }
+}
+ // }}} end of __construct
+
+ // +-------------------------------------------------------------------------+
+ // | pritnToolbar() Prints the HTML for the toolbar including the logo |
+ // +-------------------------------------------------------------------------+
+ function printToolbar($showLogo=true,$smenu='',$action=''){
+ // Print the table container and the div tag for the main tabs
+?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td><div id="yopsnav">
+ <ul><?php
+
+ $self = getenv("PHP_SELF");
+ foreach ($this->_toolbar as $tab){
+ if( !is_null($tab) ) {
+ if(@strpos($self,$tab["prefix"]) || ($smenu!='' && strlen(strstr($tab["prefix"],$smenu)))){
+ $selected = $tab;
+ echo "\n ".$this->getTabHtml($tab, "selected",$action);
+ } else {
+
+ echo "\n ".$this->getTabHtml($tab);
+ }
+ }
+ }
+ ?>
+ </ul>
+ </div>
+ <?php
+ if($smenu == 'sservice') {
+ $this->printDropTabs($selected);
+ }
+ //$this->getSearchBar();
+
+ // Print the end of the table container
+ ?>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<!-- End Toolbar -->
+ <?php
+ }
+
+ // +-------------------------------------------------------------------------+
+ // | PageProperties(): constructor. Inits class variables. |
+ // +-------------------------------------------------------------------------+
+ function addToHeader($filetype, $path){
+ if($filetype == "js"){
+ array_push($this->_js, $path);
+ } else if($filetype == "css"){
+ array_push($this->_css, $path);
+ } else {
+
+ }
+ }
+
+ // +-------------------------------------------------------------------------+
+ // | public printHeader(): Prints the header, including the JS and CSS file
+ // | includes, sets onload JS function.
+ // | @param string - onload JS function name if any
+ // +-------------------------------------------------------------------------+
+ function printHeader($onload = "", $unload = "", $classname = ""){
+ if (stristr(getenv("HTTP_USER_AGENT"), "MSIE") === false) {
+ ?><html><?
+ } else {
+ ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml">
+ <?php
+ }
+ ?>
+ <head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+ <title><?php echo _pageTitle." -- ".$this->_pageTitle ?></title><?
+ foreach($this->_css as $css){
+ echo "<link href=\"$css\" rel=\"stylesheet\" type=\"text/css\" />\n";
+ }
+ foreach($this->_js as $js){
+ echo "<script type=\"text/javascript\" src=\"$js\"></script>\n";
+ }
+ ?>
+ </head>
+ <body class="yui-skin-sam" leftmargin="0" topmargin="0" rightmargin="0" marginwidth="0" marginheight="0"
+ onload="commonInit();<?php echo $onload ?>" onunload="<?php echo $unload ?>" class="<?php echo $classname?>"><div class="popper" id="popup" style="top:-1;left:-1;"></div><?
+ }
+
+
+
+
+ function printDropTabs($tab){
+ $subtab = $tab['submenu'];
+ $str_subtab="<div id='tab_service' class='yuimenubar'style='width:100%;position:static;'>";
+ $str_subtab.="<div class='bd'>";
+ $str_subtab.="<ul class='first-of-type'>";
+ foreach($subtab as $item) {
+ $str_subtab.="<li class='yuimenubaritem'>";
+ $str_subtab.="<a class='yuimenubaritemlabel'>".$item[name]."</a>";
+ $subdroptab = $item['submenu'];
+ $str_subtab.="<div id='' class='yuimenu'>";
+ $str_subtab.="<div class=bd><ul class='first-of-type'>";
+ foreach($subdroptab as $subitem) {
+ $str_subtab.="<li class='yuimenuitem'><a class='yuimenuitemlabel' href='".$subitem[link]."' >".$subitem[name]."</a>";
+ }
+ $str_subtab.="</ul></div></div></li>";
+ }
+ $str_subtab.="</ul></div></div>";
+ print $str_subtab;
+ ?>
+ <script language='javascript'>
+ function cal_menu_init(p_oEvent) {
+ // Instantiate and render the menu bar
+ var oMenuBar = new YAHOO.widget.MenuBar("tab_service", { autosubmenudisplay:true, showdelay:250, hidedelay:750, lazyload:true });
+ oMenuBar.render();
+ }
+</script>
+ <?php
+ }
+
+
+
+ // }}}
+
+ // {{{ getTabHtml()
+ // +-------------------------------------------------------------------------+
+ // | getTabHtml() returns the HTML code for the given tab |
+ // +-------------------------------------------------------------------------+
+ function getTabHtml($tab, $selected = "",$action=''){
+ // highlight current subtab depending on URL
+ if ($selected == '' && strlen(trim($tab[link])) > 0) {
+ if (strpos(getenv('PHP_SELF'), $tab['link'])) {
+ $selected = 'selected';
+ }
+ }
+
+ return "<li class=\"$selected\">" . (strlen(trim($tab[link])) ? "<a href=\"{$tab['link']}\" " . $this->getAttList($tab) . ">{$tab['name']}</a>" : "<a style=\"text-decoration:none\" title=\"{$tab['tooltip']}\">{$tab['name']}</a>") . (strlen(trim($tab['new'])) ? "<img alt=\"NEW\" src=\"images/icons/icon_new.gif\">" : "") . "</li>";
+ }
+ // }}}
+
+ // {{{ getAttList()
+ /**
+ * Adds <A> attributes based on $this->_toolbar structure
+ * Attributes understood as of now:
+ * - target : target="$v"
+ * - tooltip : title="$v"
+ *
+ * @param array tab/subtab/contextmenu
+ * @return string attribute(s) 'name1=value1 name2=value2 ...' list
+ */
+ function getAttList($tab) {
+ $attList = '';
+
+ foreach ($tab as $k => $v) {
+ if (strlen(trim($v)) > 0) {
+ switch ($k) {
+ case 'target':
+ $attList .= " $k=\"$v\"";
+
+ break;
+
+ case 'tooltip':
+ $attList .= " title=\"$v\"";
+
+ break;
+ }
+ }
+ }
+
+ return trim($attList);
+ }
+ // }}}
+
+
+
+
+}
+?>
121 src/assist/common/Conf.php
@@ -0,0 +1,121 @@
+<?php
+
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+
+
+require_once 'Helpers.php';
+
+/**
+ * Configuration registry
+ *
+ * INI files registry
+ *
+ * Usage example:
+ * <code>
+ * <?php
+ * // init your config files somewhere in your code
+ * Conf::init('/home/y/conf/app/config.ini', 'file1', 3600);
+ * // ...
+ * // use settings from your files anywhere in your code
+ * $master_host = Conf::$FILE['file1']['hosts']['master'];
+ *
+ * // OR, default config, when you only need to use one config file
+ * // in your application
+ * Conf::init('/home/y/conf/app/config.ini');
+ * $master_host = Conf::$CONFIG['hosts']['master'];
+ *
+ * // or
+ * Conf::get('host');
+ * Conf::get('host', 'database', 'development');
+ * ?>
+ * </code>
+ */
+class Conf {
+ /**
+ * hash of parsed INI files
+ * @var array
+ */
+ static $FILE;
+
+ /**
+ * default configuration file (when no config name specified)
+ * @var array
+ */
+ static $CONFIG;
+
+ /**
+ * Initializes INI file
+ * @param string full path to configuration (INI) file
+ * @param string name reference, once config file is initialized
+ * @param int number of seconds to cache initialized config file, default is 5min
+ */
+ static function init($filename, $name=null, $ttl=300) {
+ if(!$name)
+ $name = 'default';
+
+ $parsed_file = parse_ini_file($filename, true);
+ self::$FILE[$name] = $parsed_file;
+
+ if($name == 'default')
+ self::$CONFIG = $parsed_file;
+
+ }
+
+ /**
+ * configuration setting helper
+ *
+ * shorter alternative to Conf::$FILE[name][environment][setting], Conf::get('setting') or
+ * Conf::get('setting', 'conf_name'). When no configuration name specified self::$CONFIG (default
+ * config file is used). When no environment name specified - current environment is used
+ * when setting value begins with "keydb://", e.g. "keydb://ops.opsdb_master" ysecure_get_key will
+ * be called
+ *
+ * @param string setting name
+ * @param string config file name
+ * @param string environment name
+ *
+ * @return string setting value
+ */
+ public static function get($setting, $conf=null, $env=null)
+ {
+ if (!$env) {
+ $env = env();
+ }
+
+
+ /*
+ * Error handling issues, this section of code threw lots of notices
+ * it now does some checking before attempting to blindly access variables
+ */
+ //$v = !$conf ? self::$CONFIG[$env][$setting] : Conf::$FILE[$conf][$env][$setting];
+ $v = '';
+ if (!$conf) {
+ $v = self::$CONFIG[$env][$setting];
+ } else {
+
+ //receiving errors about undefined index
+ if (array_key_exists($env, Conf::$FILE[$conf])) {
+ $v = Conf::$FILE[$conf][$env][$setting];
+ }
+ }
+
+ return $v;
+ }
+}
+
+
565 src/assist/common/DbRegistry.php
@@ -0,0 +1,565 @@
+<?php
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+
+require_once 'Logger.php';
+require_once 'Conf.php';
+
+
+class MyDB
+{/*{{{*/
+
+
+ /*
+ * These constants are intended to standardize the indexes in arrays
+ * that are parsed configurations. This allows external classes to
+ * refer to these indexes in the same way that the internals of this class
+ * refers to them.
+ */
+ const DSN = 'dsn';
+ const USERNAME = 'username';
+ const PASSWORD = 'password';
+ const HOST = 'host';
+ const PORT = 'port';
+ const DATABASE = 'database';
+
+
+ /**
+ * @var array database connections hash
+ */
+ static $connections;
+
+ /**
+ * create connection instance (PDO)
+ * @param string
+ * @param string
+ * @param string
+ * @return object
+ */
+ static function connect($dsn, $username, $password=null) {/*{{{*/
+ $key = md5("pdo-$dsn-$username-$password");
+
+ if(isset(self::$connections[$key]))
+ return self::$connections[$key];
+
+ $dbh = new OpsPDO($dsn, $username, $password);
+ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ self::$connections[$key] = $dbh;
+
+ return $dbh;
+ }/*}}}*/
+
+ /**
+ * create connection instance (PEAR)
+ * @param string
+ * @return object
+ */
+ static function connect_legacy($dsn) {/*{{{*/
+ $key = md5("pear-$dsn");
+
+ if(isset(self::$connections[$key]))
+ return self::$connections[$key];
+
+ $dbh = DB::connect($dsn);
+
+ if(DB::isError($dbh)) {
+
+ /*
+ * strip the password out of the dsn before attempting to
+ * output an error message
+ */
+ $config = self::parseDsn($dsn);
+
+ throw new Exception('Unable to connect to database ('
+ . $config[self::DSN] . ') with username (' . $config[self::USERNAME] . ')');
+ }
+
+ $dbh->setFetchMode(DB_FETCHMODE_ASSOC);
+ self::$connections[$key] = $dbh;
+
+
+ return $dbh;
+ }/*}}}*/
+
+ /**
+ * database connection (PDO)
+ * get DSN from ['db'][$name] and create connection instance
+ * @param string DSN key name in the config file
+ * @return object
+ */
+ function get($name) {/*{{{*/
+ // when PDO throws an exception it includes username and password in clear text
+ // we want to avoid this, so catch and throw exception again
+ try {
+ list($dsn, $username, $password) = self::get_dsn_username_password($name);
+ return self::connect($dsn, $username, $password);
+ }
+ catch(PDOException $e) {
+ throw new PDOException($e->getMessage());
+ }
+ }/*}}}*/
+
+ /**
+ * database connection (PEAR)
+ * get DSN from ['db'][$name] and create connection instance
+ * @param string key name in the config file
+ * @return object
+ */
+ function get_legacy($name) {/*{{{*/
+ return self::connect_legacy(self::get_dsn($name));
+ }/*}}}*/
+
+ /**
+ * parse PEAR style DSN string
+ * @param string DSN in PEAR format
+ * @return array (PDO style) $dsn, $username, $password
+ */
+ public static function get_dsn_username_password($name)
+ {/*{{{*/
+
+ $parsed = self::parseDsn(self::get_dsn($name));
+
+ return array(
+ $parsed[self::DSN],
+ $parsed[self::USERNAME],
+ $parsed[self::PASSWORD],
+ );
+
+ }/*}}}*/
+
+ /**
+ * Parse dsn, username, password from string
+ *
+ * This method also returns the parts of the dsn individually such as
+ * the host, port, and database. See the return value for more description.
+ *
+ * Expected string
+ * mysql://username:password@host:port/database
+ *
+ * port and password are optional
+ *
+ * @param string $value
+ * @return array indexes dsn, username, password, host, port, database
+ */
+ public static function parseDsn($value)
+ {
+ if (empty($value)) {
+ throw new Exception(__METHOD__ . ' - format of DSN should conform '
+ . 'to mysql://username:password@host:port/database - Received '
+ . 'empty value');
+ }
+
+ /*
+ * Matches will return:
+ * - value after double forward slashes but before the @ as index [1]
+ * - value after @ but before the next forward slash as index[2]
+ * - value after the forward slash as index[3]
+ */
+ if (!preg_match('/.+:\/\/(.+)\@(.*)\/(.*)/', $value, $matches)) {
+ throw new Exception(__METHOD__ . ' - format of DSN should conform '
+ . 'to mysql://username:password@host:port/database - Received ('
+ . $value . ')');
+ }
+
+ $username = null;
+ $password = null;
+ $host = null;
+ $port = null;
+ $database = null;
+
+ $username = $matches[1];
+ if (false !== strpos($username, ':')) {
+ list($username, $password) = explode(':', $username);
+ }
+
+ $host = $matches[2];
+ if (false !== strpos($host, ':')) {
+ list($host, $port) = explode(':', $host);
+ }
+
+ //default to localhost
+ if (empty($host)) {
+ $host = '127.0.0.1';
+ }
+
+ $database = $matches[3];
+
+ $dsn = 'mysql:host=' . $host . ';' . 'dbname=' . $database;
+
+ if (!empty($port)) {
+ $dsn .= ';port=' . $port;
+ }
+
+ return array(
+ self::DSN => $dsn,
+ self::USERNAME => $username,
+ self::PASSWORD => $password,
+ self::HOST => $host,
+ self::PORT => $port,
+ self::DATABASE => $database,
+ );
+ }
+
+ /**
+ * read 'db' conf file and get PEAR style DSN
+ * @param string name of the DSN in the 'db' configuration file
+ * @return string
+ */
+ static function get_dsn($name) {/*{{{*/
+ return Conf::get($name, 'db', 'dsn');
+ }/*}}}*/
+
+ /**
+ * helper: generate comma separated '?' using array size
+ * @param array
+ * @return string
+ */
+ static function qmarks(&$list) {
+ return join(',', array_fill(0, count($list), '?'));
+ }
+
+ /**
+ * helper: generate SQL parts and values array to be used with PDO
+ *
+ * list of SQL parts that will be joined like "join(',', $parts)".
+ * in case of
+ * - update: sql part looks like 'field = ?' and 'field = DEFAULT' if value == (string) 'DEFAULT'
+ * - insert: sql part looks like '?' or 'DEFAULT'
+ *
+ * example:
+ * <code>
+ * <?php
+ * // ...
+ * list($fields, $values) = MyDB::parts_for('update', array('col1', 'col2'), $data);
+ * $query = 'update t1 set '.join(',', $fields).' where id = ?'
+ * $values[] = 443; // add id for the where clause
+ * $stmt = $dbh->prepare($query);
+ * $stmt->execute($values);
+ * // ...
+ * ?>
+ * </code>
+ *
+ * @param string 'insert' or 'update'
+ * @param array list of allowed fields (this way we sanitize SQL)
+ * @param array key/value pairs
+ * @return array [array $sql_parts, array $values]
+ */
+ static function parts_for($mode, $fields, &$data) {/*{{{*/
+ $sql_parts = $values = array();
+ $mode = strtolower($mode);
+ foreach($data as $field => $value)
+ if(in_array($field, $fields)) {
+ if(($mode == 'insert' && $value !== 'DEFAULT') || $mode == 'update') {
+ $sign = $value === 'DEFAULT' ? 'DEFAULT' : '?';
+ $sql_parts[] = $mode == 'insert' ? $field : "{$field} = {$sign}";
+
+ if($value !== 'DEFAULT')
+ $values[] = $value;
+ }
+ }
+
+ return array($sql_parts, $values);
+ }/*}}}*/
+}/*}}}*/
+
+/**
+ * Wrapper class around PHP's PDO
+ *
+ * added logging and exceptions handling
+ */
+class OpsPDO extends PDO {/*{{{*/
+ private $active_transaction = false;
+
+ /**
+ * @return PDOStatement
+ */
+ public function prepare($query, $opts = NULL) {
+ Log::debug('query (prepare): '.$query);
+
+ if(!$stmt = parent::prepare($query)) {
+ $error_info = $this->errorInfo();
+ Log::error('query failed: '.$query.' error: '.$error_info[0].' '.$error_info[2]);
+ throw new Exception('Internal Application Error (DATABASE)');
+ }
+
+ return new OpsPDOStatement($stmt);
+ }
+
+ /**
+ *
+ * @return PDOStatement
+ */
+ function query($query) {
+ Log::debug('query: '.$query);
+ if (Log::$level == Log::DEBUG) {
+ return new OpsPDOStatement(parent::query($query));
+ } else {
+ return parent::query($query);
+ }
+ }
+
+ function exec($query) {
+ Log::debug('query (exec): '.$query);
+ return parent::exec($query);
+ }
+
+ function beginTransaction() {
+ if($this->active_transaction) {
+ Log::debug('transaction already started');
+ return false;
+ }
+
+ $this->active_transaction = true;
+
+ Log::debug('begin transaction');
+ return parent::beginTransaction();
+ }
+
+ function commit() {
+ Log::debug('commit transaction');
+ $this->active_transaction = false;
+ return parent::commit();
+ }
+
+ function rollback() {
+ Log::debug('rollback transaction');
+ $this->active_transaction = false;
+ return parent::rollback();
+ }
+
+ /**
+ * Fetches all SQL result rows as a sequential array.
+ * Uses the current fetchMode
+ *
+ * @author A. Stefan De Clercq <declercq@yahoo-inc.com>
+ * @param string $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @param mixed $fetchMode Override default fetch mode.
+ * @return array
+ */
+ public function getAll($sql, $bind = array(), $fetchMode = PDO::FETCH_ASSOC) {
+ if (! is_array($bind)) {
+ $bind = array($bind);
+ }
+
+ $stmt = parent::prepare($sql);
+ $stmt->execute($bind);
+
+ return $stmt->fetchAll($fetchMode);
+
+ }
+
+ /**
+ * Fetches the first row of the SQL result.
+ * Uses the current fetchMode for the adapter.
+ *
+ * @author A. Stefan De Clercq <declercq@yahoo-inc.com>
+ * @param string $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @param mixed $fetchMode Override default fetch mode.
+ * @return array
+ */
+ public function getRow($sql, $bind = array(), $fetchMode = PDO::FETCH_ASSOC) {
+ if (! is_array($bind)) {
+ $bind = array($bind);
+ }
+
+ $stmt = parent::prepare($sql);
+ $stmt->execute($bind);
+
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+
+ /**
+ * Fetches all SQL result rows as an array of key-value pairs.
+ *
+ * The first column is the key, the second column is the
+ * value.
+ *
+ * @author A. Stefan De Clercq <declercq@yahoo-inc.com>
+ * @param string $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @return array
+ */
+
+ public function getPairs($sql, $bind = array()) {
+ if (! is_array($bind)) {
+ $bind = array($bind);
+ }
+
+ $stmt = parent::prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
+ $stmt->execute($bind);
+
+ $data = array();
+ while ($row = $stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT)) {
+ $data[$row[0]] = $row[1];
+ }
+
+ return $data;
+ }
+
+ /**
+ * Fetches the first column of all SQL result as an array
+ *
+ * The first column in each row is used as the array key.
+ *
+ * @author A. Stefan De Clercq <declercq@yahoo-inc.com>
+ * @param string $sql An SQL SELECT statement.
+ * @param mixed $bind Data to bind into SELECT placeholders.
+ * @return array
+ */
+
+ public function getCol($sql, $bind = array()) {
+ if (! is_array($bind)) {
+ $bind = array($bind);
+ }
+
+ $stmt = parent::prepare($sql);
+ $stmt->execute($bind);
+
+ return $stmt->fetchAll(PDO::FETCH_COLUMN);
+ }
+
+ /**
+ * Fetches the first column of the the first row of an SQL result as a mixed variable
+ *
+ * @author A. Stefan De Clercq <declercq@yahoo-inc.com>
+ * @param string $sql An SQL SELECT statement
+ * @param mixed $bind Data to bind into SELECT placeholders
+ * @return mixed
+ */
+ public function getOne($sql, $bind = array()) {
+ if (! is_array($bind)) {
+ $bind = array($bind);
+ }
+
+ $stmt = parent::prepare($sql);
+ $stmt->execute($bind);
+
+ $result = $stmt->fetchColumn();
+
+ return $result? $result : NULL;
+ }
+
+}/*}}}*/
+
+/**
+ * Wrapper class around PHP's PDOStatement
+ *
+ * added logging
+ */
+class OpsPDOStatement implements IteratorAggregate {/*{{{*/
+ private $__stmt;
+
+ function __construct(PDOStatement $PDOStatement) {
+ $this->__stmt = $PDOStatement;
+ }
+
+ function execute($v = null) {
+ Log::debug('statement (execute)');
+ Log::debug($v);
+ return $this->__stmt->execute($v);
+ }
+
+ /** reflection seems to break bindParam on occasion**/
+ function bindParam($param, $value) {
+ $this->__stmt->bindParam($param, $value);
+ }
+
+ function __call($name, $args) {
+ $method = new ReflectionMethod($this->__stmt, $name);
+ return $method->invokeArgs($this->__stmt, $args);
+ }
+
+ function getIterator() { return $this->__stmt; }
+}/*}}}*/
+
+/**
+ * Base class for Application Connection
+ * contains basic helper methods.
+ * This is obsolete, don't use this approach (akabanov 04/22/08)
+ * @see MyDB
+ * @deprecated
+ */
+abstract class ConnectionBase {/*{{{*/
+ /**
+ * @param string configuration name
+ * @return string
+ */
+ static function get_dsn($conf_name) {
+ return 'mysql:host='.Conf::$FILE[$conf_name][OPS_ENV]['hostname'].
+ ';dbname='.Conf::$FILE[$conf_name][OPS_ENV]['database'];
+ }
+
+ /**
+ * @param string configuration name
+ * @return string
+ */
+ static function get_username($conf_name) {
+ return Conf::$FILE[$conf_name][OPS_ENV]['username'];
+ }
+
+ /**
+ * @param string configuration name
+ * @return string
+ */
+ static function get_password($conf_name) {
+ return Conf::$FILE[$conf_name][OPS_ENV]['password'];
+ }
+}/*}}}*/
+
+/**
+ * Database Connections Registry, we should obsolete this
+ * use DB class instead. We can't delete it because some apps
+ * still use it. Use MyDB::get() and MyDB::get_legacy() (akabanov 04/22/08)
+ * @deprecated
+ * This is obsolete, don't use this approach (akabanov 04/22/08)
+ * @see MyDB
+ * @deprecated
+ */
+class DbRegistry {/*{{{*/
+ /**
+ * @var array current connections list
+ */
+ static $connections;
+
+ /**
+ * create new connection
+ *
+ * when new connection is requested it checks connections list and if the requested connection doesn't exists
+ * creates it and puts in the connections array
+ *
+ * @param string DSN
+ * @param string username
+ * @param string password
+ */
+ static function connect($dsn, $username, $password=null) {
+ $cuid = md5($dsn.$username.$password);
+ if(isset(self::$connections[$cuid])) {
+ return self::$connections[$cuid];
+ }
+
+ $dbh = new OpsPDO($dsn, $username, $password);
+ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ self::$connections[$cuid] = $dbh;
+
+ return $dbh;
+ }
+}/*}}}*/
+
+?>
131 src/assist/common/Helpers.php
@@ -0,0 +1,131 @@
+<?php
+
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+
+function env() {/*{{{*/
+ if(defined('OPS_ENV'))
+ return OPS_ENV;
+
+ return getenv('OPS_ENV') ? getenv('OPS_ENV') : 'development';
+}/*}}}*/
+
+// initialize OPS_ENV
+if(!defined('OPS_ENV'))
+ define('OPS_ENV', env());
+
+/**
+ * the simple hash used for generating an APC key for user override
+ *
+ * @param string $username
+ * @return string
+ */
+function username_override_hash($username) {
+ return md5('username_override_'.$username);
+}
+
+/**
+ */
+function username($force=false) {/*{{{*/
+ static $username;
+
+ if($username && !$force)
+ return $username;
+ // this hack is for OpsApiServer class
+ if(getenv('OPS_API_SERVER_USERNAME'))
+ $username = getenv('OPS_API_SERVER_USERNAME');
+ else
+ $username = strlen(getenv('_byuser')) ? getenv('_byuser') : getenv('.byuser');
+
+ #if we're not in prod, check in APC for override
+ /*if (defined('OPS_ENV') && !preg_match('/^prod/i', OPS_ENV)) {
+ $override = apc_fetch(username_override_hash($username));
+ if ($override) {
+ Log::debug('User '.$username.' acting as '.$override);
+ $username = $override;
+ }
+ }
+*/
+ if(!$username)
+ $username = getenv("USER");
+
+ return $username;
+}/*}}}*/
+
+/**
+ * return true BY username; used in override process to make sure
+ * we don't override an overridden username
+ *
+ * @return string BY username
+ */
+function username_strict() {
+ $username = strlen(getenv('_byuser')) ? getenv('_byuser') : getenv('.byuser');
+ return $username;
+}
+
+/**
+ * used by OpsApiServer class only
+ * @return string
+ */
+function application() {
+ return getenv('.byappname') ?
+ getenv('.byappname') : getenv('OPS_API_SERVER_APPLICATION');
+}
+
+class Helpers {
+ /**
+ * the hostname of the current machine
+ *
+ * this method requires yphp_gethostname package
+ * @return string hostname
+ */
+ function get_localhost() {
+ // returns hostname < 255 chars
+ // http://dist.corp.yahoo.com/by-package/yphp_gethostname/
+ if (defined('PHP_HOSTNAME')) {
+ return PHP_HOSTNAME;
+ }
+
+ // returns hostname < 32 chars
+ $uname = posix_uname();
+ return ($uname['nodename']);
+ }
+
+ /**
+ * @todo document this method
+ *
+ * @return int
+ */
+ function apcTimeout(){
+ if(defined('APCTIMEOUT'))
+ return APCTIMEOUT;
+
+ return getenv('APCTIMEOUT') ? getenv('APCTIMEOUT') : 18000;
+ }
+
+ /**
+ * check if given value is an array, otherwise put it in array
+ * just to save time typing the same code block again and again
+ * @param mixed
+ * @return array
+ */
+ function as_array($value) {
+ return is_array($value) ? $value : array($value);
+ }
+}
+
+?>
105 src/assist/common/Logger.php
@@ -0,0 +1,105 @@
+<?php
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+
+
+class Log {
+ /**
+ * @var integer current log level (by default disabled)
+ */
+ public static $level = self::DISABLED;
+
+ const DISABLED = 0;
+ const ERROR = LOG_ERR;
+ const WARNING = LOG_WARNING;
+ const INFO = LOG_INFO;
+ const DEBUG = LOG_DEBUG;
+
+ /**
+ * @var array list of message labels
+ */
+ private static $level_labels = array(
+ self::ERROR => 'ERROR',
+ self::WARNING => 'WARNING',
+ self::INFO => 'INFO',
+ self::DEBUG => 'DEBUG'
+ );
+
+ /**
+ * @deprecated
+ */
+ static function init($application_name) {
+ return trigger_error("DEPRECATED Log::init()", E_USER_WARNING);
+ }
+
+ static function info($message) {
+ self::message(self::INFO, $message);
+ }
+
+ static function warning($message) {
+ self::message(self::WARNING, $message);
+ }
+
+ static function error($message) {
+ self::message(self::ERROR, $message);
+ }
+
+ static function debug($message) {
+ self::message(self::DEBUG, $message);
+ }
+
+ /**
+ * generic message method, used by other methods
+ *
+ * @param integer level
+ * @param string log message
+ */
+ private static function message($level, $message) {
+ if($level <= self::$level) {
+ $location = debug_backtrace();
+ $message = print_r($message, true);
+
+ if($level <= LOG_WARNING)
+ $message = "$message (file: ".$location[1]['file'].' @ line: '.$location[1]['line'].')';
+
+ self::error_log('['.self::level_name($level).'] '.$message);
+ }
+ }
+
+ /**
+ * custom error_log implementation (by default it uses standard php error_log())
+ *
+ * feel free to override this method in your application
+ *
+ * @param string
+ */
+ private function error_log($message) {
+ error_log($message);
+ }
+
+ static function level_name($level) {
+ return self::$level_labels[$level];
+ }
+
+ static function level($name) {
+ $name = strtoupper($name);
+ self::$level = defined("self::$name") ?
+ constant("self::$name") : self::WARNING;
+ }
+}
+
+Log::level(getenv('OPS_LOG_LEVEL'));
894 src/assist/common/MVC.php
@@ -0,0 +1,894 @@
+<?php
+
+//+---------------------------------------------------------------------------------------------------------------------------------+
+// /
+// Copyright (c) 2012 Yahoo! Inc. All rights reserved. /
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this /
+// file except in compliance with the License. You may obtain a copy of the License at /
+// /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+// /
+// Unless required by applicable law or agreed to in writing, software distributed under /
+// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF /
+// ANY KIND, either express or implied. See the License for the specific language governing /
+// permissions and limitations under the License. See accompanying LICENSE file. /
+// /
+// $Author:shawcs@yahoo-inc.com $Date: 30-Jan-2012 /
+// /
+//+---------------------------------------------------------------------------------------------------------------------------------+
+
+
+function redirect_to($controller_name, $action_name=null, $params=array(), $fragment='') {
+ $url = $controller_name;
+
+ //TODO if controller_name is a URL and params isn't empty then add it
+ if (!preg_match('/^http.*:\/.+/i', $controller_name)) {
+ $url = html::url($controller_name, $action_name, $params, $fragment);
+ }
+
+ header("Location: $url");
+ return array('redirect' => $url);
+}
+
+/**
+ * internal redirect to a controller + [action].
+ * New controller instance created and action called, when redirecting to another controller.
+ * Internal controller redirect - when controller name is string 'this'.
+ * When action_name is not specified - 'index' will be used.
+ *
+ * @param string
+ * @param string
+ * @return array ['controller' => $controller_name, 'action' => $action_name]
+ */