diff --git a/application/config/smileys.php b/application/config/smileys.php new file mode 100644 index 00000000000..abf9a898dde --- /dev/null +++ b/application/config/smileys.php @@ -0,0 +1,64 @@ + array('grin.gif', '19', '19', 'grin'), + ':lol:' => array('lol.gif', '19', '19', 'LOL'), + ':cheese:' => array('cheese.gif', '19', '19', 'cheese'), + ':)' => array('smile.gif', '19', '19', 'smile'), + ';-)' => array('wink.gif', '19', '19', 'wink'), + ';)' => array('wink.gif', '19', '19', 'wink'), + ':smirk:' => array('smirk.gif', '19', '19', 'smirk'), + ':roll:' => array('rolleyes.gif', '19', '19', 'rolleyes'), + ':-S' => array('confused.gif', '19', '19', 'confused'), + ':wow:' => array('surprise.gif', '19', '19', 'surprised'), + ':bug:' => array('bigsurprise.gif', '19', '19', 'big surprise'), + ':-P' => array('tongue_laugh.gif', '19', '19', 'tongue laugh'), + '%-P' => array('tongue_rolleye.gif', '19', '19', 'tongue rolleye'), + ';-P' => array('tongue_wink.gif', '19', '19', 'tongue wink'), + ':P' => array('raspberry.gif', '19', '19', 'raspberry'), + ':blank:' => array('blank.gif', '19', '19', 'blank stare'), + ':long:' => array('longface.gif', '19', '19', 'long face'), + ':ohh:' => array('ohh.gif', '19', '19', 'ohh'), + ':grrr:' => array('grrr.gif', '19', '19', 'grrr'), + ':gulp:' => array('gulp.gif', '19', '19', 'gulp'), + '8-/' => array('ohoh.gif', '19', '19', 'oh oh'), + ':down:' => array('downer.gif', '19', '19', 'downer'), + ':red:' => array('embarrassed.gif', '19', '19', 'red face'), + ':sick:' => array('sick.gif', '19', '19', 'sick'), + ':shut:' => array('shuteye.gif', '19', '19', 'shut eye'), + ':-/' => array('hmm.gif', '19', '19', 'hmmm'), + '>:(' => array('mad.gif', '19', '19', 'mad'), + ':mad:' => array('mad.gif', '19', '19', 'mad'), + '>:-(' => array('angry.gif', '19', '19', 'angry'), + ':angry:' => array('angry.gif', '19', '19', 'angry'), + ':zip:' => array('zip.gif', '19', '19', 'zipper'), + ':kiss:' => array('kiss.gif', '19', '19', 'kiss'), + ':ahhh:' => array('shock.gif', '19', '19', 'shock'), + ':coolsmile:' => array('shade_smile.gif', '19', '19', 'cool smile'), + ':coolsmirk:' => array('shade_smirk.gif', '19', '19', 'cool smirk'), + ':coolgrin:' => array('shade_grin.gif', '19', '19', 'cool grin'), + ':coolhmm:' => array('shade_hmm.gif', '19', '19', 'cool hmm'), + ':coolmad:' => array('shade_mad.gif', '19', '19', 'cool mad'), + ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'), + ':vampire:' => array('vampire.gif', '19', '19', 'vampire'), + ':snake:' => array('snake.gif', '19', '19', 'snake'), + ':exclaim:' => array('exclaim.gif', '19', '19', 'exclaim'), + ':question:' => array('question.gif', '19', '19', 'question') + +); diff --git a/application/controllers/Auth.php b/application/controllers/Auth.php new file mode 100644 index 00000000000..f860c848e5b --- /dev/null +++ b/application/controllers/Auth.php @@ -0,0 +1,50 @@ +load->model('M_User'); + } + + public function index() { + $this->form_validation->set_rules('username', 'Username', 'required|trim'); + $this->form_validation->set_rules('password', 'Password', 'required|trim'); + + if ($this->form_validation->run() == FALSE) { + $this->load->view('V_login'); + } else { + $this->_do_login(); + } + } + + private function _do_login() { + $username = $this->input->post('username'); + $password = $this->input->post('password'); + + $user = $this->M_User->checkUser($username, $password); + + // if user avail + if ($user) { + $profile = $this->M_User->getProfile($user['username']); + + $this->session->set_userdata($profile); + redirect('User'); + } else { + redirect('Auth'); + } + } + + public function do_logout() { + $this->session->unset_userdata('username'); + redirect('Auth'); + } + +} + +?> diff --git a/application/controllers/User.php b/application/controllers/User.php new file mode 100644 index 00000000000..6cf7478a3d0 --- /dev/null +++ b/application/controllers/User.php @@ -0,0 +1,88 @@ +session->userdata('username')) { + redirect('Auth'); + } + + $this->load->model('M_User'); + } + + public function index() { + $this->load->view('V_profile'); + } + + public function load_explore() { + $this->load->view('V_explore'); + } + + public function load_feed() { + $this->load->view('V_feed'); + } + + public function load_editProfile() { + $this->load->view('V_edit-profile'); + } + + public function load_uploadPhoto() { + $this->load->view('V_upload-photo'); + } + + public function do_editProfile() { + $this->form_validation->set_rules('name', 'Name', 'required'); + $this->form_validation->set_rules('username', 'Username', 'required|trim'); + $this->form_validation->set_rules('website', 'Website', 'required|trim'); + $this->form_validation->set_rules('bio', 'Bio', 'required'); + $this->form_validation->set_rules('email', 'Email', 'required|trim'); + $this->form_validation->set_rules('phonenumber', 'Phonenumber', 'required|trim'); + $this->form_validation->set_rules('gender', 'Username', 'required'); + + $username = $this->session->userdata('username'); + + $dataProfile = [ + 'name' => $this->input->post('name'), + 'username' => $this->input->post('username'), + 'website' => $this->input->post('website'), + 'bio' => $this->input->post('bio'), + 'email' => $this->input->post('email'), + 'phonenumber' => $this->input->post('phonenumber'), + 'gender' => $this->input->post('gender') + ]; + + $dataUser = [ + 'username' => $this->input->post('username'), + 'email' => $this->input->post('email') + ]; + + $this->M_User->editProfile($dataProfile, $username); + $this->M_User->editUser($dataUser, $username); + $this->session->set_userdata($dataProfile); + redirect('User'); + } + + public function do_uploadPhoto() { + $data = []; + + $upload = $this->M_User->uploadPhoto(); + + if ($upload['result'] == 'success') { + $this->M_User->saveIntoDatabase($upload); + redirect('User'); + } else { + $data['message'] = $upload['error']; + redirect('User/load_uploadPhoto'); + } + } + +} + +?> \ No newline at end of file diff --git a/application/models/M_User.php b/application/models/M_User.php new file mode 100644 index 00000000000..0f492e1e4b4 --- /dev/null +++ b/application/models/M_User.php @@ -0,0 +1,68 @@ +db->get_where('user', [ + 'username' => $username, + 'password' => $password + ])->row_array(); + } + + public function getProfile($username) { + return $this->db->get_where('profile', [ + 'username' => $username + ])->row_array(); + } + + public function editProfile($data, $username) { + $this->db->where('username', $username); + $this->db->update('profile', $data); + } + + public function editUser($data, $username) { + $this->db->where('username', $username); + $this->db->update('user', $data); + } + + // Upload Image ----------------------------- + public function uploadPhoto() { + $config['upload_path'] = './assets/images/'; + $config['allowed_types'] = 'jpg|png|jpeg'; + $config['max_size'] = 2048; + $config['remove_spcae'] = TRUE; + + $this->load->library('upload', $config); + if ($this->upload->do_upload('image')) { + $result = [ + 'result' => 'success', + 'file' => $this->upload->data(), + 'error' => '', + ]; + return $result; + } else { + $result = [ + 'result' => 'error', + 'file' => '', + 'error' => $this->upload->display_errors(), + ]; + return $result; + } + } + + public function saveIntoDatabase($upload) { + $data = [ + 'url' => $upload['file']['file_name'], + 'caption' => $this->input->post('caption'), + 'like' => 225, + ]; + $this->db->insert('photo', $data); + } + +} + +?> \ No newline at end of file diff --git a/application/views/V_edit-profile.php b/application/views/V_edit-profile.php new file mode 100644 index 00000000000..a76339f1f98 --- /dev/null +++ b/application/views/V_edit-profile.php @@ -0,0 +1,120 @@ + + + + + + + + + + + Edit Profile | Vietgram + + + + + + +
+
+
+
+ +
+

Edit your profile, session->userdata('username') ?>.

+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ + + + \ No newline at end of file diff --git a/application/views/V_explore.php b/application/views/V_explore.php new file mode 100644 index 00000000000..08e292f52f8 --- /dev/null +++ b/application/views/V_explore.php @@ -0,0 +1,117 @@ + + + + + + + + + + + Explore | Vietgram + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/application/views/V_feed.php b/application/views/V_feed.php new file mode 100644 index 00000000000..58ee78bac8e --- /dev/null +++ b/application/views/V_feed.php @@ -0,0 +1,218 @@ + + + + + + + + + + + Feed | Vietgram + + + + + + +
+ + db->select('*'); + $this->db->from('photo'); + $this->db->like('caption', $_GET['caption']); + $query_image = $this->db->get()->result_array(); + } else { + $query_image = $this->db->get('photo')->result_array(); + } + + // Show image + foreach ($query_image as $row) { + ?> +
+
+ + +
+ +
+
+ + + + + + +
+ +
    +
  • + Muhammad Farrel +
  • +
+ 2 hours ago +
+ + +
+
+
+ + +
+
+ + +
+ +
+
+ + + + + + +
+ +
    +
  • + Farrel love this! +
  • +
  • + Farrel love this! +
  • +
  • + Farrel love this! +
  • +
  • + Farrel love this! +
  • +
+ 2 hours ago +
+ + +
+
+
+
+
+ + +
+ +
+
+ + + + + + +
+ +
    +
  • + Farrel love this! +
  • +
  • + Farrel love this! +
  • +
  • + Farrel love this! +
  • +
  • + Farrel love this! +
  • +
+ 2 hours ago +
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/application/views/V_login.php b/application/views/V_login.php new file mode 100644 index 00000000000..74a9f290aa3 --- /dev/null +++ b/application/views/V_login.php @@ -0,0 +1,72 @@ + + + + + + Vietgram | Login + + + + + + + + +
+
+ +
+
+ + + +
+
+ + + \ No newline at end of file diff --git a/application/views/V_profile.php b/application/views/V_profile.php new file mode 100644 index 00000000000..d8bc1f2e3ee --- /dev/null +++ b/application/views/V_profile.php @@ -0,0 +1,184 @@ + + + + + + + + + + + Profile | Vietgram + + + + + + +
+
+
+ +
+
+
+

session->userdata('username'); ?>

+ Edit profile + Upload photo + Logout + +
+
    +
  • + 6 posts +
  • +
  • + 435 followers +
  • +
  • + 479 following +
  • +
+ +

+ + session->userdata('name'); ?> +
+
+ session->userdata('bio'); ?> + session->userdata('website'); ?> +

+
+
+
+ + db->get('photo')->result_array(); + foreach ($query_image as $row) { ?> +
+ " /> +
+ + + + + + + 344 + +
+
+ +
+ +
+ + + 486 + + + + 344 + +
+
+
+ +
+ + + 486 + + + + 344 + +
+
+
+ +
+ + + 486 + + + + 344 + +
+
+
+ +
+ + + 486 + + + + 344 + +
+
+
+
+ + + + \ No newline at end of file diff --git a/application/views/V_upload-photo.php b/application/views/V_upload-photo.php new file mode 100644 index 00000000000..3283be348e1 --- /dev/null +++ b/application/views/V_upload-photo.php @@ -0,0 +1,58 @@ + + + + + + + + + + Document + + + + + + + + + + + + + +
+
+
+

Upload your photo please

+
+
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+ + + \ No newline at end of file diff --git a/application/views/box-model.html b/application/views/box-model.html new file mode 100644 index 00000000000..a52be8be767 --- /dev/null +++ b/application/views/box-model.html @@ -0,0 +1,42 @@ + + + + + + + Box Model + + + +
+
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/application/views/links.html b/application/views/links.html new file mode 100644 index 00000000000..ab039d8f678 --- /dev/null +++ b/application/views/links.html @@ -0,0 +1,25 @@ + + + + + + + + Links 4 u + + + + + \ No newline at end of file diff --git a/assets/css/edit-profile.css b/assets/css/edit-profile.css new file mode 100644 index 00000000000..75465431998 --- /dev/null +++ b/assets/css/edit-profile.css @@ -0,0 +1,100 @@ +#edit-profile { + display: flex; + justify-content: center; +} + +#edit-profile .edit-profile__container { + background-color: white; + border: 1px solid #e6e6e6; + width: 100%; + max-width: 800px; +} + +#edit-profile .edit-profile__container { + padding: 40px 0; +} + +#edit-profile .edit-profile__header { + display: flex; + align-items: center; + margin-bottom: 50px; +} + +.edit-profile__header .edit-profile__avatar-container { + width: 200px; +} + +.edit-profile__avatar-container { + display: flex; + justify-content: flex-end; + margin-right: 35px; +} + +.edit-profile__avatar-container img { + width: 38px; + height: 38px; + border-radius: 50%; +} +.edit-profile__header h4 { + font-size: 18px; + font-weight: 600; +} + +.edit-profile__form .form__row { + display: flex; +} + +.form__row { + margin-bottom: 20px; + display: flex; + align-items: center; +} + +.form__row .form__label { + width: 200px; + display: block; + text-align: right; + margin-right: 35px; + font-weight: 600; + font-size: 16px; +} + +.form__row label { + font-size: 15px; + width: 80%; +} + +.form__row .form__input, +.form__row textarea { + padding: 8px; + width: 255px; + resize: vertical; + border: 0; + border: 1px solid #e6e6e6; + border-radius: 3px; +} + +.form__row input[type="checkbox"] { + margin-right: 15px; +} + +#edit-profile select { + background: 0 0; + border: 1px solid #efefef; + border-radius: 3px; + color: #262626; + font-size: 16px; + height: 32px; + padding: 0 30px 0 10px; +} + +#edit-profile input[type="submit"] { + margin-left: 235px; + border: 0; + color: white; + font-weight: 600; + border-radius: 3px; + background-color: var(--fd-blue); + font-size: 14px; + padding: 7px 25px; +} diff --git a/assets/css/explore.css b/assets/css/explore.css new file mode 100644 index 00000000000..d4a8f6ba2af --- /dev/null +++ b/assets/css/explore.css @@ -0,0 +1,70 @@ +#explore { + display: flex; + justify-content: center; + align-items: flex-start; + min-height: 500px; +} + +#explore .explore__users { + background-color: white; + border: 1px solid #e6e6e6; + border-radius: 3px; + width: 100%; + max-width: 600px; +} + +.explore__users .explore__user { + padding: 10px 15px; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid #e6e6e6; +} + +.explore__users .explore__user:last-child { + border: 0; +} + +.explore__user .explore__avatar { + width: 55px; + border-radius: 50%; +} + +.explore__user .explore__user-column { + display: flex; + align-items: center; +} + +.explore__user .explore__info { + margin-left: 15px; +} + +.explore__info .explore__username { + display: block; + font-weight: 600; + margin-bottom: 5px; +} + +.explore__info .explore__full-name { + color: #999; +} + +.explore__user-column button { + background-color: var(--fd-blue); + color: white; + border: 0; + font-weight: 600; + padding: 5px 10px; + font-size: 14px; + border-radius: 3px; + cursor: pointer; +} + +.explore__user-column button:active, +.explore__user-column button:focus { + outline: none; +} + +.explore__user-column:active { + opacity: 0.9; +} diff --git a/assets/css/feed.css b/assets/css/feed.css new file mode 100644 index 00000000000..cc88c16ef17 --- /dev/null +++ b/assets/css/feed.css @@ -0,0 +1,101 @@ +#feed { + display: flex; + align-items: center; + flex-direction: column; +} + +#feed .photo { + background-color: white; + border: 1px solid #e6e6e6; + border-radius: 3px; + width: 100%; + max-width: 600px; + margin-bottom: 65px; +} + +.photo .photo__header { + padding: 15px; + display: flex; + align-items: center; +} + +.photo__header .photo__avatar { + width: 32px; + border-radius: 50%; + margin-right: 10px; +} + +.photo .photo__user-info .photo__author { + display: block; + font-weight: 600; + margin-bottom: 5px; +} + +.photo > img { + max-width: 100%; +} + +.photo .photo__info { + padding: 15px 20px; +} + +.photo__actions { + margin-bottom: 15px; + font-size: 115%; +} + +.photo__actions .photo__action:first-child { + margin-right: 15px; +} + +.photo__actions .photo__action { + cursor: pointer; +} + +.photo .photo__likes { + font-weight: 600; + margin-bottom: 10px; + display: block; +} + +.photo .photo__add-comment-container { + margin-top: 15px; + border-top: 1px solid #e6e6e6; + padding-top: 10px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.photo__add-comment-container textarea { + width: 90%; + border: 0; + font-size: 14px; + resize: none; + height: 20px; +} + +.photo__add-comment-container textarea:focus, +.photo__add-comment-container textarea:active { + outline: none; +} + +.photo__add-comment-container i { + cursor: pointer; +} + +.photo .photo__time-ago { + font-size: 10px; + text-transform: uppercase; + color: #999; + margin-top: 10px; + display: block; +} + +.photo__comment { + margin-bottom: 10px; +} + +.photo__comments .photo__comment-author { + font-weight: 600; +} diff --git a/assets/css/footer.css b/assets/css/footer.css new file mode 100644 index 00000000000..0d5b8cbae0e --- /dev/null +++ b/assets/css/footer.css @@ -0,0 +1,30 @@ +.footer { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + max-width: 900px; + margin: 30px auto; + text-transform: uppercase; + font-size: 12px; + font-weight: 600; +} + +.footer .footer__list { + padding: 0; + list-style-type: none; + display: flex; +} + +.footer .footer__copyright { + color: hsl(0, 0%, 60%); +} + +.footer__list .footer__list-item { + margin-right: 10px; +} + +.footer .footer__link { + text-decoration: none; + color: var(--link-color); +} diff --git a/assets/css/globals.css b/assets/css/globals.css new file mode 100644 index 00000000000..cea96117b23 --- /dev/null +++ b/assets/css/globals.css @@ -0,0 +1,21 @@ +body { + background-color: white; + background-color: var(--background-color); + font-size: 14px; + font-family: "Open Sans", sans-serif; +} + +main { + animation: fadeInMain 0.5s linear; +} + +@keyframes fadeInMain { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0px); + } +} diff --git a/assets/css/login.css b/assets/css/login.css new file mode 100644 index 00000000000..f5657f0c13a --- /dev/null +++ b/assets/css/login.css @@ -0,0 +1,128 @@ +#login { + width: 100%; + max-width: 800px; + margin: 45px auto; + display: flex; + justify-content: space-around; +} + +#login .login__column { + width: 45%; +} + +.login__column .login__phone { + max-width: 100%; +} + +.login__column .login__box { + background-color: white; + border: 1px solid #e6e6e6; +} + +.login__column .login__box--transparent { + background: none; + border: 0; + display: flex; + flex-direction: column; + align-items: center; + margin-top: 35px; +} + +.login__column .login__appstores { + margin-top: 20px; +} + +.login__appstores .login__appstore { + height: 40px; +} + +#login .login__box { + padding: 30px 0; + text-align: center; +} + +#login .login__box:first-child { + margin-bottom: 10px; + padding-left: 40px; + padding-right: 40px; +} + +.login__column .login__logo { + height: 50px; +} + +.login__form input { + display: block; + width: 100%; + box-sizing: border-box; + padding: 7px; + font-size: 14px; + border: 0; + border: 1px solid #e6e6e6; + border-radius: 5px; + background: #fafafa; +} + +.login__form input:focus { + outline: none; + border: 1px solid #a9a9a9; +} + +.login__form input:first-child { + margin-bottom: 5px; +} + +.login__form input[type="submit"] { + background-color: #3f99ed; + border: 0; + padding: 5px; + margin-top: 15px; + margin-bottom: 20px; + color: white; + font-weight: 600; +} + +#login .login__divider { + display: block; + text-transform: uppercase; + font-weight: 600; + color: #999; + margin-bottom: 20px; + position: relative; + width: 100%; +} + +#login .login__link { + display: block; + text-decoration: none; + color: #003569; +} + +#login .login__link--small { + margin-top: 30px; +} + +.login__box a { + text-decoration: none; + color: var(--fd-blue); +} + +#login .login__divider:before { + content: ""; + height: 1px; + background-color: rgba(153, 153, 153, 0.5); + width: 40%; + position: absolute; + left: 0; + top: 10px; +} + +#login .login__divider:after { + content: ""; + height: 1px; + background-color: rgba(153, 153, 153, 0.5); + width: 40%; + position: absolute; + right: 0; + top: 10px; +} diff --git a/assets/css/mobile.css b/assets/css/mobile.css new file mode 100644 index 00000000000..fc236e0553c --- /dev/null +++ b/assets/css/mobile.css @@ -0,0 +1,110 @@ +@media screen and (min-width: 375px) and (max-width: 667px) { + .navigation { + padding: 0 20px; + margin-bottom: 0; + } + .navigation input, + .navigation .fa-search { + display: none; + } + #feed .photo { + background-color: transparent; + border: 0; + margin-bottom: 20px; + } + #feed .photo .photo__add-comment-container { + display: none; + } + .footer { + width: 80%; + } + .footer, + .footer .footer__list { + flex-wrap: wrap; + justify-content: center; + } + .footer__list .footer__list-item { + margin-bottom: 10px; + } + #login .login__column { + width: 100%; + } + #login .login__column:first-child { + display: none; + } + #login .login__box { + background-color: transparent; + border: 0; + } + #profile { + margin-top: 50px; + } + #profile .profile__header { + flex-direction: column; + align-items: center; + } + #profile .profile__title { + flex-wrap: wrap; + justify-content: center; + width: 100%; + } + .profile__title h3 { + margin: 20px 0; + } + .profile__title a { + margin-right: auto; + } + .profile__stats { + justify-content: space-between; + } + .profile__stats .profile__stat { + text-align: center; + margin-right: 0; + } + .profile__stat span { + display: block; + } + .profile__photos .profile__photo { + width: 33%; + margin-bottom: 0; + } + .profile__photos { + margin-bottom: 50px; + } + #explore .explore__users { + background-color: transparent; + border: 0; + } + .explore__users .explore__user { + border: 0; + } + #edit-profile > .edit-profile__container { + border: 0; + } + #edit-profile .form__row { + flex-direction: column; + } + .form__row .form__label { + margin: 0; + text-align: center; + margin-bottom: 10px; + } + #edit-profile input[type="submit"] { + width: 120px; + margin: 0; + margin-top: 20px; + } + #edit-profile .edit-profile__container { + display: flex; + flex-direction: column; + align-items: center; + } + #edit-profile .edit-profile__form { + display: flex; + flex-direction: column; + align-items: center; + } + .edit-profile__header .edit-profile__avatar-container { + width: 0; + } +} diff --git a/assets/css/navigation.css b/assets/css/navigation.css new file mode 100644 index 00000000000..cb729669732 --- /dev/null +++ b/assets/css/navigation.css @@ -0,0 +1,77 @@ +.navigation { + height: 75px; + background-color: white; + border-bottom: 1px solid #e6e6e6; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 100px; + margin-bottom: 60px; +} + +.navigation .navigation__column:first-child img { + height: 45px; +} + +.navigation .navigations__links { + display: flex; + padding: 0; + list-style-type: none; +} + +.navigation .navigation__list-item { + margin-left: 30px; + padding: 0 2px; + opacity: 0; + animation: slideNavLink 0.5s ease-out forwards; +} + +@keyframes slideNavLink { + from { + transform: translateY(-10px); + } + to { + opacity: 1; + transform: none; + } +} + +.navigation .navigation__list-item:nth-child(2) { + animation-delay: 0.2s; +} + +.navigation .navigation__list-item:last-child { + animation-delay: 0.3s; +} + +.navigation__link { + color: rgba(0, 0, 0, 0.8); + font-size: 18px; +} + +.navigation__column input { + padding: 5px 0; + padding-left: 60px; + border: 0; + border: 1px solid #e6e6e6; + border-radius: 3px; + background: #fafafa; + font-size: 16px; +} + +.navigation__column input:focus { + outline: none; + border: 1px solid #a9a9a9; +} + +.navigation__column { + position: relative; +} + +.navigation__column .fa-search { + position: absolute; + top: 10px; + left: 10px; + color: rgba(0, 0, 0, 0.5); + font-size: 12px; +} diff --git a/assets/css/profile.css b/assets/css/profile.css new file mode 100644 index 00000000000..5d115215978 --- /dev/null +++ b/assets/css/profile.css @@ -0,0 +1,161 @@ +#profile { + display: flex; + flex-direction: column; + align-items: center; +} + +#profile .profile__header { + max-width: 935px; + width: 100%; + display: flex; + margin-bottom: 50px; + font-size: 110%; +} + +.profile__header .profile__column { + width: 70%; +} + +.profile__header .profile__column:first-child { + width: 30%; + display: flex; + align-items: center; + justify-content: center; +} + +.profile__column:first-child img { + border-radius: 50%; + transform-style: preserve-3d; + transition: transform 0.5s linear; + animation: rotateLynn 1s linear infinite; +} + +@keyframes rotateLynn { + from { + transform: rotateY(0turn); + } + to { + transform: rotateY(1turn); + } +} + +.profile__column .profile__title, +.profile__column .profile__stats { + display: flex; + align-items: center; +} + +.profile__column .profile__title { + margin-bottom: 30px; +} + +.profile__title .profile__username { + margin-right: 25px; + font-size: 32px; + font-weight: 300; +} + +.profile__title a { + margin-right: 10px; + text-decoration: none; + color: inherit; + font-weight: 600; + padding: 5px 25px; + border: 1px solid #e6e6e6; + border-radius: 3px; + transition: all 0.3s ease-in-out; +} + +.profile__title a:hover { + background-color: #3f99ed; + color: white; + border-color: #3f99ed; +} + +.profile__title i { + cursor: pointer; + transition: transform 1s ease-in; +} + +.profile__title i:hover { + transform: rotate(2turn); +} + +.profile__column .profile__stats { + margin-bottom: 30px; +} + +.profile__stats .profile__stat { + margin-right: 40px; +} + +.profile__stat .stat__number { + font-weight: 600; +} + +.profile__bio .profile__full-name { + font-weight: 600; +} + +.profile__bio a { + color: var(--link-color); + font-weight: 600; + text-decoration: none; + display: block; +} + +.profile__column .profile__bio { + line-height: 125%; +} + +#profile .profile__photos { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + max-width: 936px; + width: 100%; +} + +.profile__photos .profile__photo { + width: 31%; + margin-bottom: 35px; + position: relative; +} + +.profile__photo img { + max-width: 100%; +} + +.profile__photo .profile__photo-overlay { + position: absolute; + top: 0; + background-color: rgba(0, 0, 0, 0.5); + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + color: white; + font-weight: 600; + opacity: 0; + transition: opacity 0.2s linear; +} + +.profile__photo:hover .profile__photo-overlay { + opacity: 1; +} + +.profile__photo-overlay .overlay__item { + font-size: 130%; + display: flex; + align-items: center; +} +.profile__photo-overlay .overlay__item:last-child { + margin-left: 10px; + /**/ +} + +.profile__photo-overlay .overlay__item i { + font-size: 130%; + margin-right: 5px; +} diff --git a/assets/css/reset.css b/assets/css/reset.css new file mode 100644 index 00000000000..82935aeceff --- /dev/null +++ b/assets/css/reset.css @@ -0,0 +1,124 @@ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ""; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/assets/css/styles.css b/assets/css/styles.css new file mode 100644 index 00000000000..09dd98497fc --- /dev/null +++ b/assets/css/styles.css @@ -0,0 +1,12 @@ +@import url("https://fonts.googleapis.com/css?family=Open+Sans:300,400,600"); +@import "reset.css"; +@import "variables.css"; +@import "globals.css"; +@import "login.css"; +@import "footer.css"; +@import "navigation.css"; +@import "explore.css"; +@import "feed.css"; +@import "profile.css"; +@import "edit-profile.css"; +@import "mobile.css"; diff --git a/assets/css/variables.css b/assets/css/variables.css new file mode 100644 index 00000000000..0620c7ea3f3 --- /dev/null +++ b/assets/css/variables.css @@ -0,0 +1,5 @@ +:root { + --background-color: #fafafa; + --fd-blue: #3897f0; + --link-color: #003569; +} diff --git a/assets/images/android.png b/assets/images/android.png new file mode 100644 index 00000000000..306aa45f29e Binary files /dev/null and b/assets/images/android.png differ diff --git a/assets/images/avatar.jpg b/assets/images/avatar.jpg new file mode 100644 index 00000000000..5ef783b9abf Binary files /dev/null and b/assets/images/avatar.jpg differ diff --git a/assets/images/farrel.jpg b/assets/images/farrel.jpg new file mode 100644 index 00000000000..02770da822a Binary files /dev/null and b/assets/images/farrel.jpg differ diff --git a/assets/images/feedPhoto.jpg b/assets/images/feedPhoto.jpg new file mode 100644 index 00000000000..f1da1a8cf0d Binary files /dev/null and b/assets/images/feedPhoto.jpg differ diff --git a/assets/images/gabungan.png b/assets/images/gabungan.png new file mode 100644 index 00000000000..3c99fc97233 Binary files /dev/null and b/assets/images/gabungan.png differ diff --git a/assets/images/ios.png b/assets/images/ios.png new file mode 100644 index 00000000000..460f81ab32d Binary files /dev/null and b/assets/images/ios.png differ diff --git a/assets/images/loginLogo.png b/assets/images/loginLogo.png new file mode 100644 index 00000000000..332881b2ad3 Binary files /dev/null and b/assets/images/loginLogo.png differ diff --git a/assets/images/logo.png b/assets/images/logo.png new file mode 100644 index 00000000000..e2ab02a7522 Binary files /dev/null and b/assets/images/logo.png differ diff --git a/assets/images/phoneImage.png b/assets/images/phoneImage.png new file mode 100644 index 00000000000..949173e7366 Binary files /dev/null and b/assets/images/phoneImage.png differ diff --git a/assets/images/silvia.png b/assets/images/silvia.png new file mode 100644 index 00000000000..218880a4dca Binary files /dev/null and b/assets/images/silvia.png differ diff --git a/build-release.sh b/build-release.sh old mode 100755 new mode 100644 diff --git a/composer.json b/composer.json index 39c7e77c4d9..4a1b33313c4 100644 --- a/composer.json +++ b/composer.json @@ -5,13 +5,13 @@ "homepage": "https://codeigniter.com", "license": "MIT", "support": { - "forum": "https://forum.codeigniter.com/", + "forum": "http://forum.codeigniter.com/", "wiki": "https://github.com/bcit-ci/CodeIgniter/wiki", "slack": "https://codeigniterchat.slack.com", "source": "https://github.com/bcit-ci/CodeIgniter" }, "require": { - "php": ">=5.4.8" + "php": ">=5.3.7" }, "suggest": { "paragonie/random_compat": "Provides better randomness in PHP 5.x" diff --git a/contributing.md b/contributing.md index 8f43c45a652..703fe8f44a2 100644 --- a/contributing.md +++ b/contributing.md @@ -28,14 +28,14 @@ If you change anything that requires a change to documentation then you will nee ### Compatibility -CodeIgniter recommends PHP 5.5 or newer to be used, but it should be +CodeIgniter recommends PHP 5.4 or newer to be used, but it should be compatible with PHP 5.2.4 so all code supplied must stick to this requirement. If PHP 5.3 (and above) functions or features are used then there must be a fallback for PHP 5.2.4. ### Branching -CodeIgniter uses the [Git-Flow](https://nvie.com/posts/a-successful-git-branching-model/) branching model which requires all pull requests to be sent to the "develop" branch. This is +CodeIgniter uses the [Git-Flow](http://nvie.com/posts/a-successful-git-branching-model/) branching model which requires all pull requests to be sent to the "develop" branch. This is where the next planned version will be developed. The "master" branch will always contain the latest stable version and is kept clean so a "hotfix" (e.g: an emergency security patch) can be applied to master to create a new version, without worrying about other features holding it up. For this reason all commits need to be made to "develop" and any sent to "master" will be closed automatically. If you have multiple changes to submit, please place all changes into their own branch on your fork. One thing at a time: A pull request should only contain one change. That does not mean only one commit, but one change - however many commits it took. The reason for this is that if you change X and Y but send a pull request for both at the same time, we might really want X but disagree with Y, meaning we cannot merge the request. Using the Git-Flow branching model you can create new branches for both of these features and send two requests. @@ -54,7 +54,7 @@ This will sign your commits with the information setup in your git config, e.g. `Signed-off-by: John Q Public ` -If you are using [Tower](https://www.git-tower.com/) there is a "Sign-Off" checkbox in the commit window. You could even alias git commit to use the `-s` flag so you don’t have to think about it. +If you are using [Tower](http://www.git-tower.com/) there is a "Sign-Off" checkbox in the commit window. You could even alias git commit to use the `-s` flag so you don’t have to think about it. By signing your work in this manner, you certify to a "Developer's Certificate of Origin". The current version of this certificate is in the `DCO.txt` file in the root of this repository. diff --git a/database/insta.sql b/database/insta.sql new file mode 100644 index 00000000000..f1361d8c2ac --- /dev/null +++ b/database/insta.sql @@ -0,0 +1,123 @@ +-- phpMyAdmin SQL Dump +-- version 4.9.1 +-- https://www.phpmyadmin.net/ +-- +-- Host: localhost +-- Generation Time: Apr 18, 2020 at 03:33 PM +-- Server version: 10.4.8-MariaDB +-- PHP Version: 7.1.32 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET AUTOCOMMIT = 0; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `insta` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `photo` +-- + +CREATE TABLE `photo` ( + `id` int(11) NOT NULL, + `url` varchar(30) NOT NULL, + `caption` varchar(100) NOT NULL, + `like` bigint(255) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Dumping data for table `photo` +-- + +INSERT INTO `photo` (`id`, `url`, `caption`, `like`) VALUES +(1, 'silvia.png', 'kok bisa?', 696969), +(2, 'gabungan.png', 'lah kok bisa???', 6969); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `profile` +-- + +CREATE TABLE `profile` ( + `name` varchar(25) NOT NULL, + `username` varchar(25) NOT NULL, + `website` varchar(30) NOT NULL, + `bio` varchar(100) NOT NULL, + `email` varchar(30) NOT NULL, + `phonenumber` varchar(12) NOT NULL, + `gender` varchar(6) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Dumping data for table `profile` +-- + +INSERT INTO `profile` (`name`, `username`, `website`, `bio`, `email`, `phonenumber`, `gender`) VALUES +('Muhammad Farrel', 'farrelm__', 'muhammadfarrel.github.io', 'phusying rek', 'farrel@gmail.com', '08114551997', 'male'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user` +-- + +CREATE TABLE `user` ( + `username` varchar(25) NOT NULL, + `password` varchar(50) NOT NULL, + `email` varchar(30) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Dumping data for table `user` +-- + +INSERT INTO `user` (`username`, `password`, `email`) VALUES +('farrelm__', '123', 'farrel@gmail.com'); + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `photo` +-- +ALTER TABLE `photo` + ADD PRIMARY KEY (`id`); + +-- +-- Indexes for table `profile` +-- +ALTER TABLE `profile` + ADD PRIMARY KEY (`username`); + +-- +-- Indexes for table `user` +-- +ALTER TABLE `user` + ADD PRIMARY KEY (`username`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `photo` +-- +ALTER TABLE `photo` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/index.php b/index.php old mode 100755 new mode 100644 index e7aab3b0381..e50550472ae --- a/index.php +++ b/index.php @@ -73,7 +73,14 @@ case 'testing': case 'production': ini_set('display_errors', 0); - error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED); + if (version_compare(PHP_VERSION, '5.3', '>=')) + { + error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED); + } + else + { + error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE); + } break; default: diff --git a/readme.rst b/readme.rst index 3e1382fbd8a..b6520080e91 100644 --- a/readme.rst +++ b/readme.rst @@ -31,7 +31,7 @@ Server Requirements PHP version 5.6 or newer is recommended. -It should work on 5.4.8 as well, but we strongly advise you NOT to run +It should work on 5.3.7 as well, but we strongly advise you NOT to run such old versions of PHP, because of potential security and performance issues, as well as missing features. @@ -55,7 +55,7 @@ Resources - `User Guide `_ - `Language File Translations `_ -- `Community Forums `_ +- `Community Forums `_ - `Community Wiki `_ - `Community Slack Channel `_ diff --git a/system/database/drivers/sqlite/index.html b/system/database/drivers/sqlite/index.html new file mode 100644 index 00000000000..b702fbc3967 --- /dev/null +++ b/system/database/drivers/sqlite/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php new file mode 100644 index 00000000000..aec3d748c14 --- /dev/null +++ b/system/database/drivers/sqlite/sqlite_driver.php @@ -0,0 +1,330 @@ +database, 0666, $error) + : sqlite_open($this->database, 0666, $error); + + isset($error) && log_message('error', $error); + + return $conn_id; + } + + // -------------------------------------------------------------------- + + /** + * Database version number + * + * @return string + */ + public function version() + { + return isset($this->data_cache['version']) + ? $this->data_cache['version'] + : $this->data_cache['version'] = sqlite_libversion(); + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @param string $sql an SQL query + * @return resource + */ + protected function _execute($sql) + { + return $this->is_write_type($sql) + ? sqlite_exec($this->conn_id, $sql) + : sqlite_query($this->conn_id, $sql); + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return bool + */ + protected function _trans_begin() + { + return $this->simple_query('BEGIN TRANSACTION'); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return bool + */ + protected function _trans_commit() + { + return $this->simple_query('COMMIT'); + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return bool + */ + protected function _trans_rollback() + { + return $this->simple_query('ROLLBACK'); + } + + // -------------------------------------------------------------------- + + /** + * Platform-dependant string escape + * + * @param string + * @return string + */ + protected function _escape_str($str) + { + return sqlite_escape_string($str); + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @return int + */ + public function affected_rows() + { + return sqlite_changes($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @return int + */ + public function insert_id() + { + return sqlite_last_insert_rowid($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @param bool $prefix_limit + * @return string + */ + protected function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT name FROM sqlite_master WHERE type='table'"; + + if ($prefix_limit !== FALSE && $this->dbprefix != '') + { + return $sql." AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr); + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @param string $table + * @return bool + */ + protected function _list_columns($table = '') + { + // Not supported + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Returns an object with field data + * + * @param string $table + * @return array + */ + public function field_data($table) + { + if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE) + { + return FALSE; + } + + $query = $query->result_array(); + if (empty($query)) + { + return FALSE; + } + + $retval = array(); + for ($i = 0, $c = count($query); $i < $c; $i++) + { + $retval[$i] = new stdClass(); + $retval[$i]->name = $query[$i]['name']; + $retval[$i]->type = $query[$i]['type']; + $retval[$i]->max_length = NULL; + $retval[$i]->default = $query[$i]['dflt_value']; + $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Error + * + * Returns an array containing code and message of the last + * database error that has occured. + * + * @return array + */ + public function error() + { + $error = array('code' => sqlite_last_error($this->conn_id)); + $error['message'] = sqlite_error_string($error['code']); + return $error; + } + + // -------------------------------------------------------------------- + + /** + * Replace statement + * + * Generates a platform-specific replace string from the supplied data + * + * @param string $table Table name + * @param array $keys INSERT keys + * @param array $values INSERT values + * @return string + */ + protected function _replace($table, $keys, $values) + { + return 'INSERT OR '.parent::_replace($table, $keys, $values); + } + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * + * If the database does not support the TRUNCATE statement, + * then this function maps to 'DELETE FROM table' + * + * @param string $table + * @return string + */ + protected function _truncate($table) + { + return 'DELETE FROM '.$table; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @return void + */ + protected function _close() + { + sqlite_close($this->conn_id); + } + +} diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php new file mode 100644 index 00000000000..6aa9c61c473 --- /dev/null +++ b/system/database/drivers/sqlite/sqlite_forge.php @@ -0,0 +1,205 @@ +db->database) OR ! @unlink($this->db->database)) + { + return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE; + } + elseif ( ! empty($this->db->data_cache['db_names'])) + { + $key = array_search(strtolower($this->db->database), array_map('strtolower', $this->db->data_cache['db_names']), TRUE); + if ($key !== FALSE) + { + unset($this->db->data_cache['db_names'][$key]); + } + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * ALTER TABLE + * + * @todo implement drop_column(), modify_column() + * @param string $alter_type ALTER type + * @param string $table Table name + * @param mixed $field Column definition + * @return string|string[] + */ + protected function _alter_table($alter_type, $table, $field) + { + if ($alter_type === 'DROP' OR $alter_type === 'CHANGE') + { + // drop_column(): + // BEGIN TRANSACTION; + // CREATE TEMPORARY TABLE t1_backup(a,b); + // INSERT INTO t1_backup SELECT a,b FROM t1; + // DROP TABLE t1; + // CREATE TABLE t1(a,b); + // INSERT INTO t1 SELECT a,b FROM t1_backup; + // DROP TABLE t1_backup; + // COMMIT; + + return FALSE; + } + + return parent::_alter_table($alter_type, $table, $field); + } + + // -------------------------------------------------------------------- + + /** + * Process column + * + * @param array $field + * @return string + */ + protected function _process_column($field) + { + return $this->db->escape_identifiers($field['name']) + .' '.$field['type'] + .$field['auto_increment'] + .$field['null'] + .$field['unique'] + .$field['default']; + } + + // -------------------------------------------------------------------- + + /** + * Field attribute TYPE + * + * Performs a data type mapping between different databases. + * + * @param array &$attributes + * @return void + */ + protected function _attr_type(&$attributes) + { + switch (strtoupper($attributes['TYPE'])) + { + case 'ENUM': + case 'SET': + $attributes['TYPE'] = 'TEXT'; + return; + default: return; + } + } + + // -------------------------------------------------------------------- + + /** + * Field attribute AUTO_INCREMENT + * + * @param array &$attributes + * @param array &$field + * @return void + */ + protected function _attr_auto_increment(&$attributes, &$field) + { + if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE && stripos($field['type'], 'int') !== FALSE) + { + $field['type'] = 'INTEGER PRIMARY KEY'; + $field['default'] = ''; + $field['null'] = ''; + $field['unique'] = ''; + $field['auto_increment'] = ' AUTOINCREMENT'; + + $this->primary_keys = array(); + } + } + +} diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php new file mode 100644 index 00000000000..30c93a26fa0 --- /dev/null +++ b/system/database/drivers/sqlite/sqlite_result.php @@ -0,0 +1,164 @@ +num_rows) + ? $this->num_rows + : $this->num_rows = @sqlite_num_rows($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @return int + */ + public function num_fields() + { + return @sqlite_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @return array + */ + public function list_fields() + { + $field_names = array(); + for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) + { + $field_names[$i] = sqlite_field_name($this->result_id, $i); + } + + return $field_names; + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @return array + */ + public function field_data() + { + $retval = array(); + for ($i = 0, $c = $this->num_fields(); $i < $c; $i++) + { + $retval[$i] = new stdClass(); + $retval[$i]->name = sqlite_field_name($this->result_id, $i); + $retval[$i]->type = NULL; + $retval[$i]->max_length = NULL; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero. + * + * @param int $n + * @return bool + */ + public function data_seek($n = 0) + { + return sqlite_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @return array + */ + protected function _fetch_assoc() + { + return sqlite_fetch_array($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @param string $class_name + * @return object + */ + protected function _fetch_object($class_name = 'stdClass') + { + return sqlite_fetch_object($this->result_id, $class_name); + } + +} diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php new file mode 100644 index 00000000000..2c7f8099ecf --- /dev/null +++ b/system/database/drivers/sqlite/sqlite_utility.php @@ -0,0 +1,61 @@ +db->display_error('db_unsupported_feature'); + } + +} diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php new file mode 100644 index 00000000000..b25875974d3 --- /dev/null +++ b/system/helpers/email_helper.php @@ -0,0 +1,84 @@ +field_id pairs + * @param string field_id if alias name was passed in + * @param bool + * @return array + */ + function smiley_js($alias = '', $field_id = '', $inline = TRUE) + { + static $do_setup = TRUE; + $r = ''; + + if ($alias !== '' && ! is_array($alias)) + { + $alias = array($alias => $field_id); + } + + if ($do_setup === TRUE) + { + $do_setup = FALSE; + $m = array(); + + if (is_array($alias)) + { + foreach ($alias as $name => $id) + { + $m[] = '"'.$name.'" : "'.$id.'"'; + } + } + + $m = '{'.implode(',', $m).'}'; + + $r .= << $id) + { + $r .= 'smiley_map["'.$name.'"] = "'.$id."\";\n"; + } + } + + return ($inline) + ? '' + : $r; + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('get_clickable_smileys')) +{ + /** + * Get Clickable Smileys + * + * Returns an array of image tag links that can be clicked to be inserted + * into a form field. + * + * @param string the URL to the folder containing the smiley images + * @param array + * @return array + */ + function get_clickable_smileys($image_url, $alias = '') + { + // For backward compatibility with js_insert_smiley + if (is_array($alias)) + { + $smileys = $alias; + } + elseif (FALSE === ($smileys = _get_smiley_array())) + { + return FALSE; + } + + // Add a trailing slash to the file path if needed + $image_url = rtrim($image_url, '/').'/'; + + $used = array(); + foreach ($smileys as $key => $val) + { + // Keep duplicates from being used, which can happen if the + // mapping array contains multiple identical replacements. For example: + // :-) and :) might be replaced with the same image so both smileys + // will be in the array. + if (isset($used[$smileys[$key][0]])) + { + continue; + } + + $link[] = ''.$smileys[$key][3].''; + $used[$smileys[$key][0]] = TRUE; + } + + return $link; + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('parse_smileys')) +{ + /** + * Parse Smileys + * + * Takes a string as input and swaps any contained smileys for the actual image + * + * @param string the text to be parsed + * @param string the URL to the folder containing the smiley images + * @param array + * @return string + */ + function parse_smileys($str = '', $image_url = '', $smileys = NULL) + { + if ($image_url === '' OR ( ! is_array($smileys) && FALSE === ($smileys = _get_smiley_array()))) + { + return $str; + } + + // Add a trailing slash to the file path if needed + $image_url = rtrim($image_url, '/').'/'; + + foreach ($smileys as $key => $val) + { + $str = str_replace($key, ''.$smileys[$key][3].'', $str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +if ( ! function_exists('_get_smiley_array')) +{ + /** + * Get Smiley Array + * + * Fetches the config/smiley.php file + * + * @return mixed + */ + function _get_smiley_array() + { + static $_smileys; + + if ( ! is_array($_smileys)) + { + if (file_exists(APPPATH.'config/smileys.php')) + { + include(APPPATH.'config/smileys.php'); + } + + if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys.php')) + { + include(APPPATH.'config/'.ENVIRONMENT.'/smileys.php'); + } + + if (empty($smileys) OR ! is_array($smileys)) + { + $_smileys = array(); + return FALSE; + } + + $_smileys = $smileys; + } + + return $_smileys; + } +} diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php new file mode 100644 index 00000000000..6a107752caf --- /dev/null +++ b/system/libraries/Cart.php @@ -0,0 +1,567 @@ +CI =& get_instance(); + + // Are any config settings being passed manually? If so, set them + $config = is_array($params) ? $params : array(); + + // Load the Sessions class + $this->CI->load->driver('session', $config); + + // Grab the shopping cart array from the session table + $this->_cart_contents = $this->CI->session->userdata('cart_contents'); + if ($this->_cart_contents === NULL) + { + // No cart exists so we'll set some base values + $this->_cart_contents = array('cart_total' => 0, 'total_items' => 0); + } + + log_message('info', 'Cart Class Initialized'); + } + + // -------------------------------------------------------------------- + + /** + * Insert items into the cart and save it to the session table + * + * @param array + * @return bool + */ + public function insert($items = array()) + { + // Was any cart data passed? No? Bah... + if ( ! is_array($items) OR count($items) === 0) + { + log_message('error', 'The insert method must be passed an array containing data.'); + return FALSE; + } + + // You can either insert a single product using a one-dimensional array, + // or multiple products using a multi-dimensional one. The way we + // determine the array type is by looking for a required array key named "id" + // at the top level. If it's not found, we will assume it's a multi-dimensional array. + + $save_cart = FALSE; + if (isset($items['id'])) + { + if (($rowid = $this->_insert($items))) + { + $save_cart = TRUE; + } + } + else + { + foreach ($items as $val) + { + if (is_array($val) && isset($val['id'])) + { + if ($this->_insert($val)) + { + $save_cart = TRUE; + } + } + } + } + + // Save the cart data if the insert was successful + if ($save_cart === TRUE) + { + $this->_save_cart(); + return isset($rowid) ? $rowid : TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Insert + * + * @param array + * @return bool + */ + protected function _insert($items = array()) + { + // Was any cart data passed? No? Bah... + if ( ! is_array($items) OR count($items) === 0) + { + log_message('error', 'The insert method must be passed an array containing data.'); + return FALSE; + } + + // -------------------------------------------------------------------- + + // Does the $items array contain an id, quantity, price, and name? These are required + if ( ! isset($items['id'], $items['qty'], $items['price'], $items['name'])) + { + log_message('error', 'The cart array must contain a product ID, quantity, price, and name.'); + return FALSE; + } + + // -------------------------------------------------------------------- + + // Prep the quantity. It can only be a number. Duh... also trim any leading zeros + $items['qty'] = (float) $items['qty']; + + // If the quantity is zero or blank there's nothing for us to do + if ($items['qty'] == 0) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + // Validate the product ID. It can only be alpha-numeric, dashes, underscores or periods + // Not totally sure we should impose this rule, but it seems prudent to standardize IDs. + // Note: These can be user-specified by setting the $this->product_id_rules variable. + if ( ! preg_match('/^['.$this->product_id_rules.']+$/i', $items['id'])) + { + log_message('error', 'Invalid product ID. The product ID can only contain alpha-numeric characters, dashes, and underscores'); + return FALSE; + } + + // -------------------------------------------------------------------- + + // Validate the product name. It can only be alpha-numeric, dashes, underscores, colons or periods. + // Note: These can be user-specified by setting the $this->product_name_rules variable. + if ($this->product_name_safe && ! preg_match('/^['.$this->product_name_rules.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $items['name'])) + { + log_message('error', 'An invalid name was submitted as the product name: '.$items['name'].' The name can only contain alpha-numeric characters, dashes, underscores, colons, and spaces'); + return FALSE; + } + + // -------------------------------------------------------------------- + + // Prep the price. Remove leading zeros and anything that isn't a number or decimal point. + $items['price'] = (float) $items['price']; + + // We now need to create a unique identifier for the item being inserted into the cart. + // Every time something is added to the cart it is stored in the master cart array. + // Each row in the cart array, however, must have a unique index that identifies not only + // a particular product, but makes it possible to store identical products with different options. + // For example, what if someone buys two identical t-shirts (same product ID), but in + // different sizes? The product ID (and other attributes, like the name) will be identical for + // both sizes because it's the same shirt. The only difference will be the size. + // Internally, we need to treat identical submissions, but with different options, as a unique product. + // Our solution is to convert the options array to a string and MD5 it along with the product ID. + // This becomes the unique "row ID" + if (isset($items['options']) && count($items['options']) > 0) + { + $rowid = md5($items['id'].serialize($items['options'])); + } + else + { + // No options were submitted so we simply MD5 the product ID. + // Technically, we don't need to MD5 the ID in this case, but it makes + // sense to standardize the format of array indexes for both conditions + $rowid = md5($items['id']); + } + + // -------------------------------------------------------------------- + + // Now that we have our unique "row ID", we'll add our cart items to the master array + // grab quantity if it's already there and add it on + $old_quantity = isset($this->_cart_contents[$rowid]['qty']) ? (int) $this->_cart_contents[$rowid]['qty'] : 0; + + // Re-create the entry, just to make sure our index contains only the data from this submission + $items['rowid'] = $rowid; + $items['qty'] += $old_quantity; + $this->_cart_contents[$rowid] = $items; + + return $rowid; + } + + // -------------------------------------------------------------------- + + /** + * Update the cart + * + * This function permits the quantity of a given item to be changed. + * Typically it is called from the "view cart" page if a user makes + * changes to the quantity before checkout. That array must contain the + * product ID and quantity for each item. + * + * @param array + * @return bool + */ + public function update($items = array()) + { + // Was any cart data passed? + if ( ! is_array($items) OR count($items) === 0) + { + return FALSE; + } + + // You can either update a single product using a one-dimensional array, + // or multiple products using a multi-dimensional one. The way we + // determine the array type is by looking for a required array key named "rowid". + // If it's not found we assume it's a multi-dimensional array + $save_cart = FALSE; + if (isset($items['rowid'])) + { + if ($this->_update($items) === TRUE) + { + $save_cart = TRUE; + } + } + else + { + foreach ($items as $val) + { + if (is_array($val) && isset($val['rowid'])) + { + if ($this->_update($val) === TRUE) + { + $save_cart = TRUE; + } + } + } + } + + // Save the cart data if the insert was successful + if ($save_cart === TRUE) + { + $this->_save_cart(); + return TRUE; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Update the cart + * + * This function permits changing item properties. + * Typically it is called from the "view cart" page if a user makes + * changes to the quantity before checkout. That array must contain the + * rowid and quantity for each item. + * + * @param array + * @return bool + */ + protected function _update($items = array()) + { + // Without these array indexes there is nothing we can do + if ( ! isset($items['rowid'], $this->_cart_contents[$items['rowid']])) + { + return FALSE; + } + + // Prep the quantity + if (isset($items['qty'])) + { + $items['qty'] = (float) $items['qty']; + // Is the quantity zero? If so we will remove the item from the cart. + // If the quantity is greater than zero we are updating + if ($items['qty'] == 0) + { + unset($this->_cart_contents[$items['rowid']]); + return TRUE; + } + } + + // find updatable keys + $keys = array_intersect(array_keys($this->_cart_contents[$items['rowid']]), array_keys($items)); + // if a price was passed, make sure it contains valid data + if (isset($items['price'])) + { + $items['price'] = (float) $items['price']; + } + + // product id & name shouldn't be changed + foreach (array_diff($keys, array('id', 'name')) as $key) + { + $this->_cart_contents[$items['rowid']][$key] = $items[$key]; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Save the cart array to the session DB + * + * @return bool + */ + protected function _save_cart() + { + // Let's add up the individual prices and set the cart sub-total + $this->_cart_contents['total_items'] = $this->_cart_contents['cart_total'] = 0; + foreach ($this->_cart_contents as $key => $val) + { + // We make sure the array contains the proper indexes + if ( ! is_array($val) OR ! isset($val['price'], $val['qty'])) + { + continue; + } + + $this->_cart_contents['cart_total'] += ($val['price'] * $val['qty']); + $this->_cart_contents['total_items'] += $val['qty']; + $this->_cart_contents[$key]['subtotal'] = ($this->_cart_contents[$key]['price'] * $this->_cart_contents[$key]['qty']); + } + + // Is our cart empty? If so we delete it from the session + if (count($this->_cart_contents) <= 2) + { + $this->CI->session->unset_userdata('cart_contents'); + + // Nothing more to do... coffee time! + return FALSE; + } + + // If we made it this far it means that our cart has data. + // Let's pass it to the Session class so it can be stored + $this->CI->session->set_userdata(array('cart_contents' => $this->_cart_contents)); + + // Woot! + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Cart Total + * + * @return int + */ + public function total() + { + return $this->_cart_contents['cart_total']; + } + + // -------------------------------------------------------------------- + + /** + * Remove Item + * + * Removes an item from the cart + * + * @param int + * @return bool + */ + public function remove($rowid) + { + // unset & save + unset($this->_cart_contents[$rowid]); + $this->_save_cart(); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Total Items + * + * Returns the total item count + * + * @return int + */ + public function total_items() + { + return $this->_cart_contents['total_items']; + } + + // -------------------------------------------------------------------- + + /** + * Cart Contents + * + * Returns the entire cart array + * + * @param bool + * @return array + */ + public function contents($newest_first = FALSE) + { + // do we want the newest first? + $cart = ($newest_first) ? array_reverse($this->_cart_contents) : $this->_cart_contents; + + // Remove these so they don't create a problem when showing the cart table + unset($cart['total_items']); + unset($cart['cart_total']); + + return $cart; + } + + // -------------------------------------------------------------------- + + /** + * Get cart item + * + * Returns the details of a specific item in the cart + * + * @param string $row_id + * @return array + */ + public function get_item($row_id) + { + return (in_array($row_id, array('total_items', 'cart_total'), TRUE) OR ! isset($this->_cart_contents[$row_id])) + ? FALSE + : $this->_cart_contents[$row_id]; + } + + // -------------------------------------------------------------------- + + /** + * Has options + * + * Returns TRUE if the rowid passed to this function correlates to an item + * that has options associated with it. + * + * @param string $row_id = '' + * @return bool + */ + public function has_options($row_id = '') + { + return (isset($this->_cart_contents[$row_id]['options']) && count($this->_cart_contents[$row_id]['options']) !== 0); + } + + // -------------------------------------------------------------------- + + /** + * Product options + * + * Returns the an array of options, for a particular product row ID + * + * @param string $row_id = '' + * @return array + */ + public function product_options($row_id = '') + { + return isset($this->_cart_contents[$row_id]['options']) ? $this->_cart_contents[$row_id]['options'] : array(); + } + + // -------------------------------------------------------------------- + + /** + * Format Number + * + * Returns the supplied number with commas and a decimal point. + * + * @param float + * @return string + */ + public function format_number($n = '') + { + return ($n === '') ? '' : number_format( (float) $n, 2, '.', ','); + } + + // -------------------------------------------------------------------- + + /** + * Destroy the cart + * + * Empties the cart and kills the session + * + * @return void + */ + public function destroy() + { + $this->_cart_contents = array('cart_total' => 0, 'total_items' => 0); + $this->CI->session->unset_userdata('cart_contents'); + } + +} diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php new file mode 100644 index 00000000000..c9103945b73 --- /dev/null +++ b/system/libraries/Javascript.php @@ -0,0 +1,856 @@ + 'jquery', 'autoload' => TRUE); + + foreach ($defaults as $key => $val) + { + if (isset($params[$key]) && $params[$key] !== '') + { + $defaults[$key] = $params[$key]; + } + } + + extract($defaults); + + $this->CI =& get_instance(); + + // load the requested js library + $this->CI->load->library('Javascript/'.$js_library_driver, array('autoload' => $autoload)); + // make js to refer to current library + $this->js =& $this->CI->$js_library_driver; + + log_message('info', 'Javascript Class Initialized and loaded. Driver used: '.$js_library_driver); + } + + // -------------------------------------------------------------------- + // Event Code + // -------------------------------------------------------------------- + + /** + * Blur + * + * Outputs a javascript library blur event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function blur($element = 'this', $js = '') + { + return $this->js->_blur($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Change + * + * Outputs a javascript library change event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function change($element = 'this', $js = '') + { + return $this->js->_change($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Click + * + * Outputs a javascript library click event + * + * @param string The element to attach the event to + * @param string The code to execute + * @param bool whether or not to return false + * @return string + */ + public function click($element = 'this', $js = '', $ret_false = TRUE) + { + return $this->js->_click($element, $js, $ret_false); + } + + // -------------------------------------------------------------------- + + /** + * Double Click + * + * Outputs a javascript library dblclick event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function dblclick($element = 'this', $js = '') + { + return $this->js->_dblclick($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Error + * + * Outputs a javascript library error event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function error($element = 'this', $js = '') + { + return $this->js->_error($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Focus + * + * Outputs a javascript library focus event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function focus($element = 'this', $js = '') + { + return $this->js->_focus($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Hover + * + * Outputs a javascript library hover event + * + * @param string - element + * @param string - Javascript code for mouse over + * @param string - Javascript code for mouse out + * @return string + */ + public function hover($element = 'this', $over = '', $out = '') + { + return $this->js->_hover($element, $over, $out); + } + + // -------------------------------------------------------------------- + + /** + * Keydown + * + * Outputs a javascript library keydown event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function keydown($element = 'this', $js = '') + { + return $this->js->_keydown($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Keyup + * + * Outputs a javascript library keydown event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function keyup($element = 'this', $js = '') + { + return $this->js->_keyup($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Load + * + * Outputs a javascript library load event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function load($element = 'this', $js = '') + { + return $this->js->_load($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Mousedown + * + * Outputs a javascript library mousedown event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function mousedown($element = 'this', $js = '') + { + return $this->js->_mousedown($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Mouse Out + * + * Outputs a javascript library mouseout event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function mouseout($element = 'this', $js = '') + { + return $this->js->_mouseout($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Mouse Over + * + * Outputs a javascript library mouseover event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function mouseover($element = 'this', $js = '') + { + return $this->js->_mouseover($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Mouseup + * + * Outputs a javascript library mouseup event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function mouseup($element = 'this', $js = '') + { + return $this->js->_mouseup($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Output + * + * Outputs the called javascript to the screen + * + * @param string The code to output + * @return string + */ + public function output($js) + { + return $this->js->_output($js); + } + + // -------------------------------------------------------------------- + + /** + * Ready + * + * Outputs a javascript library mouseup event + * + * @param string $js Code to execute + * @return string + */ + public function ready($js) + { + return $this->js->_document_ready($js); + } + + // -------------------------------------------------------------------- + + /** + * Resize + * + * Outputs a javascript library resize event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function resize($element = 'this', $js = '') + { + return $this->js->_resize($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Scroll + * + * Outputs a javascript library scroll event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function scroll($element = 'this', $js = '') + { + return $this->js->_scroll($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Unload + * + * Outputs a javascript library unload event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + public function unload($element = 'this', $js = '') + { + return $this->js->_unload($element, $js); + } + + // -------------------------------------------------------------------- + // Effects + // -------------------------------------------------------------------- + + /** + * Add Class + * + * Outputs a javascript library addClass event + * + * @param string - element + * @param string - Class to add + * @return string + */ + public function addClass($element = 'this', $class = '') + { + return $this->js->_addClass($element, $class); + } + + // -------------------------------------------------------------------- + + /** + * Animate + * + * Outputs a javascript library animate event + * + * @param string $element = 'this' + * @param array $params = array() + * @param mixed $speed 'slow', 'normal', 'fast', or time in milliseconds + * @param string $extra + * @return string + */ + public function animate($element = 'this', $params = array(), $speed = '', $extra = '') + { + return $this->js->_animate($element, $params, $speed, $extra); + } + + // -------------------------------------------------------------------- + + /** + * Fade In + * + * Outputs a javascript library hide event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + public function fadeIn($element = 'this', $speed = '', $callback = '') + { + return $this->js->_fadeIn($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Fade Out + * + * Outputs a javascript library hide event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + public function fadeOut($element = 'this', $speed = '', $callback = '') + { + return $this->js->_fadeOut($element, $speed, $callback); + } + // -------------------------------------------------------------------- + + /** + * Slide Up + * + * Outputs a javascript library slideUp event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + public function slideUp($element = 'this', $speed = '', $callback = '') + { + return $this->js->_slideUp($element, $speed, $callback); + + } + + // -------------------------------------------------------------------- + + /** + * Remove Class + * + * Outputs a javascript library removeClass event + * + * @param string - element + * @param string - Class to add + * @return string + */ + public function removeClass($element = 'this', $class = '') + { + return $this->js->_removeClass($element, $class); + } + + // -------------------------------------------------------------------- + + /** + * Slide Down + * + * Outputs a javascript library slideDown event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + public function slideDown($element = 'this', $speed = '', $callback = '') + { + return $this->js->_slideDown($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Slide Toggle + * + * Outputs a javascript library slideToggle event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + public function slideToggle($element = 'this', $speed = '', $callback = '') + { + return $this->js->_slideToggle($element, $speed, $callback); + + } + + // -------------------------------------------------------------------- + + /** + * Hide + * + * Outputs a javascript library hide action + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + public function hide($element = 'this', $speed = '', $callback = '') + { + return $this->js->_hide($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Toggle + * + * Outputs a javascript library toggle event + * + * @param string - element + * @return string + */ + public function toggle($element = 'this') + { + return $this->js->_toggle($element); + + } + + // -------------------------------------------------------------------- + + /** + * Toggle Class + * + * Outputs a javascript library toggle class event + * + * @param string $element = 'this' + * @param string $class = '' + * @return string + */ + public function toggleClass($element = 'this', $class = '') + { + return $this->js->_toggleClass($element, $class); + } + + // -------------------------------------------------------------------- + + /** + * Show + * + * Outputs a javascript library show event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + public function show($element = 'this', $speed = '', $callback = '') + { + return $this->js->_show($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Compile + * + * gather together all script needing to be output + * + * @param string $view_var + * @param bool $script_tags + * @return string + */ + public function compile($view_var = 'script_foot', $script_tags = TRUE) + { + $this->js->_compile($view_var, $script_tags); + } + + // -------------------------------------------------------------------- + + /** + * Clear Compile + * + * Clears any previous javascript collected for output + * + * @return void + */ + public function clear_compile() + { + $this->js->_clear_compile(); + } + + // -------------------------------------------------------------------- + + /** + * External + * + * Outputs a + * + * @param string + * @return string + */ + protected function _close_script($extra = "\n") + { + return ''.$extra; + } + + // -------------------------------------------------------------------- + // AJAX-Y STUFF - still a testbed + // -------------------------------------------------------------------- + + /** + * Update + * + * Outputs a javascript library slideDown event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + public function update($element = 'this', $speed = '', $callback = '') + { + return $this->js->_updater($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Generate JSON + * + * Can be passed a database result or associative array and returns a JSON formatted string + * + * @param mixed result set or array + * @param bool match array types (defaults to objects) + * @return string a json formatted string + */ + public function generate_json($result = NULL, $match_array_type = FALSE) + { + // JSON data can optionally be passed to this function + // either as a database result object or an array, or a user supplied array + if ($result !== NULL) + { + if (is_object($result)) + { + $json_result = is_callable(array($result, 'result_array')) ? $result->result_array() : (array) $result; + } + elseif (is_array($result)) + { + $json_result = $result; + } + else + { + return $this->_prep_args($result); + } + } + else + { + return 'null'; + } + + $json = array(); + $_is_assoc = TRUE; + + if ( ! is_array($json_result) && empty($json_result)) + { + show_error('Generate JSON Failed - Illegal key, value pair.'); + } + elseif ($match_array_type) + { + $_is_assoc = $this->_is_associative_array($json_result); + } + + foreach ($json_result as $k => $v) + { + if ($_is_assoc) + { + $json[] = $this->_prep_args($k, TRUE).':'.$this->generate_json($v, $match_array_type); + } + else + { + $json[] = $this->generate_json($v, $match_array_type); + } + } + + $json = implode(',', $json); + + return $_is_assoc ? '{'.$json.'}' : '['.$json.']'; + + } + + // -------------------------------------------------------------------- + + /** + * Is associative array + * + * Checks for an associative array + * + * @param array + * @return bool + */ + protected function _is_associative_array($arr) + { + foreach (array_keys($arr) as $key => $val) + { + if ($key !== $val) + { + return TRUE; + } + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Prep Args + * + * Ensures a standard json value and escapes values + * + * @param mixed $result + * @param bool $is_key = FALSE + * @return string + */ + protected function _prep_args($result, $is_key = FALSE) + { + if ($result === NULL) + { + return 'null'; + } + elseif (is_bool($result)) + { + return ($result === TRUE) ? 'true' : 'false'; + } + elseif (is_string($result) OR $is_key) + { + return '"'.str_replace(array('\\', "\t", "\n", "\r", '"', '/'), array('\\\\', '\\t', '\\n', "\\r", '\"', '\/'), $result).'"'; + } + elseif (is_scalar($result)) + { + return $result; + } + } + +} diff --git a/system/libraries/Javascript/Jquery.php b/system/libraries/Javascript/Jquery.php new file mode 100644 index 00000000000..485d1dc1819 --- /dev/null +++ b/system/libraries/Javascript/Jquery.php @@ -0,0 +1,1076 @@ +CI =& get_instance(); + extract($params); + + if ($autoload === TRUE) + { + $this->script(); + } + + log_message('info', 'Jquery Class Initialized'); + } + + // -------------------------------------------------------------------- + // Event Code + // -------------------------------------------------------------------- + + /** + * Blur + * + * Outputs a jQuery blur event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _blur($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'blur'); + } + + // -------------------------------------------------------------------- + + /** + * Change + * + * Outputs a jQuery change event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _change($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'change'); + } + + // -------------------------------------------------------------------- + + /** + * Click + * + * Outputs a jQuery click event + * + * @param string The element to attach the event to + * @param string The code to execute + * @param bool whether or not to return false + * @return string + */ + protected function _click($element = 'this', $js = '', $ret_false = TRUE) + { + is_array($js) OR $js = array($js); + + if ($ret_false) + { + $js[] = 'return false;'; + } + + return $this->_add_event($element, $js, 'click'); + } + + // -------------------------------------------------------------------- + + /** + * Double Click + * + * Outputs a jQuery dblclick event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _dblclick($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'dblclick'); + } + + // -------------------------------------------------------------------- + + /** + * Error + * + * Outputs a jQuery error event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _error($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'error'); + } + + // -------------------------------------------------------------------- + + /** + * Focus + * + * Outputs a jQuery focus event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _focus($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'focus'); + } + + // -------------------------------------------------------------------- + + /** + * Hover + * + * Outputs a jQuery hover event + * + * @param string - element + * @param string - Javascript code for mouse over + * @param string - Javascript code for mouse out + * @return string + */ + protected function _hover($element = 'this', $over = '', $out = '') + { + $event = "\n\t$(".$this->_prep_element($element).").hover(\n\t\tfunction()\n\t\t{\n\t\t\t{$over}\n\t\t}, \n\t\tfunction()\n\t\t{\n\t\t\t{$out}\n\t\t});\n"; + + $this->jquery_code_for_compile[] = $event; + + return $event; + } + + // -------------------------------------------------------------------- + + /** + * Keydown + * + * Outputs a jQuery keydown event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _keydown($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'keydown'); + } + + // -------------------------------------------------------------------- + + /** + * Keyup + * + * Outputs a jQuery keydown event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _keyup($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'keyup'); + } + + // -------------------------------------------------------------------- + + /** + * Load + * + * Outputs a jQuery load event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _load($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'load'); + } + + // -------------------------------------------------------------------- + + /** + * Mousedown + * + * Outputs a jQuery mousedown event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _mousedown($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'mousedown'); + } + + // -------------------------------------------------------------------- + + /** + * Mouse Out + * + * Outputs a jQuery mouseout event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _mouseout($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'mouseout'); + } + + // -------------------------------------------------------------------- + + /** + * Mouse Over + * + * Outputs a jQuery mouseover event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _mouseover($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'mouseover'); + } + + // -------------------------------------------------------------------- + + /** + * Mouseup + * + * Outputs a jQuery mouseup event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _mouseup($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'mouseup'); + } + + // -------------------------------------------------------------------- + + /** + * Output + * + * Outputs script directly + * + * @param array $array_js = array() + * @return void + */ + protected function _output($array_js = array()) + { + if ( ! is_array($array_js)) + { + $array_js = array($array_js); + } + + foreach ($array_js as $js) + { + $this->jquery_code_for_compile[] = "\t".$js."\n"; + } + } + + // -------------------------------------------------------------------- + + /** + * Resize + * + * Outputs a jQuery resize event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _resize($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'resize'); + } + + // -------------------------------------------------------------------- + + /** + * Scroll + * + * Outputs a jQuery scroll event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _scroll($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'scroll'); + } + + // -------------------------------------------------------------------- + + /** + * Unload + * + * Outputs a jQuery unload event + * + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + protected function _unload($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'unload'); + } + + // -------------------------------------------------------------------- + // Effects + // -------------------------------------------------------------------- + + /** + * Add Class + * + * Outputs a jQuery addClass event + * + * @param string $element + * @param string $class + * @return string + */ + protected function _addClass($element = 'this', $class = '') + { + $element = $this->_prep_element($element); + return '$('.$element.').addClass("'.$class.'");'; + } + + // -------------------------------------------------------------------- + + /** + * Animate + * + * Outputs a jQuery animate event + * + * @param string $element + * @param array $params + * @param string $speed 'slow', 'normal', 'fast', or time in milliseconds + * @param string $extra + * @return string + */ + protected function _animate($element = 'this', $params = array(), $speed = '', $extra = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + $animations = "\t\t\t"; + + foreach ($params as $param => $value) + { + $animations .= $param.": '".$value."', "; + } + + $animations = substr($animations, 0, -2); // remove the last ", " + + if ($speed !== '') + { + $speed = ', '.$speed; + } + + if ($extra !== '') + { + $extra = ', '.$extra; + } + + return "$({$element}).animate({\n$animations\n\t\t}".$speed.$extra.');'; + } + + // -------------------------------------------------------------------- + + /** + * Fade In + * + * Outputs a jQuery hide event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + protected function _fadeIn($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback !== '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + return "$({$element}).fadeIn({$speed}{$callback});"; + } + + // -------------------------------------------------------------------- + + /** + * Fade Out + * + * Outputs a jQuery hide event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + protected function _fadeOut($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback !== '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + return '$('.$element.').fadeOut('.$speed.$callback.');'; + } + + // -------------------------------------------------------------------- + + /** + * Hide + * + * Outputs a jQuery hide action + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + protected function _hide($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback !== '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + return "$({$element}).hide({$speed}{$callback});"; + } + + // -------------------------------------------------------------------- + + /** + * Remove Class + * + * Outputs a jQuery remove class event + * + * @param string $element + * @param string $class + * @return string + */ + protected function _removeClass($element = 'this', $class = '') + { + $element = $this->_prep_element($element); + return '$('.$element.').removeClass("'.$class.'");'; + } + + // -------------------------------------------------------------------- + + /** + * Slide Up + * + * Outputs a jQuery slideUp event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + protected function _slideUp($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback !== '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + return '$('.$element.').slideUp('.$speed.$callback.');'; + } + + // -------------------------------------------------------------------- + + /** + * Slide Down + * + * Outputs a jQuery slideDown event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + protected function _slideDown($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback !== '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + return '$('.$element.').slideDown('.$speed.$callback.');'; + } + + // -------------------------------------------------------------------- + + /** + * Slide Toggle + * + * Outputs a jQuery slideToggle event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + protected function _slideToggle($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback !== '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + return '$('.$element.').slideToggle('.$speed.$callback.');'; + } + + // -------------------------------------------------------------------- + + /** + * Toggle + * + * Outputs a jQuery toggle event + * + * @param string - element + * @return string + */ + protected function _toggle($element = 'this') + { + $element = $this->_prep_element($element); + return '$('.$element.').toggle();'; + } + + // -------------------------------------------------------------------- + + /** + * Toggle Class + * + * Outputs a jQuery toggle class event + * + * @param string $element + * @param string $class + * @return string + */ + protected function _toggleClass($element = 'this', $class = '') + { + $element = $this->_prep_element($element); + return '$('.$element.').toggleClass("'.$class.'");'; + } + + // -------------------------------------------------------------------- + + /** + * Show + * + * Outputs a jQuery show event + * + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + protected function _show($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback !== '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + return '$('.$element.').show('.$speed.$callback.');'; + } + + // -------------------------------------------------------------------- + + /** + * Updater + * + * An Ajax call that populates the designated DOM node with + * returned content + * + * @param string The element to attach the event to + * @param string the controller to run the call against + * @param string optional parameters + * @return string + */ + + protected function _updater($container = 'this', $controller = '', $options = '') + { + $container = $this->_prep_element($container); + $controller = (strpos('://', $controller) === FALSE) ? $controller : $this->CI->config->site_url($controller); + + // ajaxStart and ajaxStop are better choices here... but this is a stop gap + if ($this->CI->config->item('javascript_ajax_img') === '') + { + $loading_notifier = 'Loading...'; + } + else + { + $loading_notifier = 'Loading'; + } + + $updater = '$('.$container.").empty();\n" // anything that was in... get it out + ."\t\t$(".$container.').prepend("'.$loading_notifier."\");\n"; // to replace with an image + + $request_options = ''; + if ($options !== '') + { + $request_options .= ', {' + .(is_array($options) ? "'".implode("', '", $options)."'" : "'".str_replace(':', "':'", $options)."'") + .'}'; + } + + return $updater."\t\t$($container).load('$controller'$request_options);"; + } + + // -------------------------------------------------------------------- + // Pre-written handy stuff + // -------------------------------------------------------------------- + + /** + * Zebra tables + * + * @param string $class + * @param string $odd + * @param string $hover + * @return string + */ + protected function _zebraTables($class = '', $odd = 'odd', $hover = '') + { + $class = ($class !== '') ? '.'.$class : ''; + $zebra = "\t\$(\"table{$class} tbody tr:nth-child(even)\").addClass(\"{$odd}\");"; + + $this->jquery_code_for_compile[] = $zebra; + + if ($hover !== '') + { + $hover = $this->hover("table{$class} tbody tr", "$(this).addClass('hover');", "$(this).removeClass('hover');"); + } + + return $zebra; + } + + // -------------------------------------------------------------------- + // Plugins + // -------------------------------------------------------------------- + + /** + * Corner Plugin + * + * @link http://www.malsup.com/jquery/corner/ + * @param string $element + * @param string $corner_style + * @return string + */ + public function corner($element = '', $corner_style = '') + { + // may want to make this configurable down the road + $corner_location = '/plugins/jquery.corner.js'; + + if ($corner_style !== '') + { + $corner_style = '"'.$corner_style.'"'; + } + + return '$('.$this->_prep_element($element).').corner('.$corner_style.');'; + } + + // -------------------------------------------------------------------- + + /** + * Modal window + * + * Load a thickbox modal window + * + * @param string $src + * @param bool $relative + * @return void + */ + public function modal($src, $relative = FALSE) + { + $this->jquery_code_for_load[] = $this->external($src, $relative); + } + + // -------------------------------------------------------------------- + + /** + * Effect + * + * Load an Effect library + * + * @param string $src + * @param bool $relative + * @return void + */ + public function effect($src, $relative = FALSE) + { + $this->jquery_code_for_load[] = $this->external($src, $relative); + } + + // -------------------------------------------------------------------- + + /** + * Plugin + * + * Load a plugin library + * + * @param string $src + * @param bool $relative + * @return void + */ + public function plugin($src, $relative = FALSE) + { + $this->jquery_code_for_load[] = $this->external($src, $relative); + } + + // -------------------------------------------------------------------- + + /** + * UI + * + * Load a user interface library + * + * @param string $src + * @param bool $relative + * @return void + */ + public function ui($src, $relative = FALSE) + { + $this->jquery_code_for_load[] = $this->external($src, $relative); + } + + // -------------------------------------------------------------------- + + /** + * Sortable + * + * Creates a jQuery sortable + * + * @param string $element + * @param array $options + * @return string + */ + public function sortable($element, $options = array()) + { + if (count($options) > 0) + { + $sort_options = array(); + foreach ($options as $k=>$v) + { + $sort_options[] = "\n\t\t".$k.': '.$v; + } + $sort_options = implode(',', $sort_options); + } + else + { + $sort_options = ''; + } + + return '$('.$this->_prep_element($element).').sortable({'.$sort_options."\n\t});"; + } + + // -------------------------------------------------------------------- + + /** + * Table Sorter Plugin + * + * @param string table name + * @param string plugin location + * @return string + */ + public function tablesorter($table = '', $options = '') + { + $this->jquery_code_for_compile[] = "\t$(".$this->_prep_element($table).').tablesorter('.$options.");\n"; + } + + // -------------------------------------------------------------------- + // Class functions + // -------------------------------------------------------------------- + + /** + * Add Event + * + * Constructs the syntax for an event, and adds to into the array for compilation + * + * @param string The element to attach the event to + * @param string The code to execute + * @param string The event to pass + * @return string + */ + protected function _add_event($element, $js, $event) + { + if (is_array($js)) + { + $js = implode("\n\t\t", $js); + } + + $event = "\n\t$(".$this->_prep_element($element).').'.$event."(function(){\n\t\t{$js}\n\t});\n"; + $this->jquery_code_for_compile[] = $event; + return $event; + } + + // -------------------------------------------------------------------- + + /** + * Compile + * + * As events are specified, they are stored in an array + * This function compiles them all for output on a page + * + * @param string $view_var + * @param bool $script_tags + * @return void + */ + protected function _compile($view_var = 'script_foot', $script_tags = TRUE) + { + // External references + $external_scripts = implode('', $this->jquery_code_for_load); + $this->CI->load->vars(array('library_src' => $external_scripts)); + + if (count($this->jquery_code_for_compile) === 0) + { + // no inline references, let's just return + return; + } + + // Inline references + $script = '$(document).ready(function() {'."\n" + .implode('', $this->jquery_code_for_compile) + .'});'; + + $output = ($script_tags === FALSE) ? $script : $this->inline($script); + + $this->CI->load->vars(array($view_var => $output)); + } + + // -------------------------------------------------------------------- + + /** + * Clear Compile + * + * Clears the array of script events collected for output + * + * @return void + */ + protected function _clear_compile() + { + $this->jquery_code_for_compile = array(); + } + + // -------------------------------------------------------------------- + + /** + * Document Ready + * + * A wrapper for writing document.ready() + * + * @param array $js + * @return void + */ + protected function _document_ready($js) + { + is_array($js) OR $js = array($js); + + foreach ($js as $script) + { + $this->jquery_code_for_compile[] = $script; + } + } + + // -------------------------------------------------------------------- + + /** + * Script Tag + * + * Outputs the script tag that loads the jquery.js file into an HTML document + * + * @param string $library_src + * @param bool $relative + * @return string + */ + public function script($library_src = '', $relative = FALSE) + { + $library_src = $this->external($library_src, $relative); + $this->jquery_code_for_load[] = $library_src; + return $library_src; + } + + // -------------------------------------------------------------------- + + /** + * Prep Element + * + * Puts HTML element in quotes for use in jQuery code + * unless the supplied element is the Javascript 'this' + * object, in which case no quotes are added + * + * @param string + * @return string + */ + protected function _prep_element($element) + { + if ($element !== 'this') + { + $element = '"'.$element.'"'; + } + + return $element; + } + + // -------------------------------------------------------------------- + + /** + * Validate Speed + * + * Ensures the speed parameter is valid for jQuery + * + * @param string + * @return string + */ + protected function _validate_speed($speed) + { + if (in_array($speed, array('slow', 'normal', 'fast'))) + { + return '"'.$speed.'"'; + } + elseif (preg_match('/[^0-9]/', $speed)) + { + return ''; + } + + return $speed; + } + +} diff --git a/system/libraries/Javascript/index.html b/system/libraries/Javascript/index.html new file mode 100644 index 00000000000..b702fbc3967 --- /dev/null +++ b/system/libraries/Javascript/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php new file mode 100644 index 00000000000..240c5f54e88 --- /dev/null +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -0,0 +1,59 @@ +_allow_get_array = (config_item('allow_get_array') === TRUE); + $this->_enable_xss = (config_item('global_xss_filtering') === TRUE); + $this->_enable_csrf = (config_item('csrf_protection') === TRUE); + + // Assign Security and Utf8 classes + $this->security = $security; + $this->uni = $utf8; + + // Sanitize global arrays + $this->_sanitize_globals(); + } + + public function fetch_from_array($array, $index = '', $xss_clean = FALSE) + { + return parent::_fetch_from_array($array, $index, $xss_clean); + } + + /** + * Lie about being a CLI request + * + * We take advantage of this in libraries/Session_test + */ + public function is_cli_request() + { + return FALSE; + } + + public function __set($name, $value) + { + if ($name === 'ip_address') + { + $this->ip_address = $value; + } + } + +} \ No newline at end of file diff --git a/tests/mocks/core/utf8.php b/tests/mocks/core/utf8.php new file mode 100644 index 00000000000..3a6282e1d9a --- /dev/null +++ b/tests/mocks/core/utf8.php @@ -0,0 +1,19 @@ +`. + +.. important:: The Email helper is DEPRECATED and is currently + only kept for backwards compatibility. + +.. contents:: + :local: + +.. raw:: html + +
+ +Loading this Helper +=================== + +This helper is loaded using the following code:: + + $this->load->helper('email'); + +Available Functions +=================== + +The following functions are available: + + +.. php:function:: valid_email($email) + + :param string $email: E-mail address + :returns: TRUE if a valid email is supplied, FALSE otherwise + :rtype: bool + + Checks if the input is a correctly formatted e-mail address. Note that is + doesn't actually prove that the address will be able recieve mail, but + simply that it is a validly formed address. + + Example:: + + if (valid_email('email@somesite.com')) + { + echo 'email is valid'; + } + else + { + echo 'email is not valid'; + } + + .. note:: All that this function does is to use PHP's native ``filter_var()``:: + + (bool) filter_var($email, FILTER_VALIDATE_EMAIL); + +.. php:function:: send_email($recipient, $subject, $message) + + :param string $recipient: E-mail address + :param string $subject: Mail subject + :param string $message: Message body + :returns: TRUE if the mail was successfully sent, FALSE in case of an error + :rtype: bool + + Sends an email using PHP's native `mail() `_ + function. + + .. note:: All that this function does is to use PHP's native ``mail`` + + :: + + mail($recipient, $subject, $message); + + For a more robust email solution, see CodeIgniter's :doc:`Email Library + <../libraries/email>`. \ No newline at end of file diff --git a/user_guide_src/source/helpers/smiley_helper.rst b/user_guide_src/source/helpers/smiley_helper.rst new file mode 100644 index 00000000000..3e766994204 --- /dev/null +++ b/user_guide_src/source/helpers/smiley_helper.rst @@ -0,0 +1,169 @@ +############# +Smiley Helper +############# + +The Smiley Helper file contains functions that let you manage smileys +(emoticons). + +.. important:: The Smiley helper is DEPRECATED and should not be used. + It is currently only kept for backwards compatibility. + +.. contents:: + :local: + +.. raw:: html + +
+ +Loading this Helper +=================== + +This helper is loaded using the following code:: + + $this->load->helper('smiley'); + +Overview +======== + +The Smiley helper has a renderer that takes plain text smileys, like +:-) and turns them into a image representation, like |smile!| + +It also lets you display a set of smiley images that when clicked will +be inserted into a form field. For example, if you have a blog that +allows user commenting you can show the smileys next to the comment +form. Your users can click a desired smiley and with the help of some +JavaScript it will be placed into the form field. + +Clickable Smileys Tutorial +========================== + +Here is an example demonstrating how you might create a set of clickable +smileys next to a form field. This example requires that you first +download and install the smiley images, then create a controller and the +View as described. + +.. important:: Before you begin, please `download the smiley images + `_ + and put them in a publicly accessible place on your server. + This helper also assumes you have the smiley replacement array + located at `application/config/smileys.php` + +The Controller +-------------- + +In your **application/controllers/** directory, create a file called +Smileys.php and place the code below in it. + +.. important:: Change the URL in the :php:func:`get_clickable_smileys()` + function below so that it points to your smiley folder. + +You'll notice that in addition to the smiley helper, we are also using +the :doc:`Table Class <../libraries/table>`:: + + load->helper('smiley'); + $this->load->library('table'); + + $image_array = get_clickable_smileys('http://example.com/images/smileys/', 'comments'); + $col_array = $this->table->make_columns($image_array, 8); + + $data['smiley_table'] = $this->table->generate($col_array); + $this->load->view('smiley_view', $data); + } + + } + +In your **application/views/** directory, create a file called **smiley_view.php** +and place this code in it:: + + + + Smileys + + + +
+ +
+

Click to insert a smiley!

+ + When you have created the above controller and view, load it by visiting http://www.example.com/index.php/smileys/ + + + +Field Aliases +------------- + +When making changes to a view it can be inconvenient to have the field +id in the controller. To work around this, you can give your smiley +links a generic name that will be tied to a specific id in your view. + +:: + + $image_array = get_smiley_links("http://example.com/images/smileys/", "comment_textarea_alias"); + +To map the alias to the field id, pass them both into the +:func:`smiley_js()` function:: + + $image_array = smiley_js("comment_textarea_alias", "comments"); + +Available Functions +=================== + +.. php:function:: get_clickable_smileys($image_url[, $alias = ''[, $smileys = NULL]]) + + :param string $image_url: URL path to the smileys directory + :param string $alias: Field alias + :returns: An array of ready to use smileys + :rtype: array + + Returns an array containing your smiley images wrapped in a clickable + link. You must supply the URL to your smiley folder and a field id or + field alias. + + Example:: + + $image_array = get_clickable_smileys('http://example.com/images/smileys/', 'comment'); + +.. php:function:: smiley_js([$alias = ''[, $field_id = ''[, $inline = TRUE]]]) + + :param string $alias: Field alias + :param string $field_id: Field ID + :param bool $inline: Whether we're inserting an inline smiley + :returns: Smiley-enabling JavaScript code + :rtype: string + + Generates the JavaScript that allows the images to be clicked and + inserted into a form field. If you supplied an alias instead of an id + when generating your smiley links, you need to pass the alias and + corresponding form id into the function. This function is designed to be + placed into the area of your web page. + + Example:: + + + +.. php:function:: parse_smileys([$str = ''[, $image_url = ''[, $smileys = NULL]]]) + + :param string $str: Text containing smiley codes + :param string $image_url: URL path to the smileys directory + :param array $smileys: An array of smileys + :returns: Parsed smileys + :rtype: string + + Takes a string of text as input and replaces any contained plain text + smileys into the image equivalent. The first parameter must contain your + string, the second must contain the URL to your smiley folder + + Example:: + + $str = 'Here are some smileys: :-) ;-)'; + $str = parse_smileys($str, 'http://example.com/images/smileys/'); + echo $str; + +.. |smile!| image:: ../images/smile.gif \ No newline at end of file diff --git a/user_guide_src/source/images/smile.gif b/user_guide_src/source/images/smile.gif new file mode 100644 index 00000000000..bf0922504ed Binary files /dev/null and b/user_guide_src/source/images/smile.gif differ diff --git a/user_guide_src/source/libraries/cart.rst b/user_guide_src/source/libraries/cart.rst new file mode 100644 index 00000000000..be343320db8 --- /dev/null +++ b/user_guide_src/source/libraries/cart.rst @@ -0,0 +1,398 @@ +################### +Shopping Cart Class +################### + +The Cart Class permits items to be added to a session that stays active +while a user is browsing your site. These items can be retrieved and +displayed in a standard "shopping cart" format, allowing the user to +update the quantity or remove items from the cart. + +.. important:: The Cart library is DEPRECATED and should not be used. + It is currently only kept for backwards compatibility. + +Please note that the Cart Class ONLY provides the core "cart" +functionality. It does not provide shipping, credit card authorization, +or other processing components. + +.. contents:: + :local: + +.. raw:: html + +
+ +******************** +Using the Cart Class +******************** + +Initializing the Shopping Cart Class +==================================== + +.. important:: The Cart class utilizes CodeIgniter's :doc:`Session + Class ` to save the cart information to a database, so + before using the Cart class you must set up a database table as + indicated in the :doc:`Session Documentation `, and set the + session preferences in your application/config/config.php file to + utilize a database. + +To initialize the Shopping Cart Class in your controller constructor, +use the ``$this->load->library()`` method:: + + $this->load->library('cart'); + +Once loaded, the Cart object will be available using:: + + $this->cart + +.. note:: The Cart Class will load and initialize the Session Class + automatically, so unless you are using sessions elsewhere in your + application, you do not need to load the Session class. + +Adding an Item to The Cart +========================== + +To add an item to the shopping cart, simply pass an array with the +product information to the ``$this->cart->insert()`` method, as shown +below:: + + $data = array( + 'id' => 'sku_123ABC', + 'qty' => 1, + 'price' => 39.95, + 'name' => 'T-Shirt', + 'options' => array('Size' => 'L', 'Color' => 'Red') + ); + + $this->cart->insert($data); + +.. important:: The first four array indexes above (id, qty, price, and + name) are **required**. If you omit any of them the data will not be + saved to the cart. The fifth index (options) is optional. It is intended + to be used in cases where your product has options associated with it. + Use an array for options, as shown above. + +The five reserved indexes are: + +- **id** - Each product in your store must have a unique identifier. + Typically this will be an "sku" or other such identifier. +- **qty** - The quantity being purchased. +- **price** - The price of the item. +- **name** - The name of the item. +- **options** - Any additional attributes that are needed to identify + the product. These must be passed via an array. + +In addition to the five indexes above, there are two reserved words: +rowid and subtotal. These are used internally by the Cart class, so +please do NOT use those words as index names when inserting data into +the cart. + +Your array may contain additional data. Anything you include in your +array will be stored in the session. However, it is best to standardize +your data among all your products in order to make displaying the +information in a table easier. + +:: + + $data = array( + 'id' => 'sku_123ABC', + 'qty' => 1, + 'price' => 39.95, + 'name' => 'T-Shirt', + 'coupon' => 'XMAS-50OFF' + ); + + $this->cart->insert($data); + +The ``insert()`` method will return the $rowid if you successfully insert a +single item. + +Adding Multiple Items to The Cart +================================= + +By using a multi-dimensional array, as shown below, it is possible to +add multiple products to the cart in one action. This is useful in cases +where you wish to allow people to select from among several items on the +same page. + +:: + + $data = array( + array( + 'id' => 'sku_123ABC', + 'qty' => 1, + 'price' => 39.95, + 'name' => 'T-Shirt', + 'options' => array('Size' => 'L', 'Color' => 'Red') + ), + array( + 'id' => 'sku_567ZYX', + 'qty' => 1, + 'price' => 9.95, + 'name' => 'Coffee Mug' + ), + array( + 'id' => 'sku_965QRS', + 'qty' => 1, + 'price' => 29.95, + 'name' => 'Shot Glass' + ) + ); + + $this->cart->insert($data); + +Displaying the Cart +=================== + +To display the cart you will create a :doc:`view +file ` with code similar to the one shown below. + +Please note that this example uses the :doc:`form +helper `. + +:: + + + + + + + + + + + + + + + cart->contents() as $items): ?> + + + + + + + + + + + + + + + + + + + + +
QTYItem DescriptionItem PriceSub-Total
$i.'[qty]', 'value' => $items['qty'], 'maxlength' => '3', 'size' => '5')); ?> + + + cart->has_options($items['rowid']) == TRUE): ?> + +

+ cart->product_options($items['rowid']) as $option_name => $option_value): ?> + + :
+ + +

+ + + +
cart->format_number($items['price']); ?>$cart->format_number($items['subtotal']); ?>
 Total$cart->format_number($this->cart->total()); ?>
+ +

+ +Updating The Cart +================= + +To update the information in your cart, you must pass an array +containing the Row ID and one or more pre-defined properties to the +``$this->cart->update()`` method. + +.. note:: If the quantity is set to zero, the item will be removed from + the cart. + +:: + + $data = array( + 'rowid' => 'b99ccdf16028f015540f341130b6d8ec', + 'qty' => 3 + ); + + $this->cart->update($data); + + // Or a multi-dimensional array + + $data = array( + array( + 'rowid' => 'b99ccdf16028f015540f341130b6d8ec', + 'qty' => 3 + ), + array( + 'rowid' => 'xw82g9q3r495893iajdh473990rikw23', + 'qty' => 4 + ), + array( + 'rowid' => 'fh4kdkkkaoe30njgoe92rkdkkobec333', + 'qty' => 2 + ) + ); + + $this->cart->update($data); + +You may also update any property you have previously defined when +inserting the item such as options, price or other custom fields. + +:: + + $data = array( + 'rowid' => 'b99ccdf16028f015540f341130b6d8ec', + 'qty' => 1, + 'price' => 49.95, + 'coupon' => NULL + ); + + $this->cart->update($data); + +What is a Row ID? +***************** + +The row ID is a unique identifier that is generated by the cart code +when an item is added to the cart. The reason a unique ID is created +is so that identical products with different options can be managed +by the cart. + +For example, let's say someone buys two identical t-shirts (same product +ID), but in different sizes. The product ID (and other attributes) will +be identical for both sizes because it's the same shirt. The only +difference will be the size. The cart must therefore have a means of +identifying this difference so that the two sizes of shirts can be +managed independently. It does so by creating a unique "row ID" based on +the product ID and any options associated with it. + +In nearly all cases, updating the cart will be something the user does +via the "view cart" page, so as a developer, it is unlikely that you +will ever have to concern yourself with the "row ID", other than making +sure your "view cart" page contains this information in a hidden form +field, and making sure it gets passed to the ``update()`` method when +the update form is submitted. Please examine the construction of the +"view cart" page above for more information. + + +*************** +Class Reference +*************** + +.. php:class:: CI_Cart + + .. attribute:: $product_id_rules = '\.a-z0-9_-' + + These are the regular expression rules that we use to validate the product + ID - alpha-numeric, dashes, underscores, or periods by default + + .. attribute:: $product_name_rules = '\w \-\.\:' + + These are the regular expression rules that we use to validate the product ID and product name - alpha-numeric, dashes, underscores, colons or periods by + default + + .. attribute:: $product_name_safe = TRUE + + Whether or not to only allow safe product names. Default TRUE. + + + .. php:method:: insert([$items = array()]) + + :param array $items: Items to insert into the cart + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Insert items into the cart and save it to the session table. Returns TRUE + on success and FALSE on failure. + + + .. php:method:: update([$items = array()]) + + :param array $items: Items to update in the cart + :returns: TRUE on success, FALSE on failure + :rtype: bool + + This method permits changing the properties of a given item. + Typically it is called from the "view cart" page if a user makes changes + to the quantity before checkout. That array must contain the rowid + for each item. + + .. php:method:: remove($rowid) + + :param int $rowid: ID of the item to remove from the cart + :returns: TRUE on success, FALSE on failure + :rtype: bool + + Allows you to remove an item from the shopping cart by passing it the + ``$rowid``. + + .. php:method:: total() + + :returns: Total amount + :rtype: int + + Displays the total amount in the cart. + + + .. php:method:: total_items() + + :returns: Total amount of items in the cart + :rtype: int + + Displays the total number of items in the cart. + + + .. php:method:: contents([$newest_first = FALSE]) + + :param bool $newest_first: Whether to order the array with newest items first + :returns: An array of cart contents + :rtype: array + + Returns an array containing everything in the cart. You can sort the + order by which the array is returned by passing it TRUE where the contents + will be sorted from newest to oldest, otherwise it is sorted from oldest + to newest. + + .. php:method:: get_item($row_id) + + :param int $row_id: Row ID to retrieve + :returns: Array of item data + :rtype: array + + Returns an array containing data for the item matching the specified row + ID, or FALSE if no such item exists. + + .. php:method:: has_options($row_id = '') + + :param int $row_id: Row ID to inspect + :returns: TRUE if options exist, FALSE otherwise + :rtype: bool + + Returns TRUE (boolean) if a particular row in the cart contains options. + This method is designed to be used in a loop with ``contents()``, since + you must pass the rowid to this method, as shown in the Displaying + the Cart example above. + + .. php:method:: product_options([$row_id = '']) + + :param int $row_id: Row ID + :returns: Array of product options + :rtype: array + + Returns an array of options for a particular product. This method is + designed to be used in a loop with ``contents()``, since you + must pass the rowid to this method, as shown in the Displaying the + Cart example above. + + .. php:method:: destroy() + + :rtype: void + + Permits you to destroy the cart. This method will likely be called + when you are finished processing the customer's order. \ No newline at end of file diff --git a/user_guide_src/source/libraries/javascript.rst b/user_guide_src/source/libraries/javascript.rst new file mode 100644 index 00000000000..e91b9ad7835 --- /dev/null +++ b/user_guide_src/source/libraries/javascript.rst @@ -0,0 +1,322 @@ +################ +Javascript Class +################ + +CodeIgniter provides a library to help you with certain common functions +that you may want to use with Javascript. Please note that CodeIgniter +does not require the jQuery library to run, and that any scripting +library will work equally well. The jQuery library is simply presented +as a convenience if you choose to use it. + +.. important:: This library is DEPRECATED and should not be used. It has always + been with an 'experimental' status and is now no longer supported. + Currently only kept for backwards compatibility. + +.. contents:: + :local: + +.. raw:: html + +
+ +************************** +Using the Javascript Class +************************** + +Initializing the Class +====================== + +To initialize the Javascript class manually in your controller +constructor, use the ``$this->load->library()`` method. Currently, +the only available library is jQuery, which will automatically be +loaded like this:: + + $this->load->library('javascript'); + +The Javascript class also accepts parameters: + +- js_library_driver (string) *default: 'jquery'* +- autoload (bool) *default: TRUE* + +You may override the defaults by sending an associative array:: + + $this->load->library( + 'javascript', + array( + 'js_library_driver' => 'scripto', + 'autoload' => FALSE + ) + ); + +Again, presently only 'jquery' is available. You may wish to set +autoload to FALSE, though, if you do not want the jQuery library to +automatically include a script tag for the main jQuery script file. This +is useful if you are loading it from a location outside of CodeIgniter, +or already have the script tag in your markup. + +Once loaded, the jQuery library object will be available using: + + $this->javascript + +Setup and Configuration +======================= + +Set these variables in your view +-------------------------------- + +As a Javascript library, your files must be available to your +application. + +As Javascript is a client side language, the library must be able to +write content into your final output. This generally means a view. +You'll need to include the following variables in the ```` +sections of your output. + +:: + + + + + +``$library_src``, is where the actual library file will be loaded, as +well as any subsequent plugin script calls; $script_head is where +specific events, functions and other commands will be rendered. + +Set the path to the librarys with config items +---------------------------------------------- + +There are some configuration items in Javascript library. These can +either be set in *application/config.php*, within its own +*config/javascript.php* file, or within any controller usings the +``set_item()`` function. + +An image to be used as an "ajax loader", or progress indicator. Without +one, the simple text message of "loading" will appear when Ajax calls +need to be made. + +:: + + $config['javascript_location'] = 'http://localhost/codeigniter/themes/js/jquery/'; + $config['javascript_ajax_img'] = 'images/ajax-loader.gif'; + +If you keep your files in the same directories they were downloaded +from, then you need not set this configuration items. + +The jQuery Class +================ + +To initialize the jQuery class manually in your controller constructor, +use the ``$this->load->library()`` method:: + + $this->load->library('javascript/jquery'); + +You may send an optional parameter to determine whether or not a script +tag for the main jQuery file will be automatically included when loading +the library. It will be created by default. To prevent this, load the +library as follows:: + + $this->load->library('javascript/jquery', FALSE); + +Once loaded, the jQuery library object will be available using: + + $this->jquery + +jQuery Events +============= + +Events are set using the following syntax. +:: + + $this->jquery->event('element_path', code_to_run()); + +In the above example: + +- "event" is any of blur, change, click, dblclick, error, focus, hover, + keydown, keyup, load, mousedown, mouseup, mouseover, mouseup, resize, + scroll, or unload. +- "element_path" is any valid `jQuery selector + `_. Due to jQuery's unique + selector syntax, this is usually an element id, or CSS selector. For + example "#notice_area" would effect ``
``, and + "#content a.notice" would effect all anchors with a class of "notice" + in the div with id "content". +- "``code_to_run()``" is script your write yourself, or an action such as + an effect from the jQuery library below. + +Effects +======= + +The query library supports a powerful +`Effects `_ repertoire. Before an effect +can be used, it must be loaded:: + + $this->jquery->effect([optional path] plugin name); // for example $this->jquery->effect('bounce'); + + +hide() / show() +--------------- + +Each of this functions will affect the visibility of an item on your +page. hide() will set an item invisible, show() will reveal it. + +:: + + $this->jquery->hide(target, optional speed, optional extra information); + $this->jquery->show(target, optional speed, optional extra information); + + +- "target" will be any valid jQuery selector or selectors. +- "speed" is optional, and is set to either slow, normal, fast, or + alternatively a number of milliseconds. +- "extra information" is optional, and could include a callback, or + other additional information. + +toggle() +-------- + +toggle() will change the visibility of an item to the opposite of its +current state, hiding visible elements, and revealing hidden ones. + +:: + + $this->jquery->toggle(target); + + +- "target" will be any valid jQuery selector or selectors. + +animate() +--------- + +:: + + $this->jquery->animate(target, parameters, optional speed, optional extra information); + + +- "target" will be any valid jQuery selector or selectors. +- "parameters" in jQuery would generally include a series of CSS + properties that you wish to change. +- "speed" is optional, and is set to either slow, normal, fast, or + alternatively a number of milliseconds. +- "extra information" is optional, and could include a callback, or + other additional information. + +For a full summary, see +`http://api.jquery.com/animate/ `_ + +Here is an example of an animate() called on a div with an id of "note", +and triggered by a click using the jQuery library's click() event. + +:: + + $params = array( + 'height' => 80, + 'width' => '50%', + 'marginLeft' => 125 + ); + $this->jquery->click('#trigger', $this->jquery->animate('#note', $params, 'normal')); + +fadeIn() / fadeOut() +-------------------- + +:: + + $this->jquery->fadeIn(target, optional speed, optional extra information); + $this->jquery->fadeOut(target, optional speed, optional extra information); + + +- "target" will be any valid jQuery selector or selectors. +- "speed" is optional, and is set to either slow, normal, fast, or + alternatively a number of milliseconds. +- "extra information" is optional, and could include a callback, or + other additional information. + +toggleClass() +------------- + +This function will add or remove a CSS class to its target. + +:: + + $this->jquery->toggleClass(target, class) + + +- "target" will be any valid jQuery selector or selectors. +- "class" is any CSS classname. Note that this class must be defined + and available in a CSS that is already loaded. + +fadeIn() / fadeOut() +-------------------- + +These effects cause an element(s) to disappear or reappear over time. + +:: + + $this->jquery->fadeIn(target, optional speed, optional extra information); + $this->jquery->fadeOut(target, optional speed, optional extra information); + + +- "target" will be any valid jQuery selector or selectors. +- "speed" is optional, and is set to either slow, normal, fast, or + alternatively a number of milliseconds. +- "extra information" is optional, and could include a callback, or + other additional information. + +slideUp() / slideDown() / slideToggle() +--------------------------------------- + +These effects cause an element(s) to slide. + +:: + + $this->jquery->slideUp(target, optional speed, optional extra information); + $this->jquery->slideDown(target, optional speed, optional extra information); + $this->jquery->slideToggle(target, optional speed, optional extra information); + + +- "target" will be any valid jQuery selector or selectors. +- "speed" is optional, and is set to either slow, normal, fast, or + alternatively a number of milliseconds. +- "extra information" is optional, and could include a callback, or + other additional information. + +Plugins +======= + +Some select jQuery plugins are made available using this library. + +corner() +-------- + +Used to add distinct corners to page elements. For full details see +`http://malsup.com/jquery/corner/ `_ + +:: + + $this->jquery->corner(target, corner_style); + + +- "target" will be any valid jQuery selector or selectors. +- "corner_style" is optional, and can be set to any valid style such + as round, sharp, bevel, bite, dog, etc. Individual corners can be set + by following the style with a space and using "tl" (top left), "tr" + (top right), "bl" (bottom left), or "br" (bottom right). + +:: + + $this->jquery->corner("#note", "cool tl br"); + + +tablesorter() +------------- + +description to come + +modal() +------- + +description to come + +calendar() +---------- + +description to come \ No newline at end of file