Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Dodawanie do ulubionych
Forum PHP.pl > Forum > Przedszkole
annie
Cześć!
Nie wiem na jakim poziomie zaawansowania jest to pytanie, ale dodaje do przedszkola wink.gif Buduję stronę z artykułami. Tylko zalogowani użytkownicy mają do nich dostęp i chciałabym umożliwić im dodawanie wybranych artykułów do ulubionych. Przy każdym artykule jest link <a href="#" class="favourite">Favourite</a>, który miałby właśnie to umożliwić.
Mój poziom PHP jest podstawowy, więc proszę o jasne i klarowne odpowiedzi wink.gif

HTML i PHP
Kod
<?php
session_start();
require_once('connection.php');

mysql_select_db($database_connection, $connection);
$query_favorite = "SELECT username, post_id FROM favorite";
$favorite = mysql_query($query_favorite, $connection) or die(mysql_error());
$row_favorite = mysql_fetch_assoc($favorite);
$totalRows_favorite = mysql_num_rows($favorite);
?>

if(isset($_SESSION['valid_user'])){
} else {header('Location: index.php');
};

<a href="#" class="favourite">Favourite</a>


SHOW CREATE TABLES z bazy danych

Kod
CREATE TABLE `user` (
  `username` varchar(45) NOT NULL,
  `email` varchar(45) NOT NULL,
  `password` varchar(45) NOT NULL,
  `profilepic` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `post` (
  `post_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) NOT NULL,
  `dato` date NOT NULL,
  `category` varchar(100) NOT NULL,
  `description` varchar(500) NOT NULL,
  `text` longtext NOT NULL,
  PRIMARY KEY (`post_id`),
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8

CREATE TABLE `favorite` (
  `username` varchar(45) NOT NULL,
  `post_id` int(11) NOT NULL,
  PRIMARY KEY (`username`,`post_id`),
  KEY `fk_favorite_post1_idx` (`post_id`),
  CONSTRAINT `fk_favorite_user` FOREIGN KEY (`username`) REFERENCES `user` (`username`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_favorite_post1` FOREIGN KEY (`post_id`) REFERENCES `post` (`post_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8



EDIT:

Myślałam o czymś takim:
Kod
if(in_array($_POST['id'], $row_favorite))
{
// jezeli juz jest w ulubionych, usun z ulubionych
}
else
{
// jezeli nie ma, dodaj do ulubionych
}

<a href="#" class="favourite" data-id="<?php echo $post_id; ?>">Favourite</a>
?>

ale nie wiem jak to dalej zakodować, tak żeby wysłać dane o poście/artykule i o zalogowanym użytkowniku do bazy danych.
slashynsky
  1. if(isset($_SESSION['valid_user'])){
  2. } else {header('Location: index.php');
  3. };


mozna zamienic na:
  1. if(!isset($_SESSION['valid_user'])){header('Location: index.php');};


zawsze troche mniej kodu.

Jezeli juz sie uczysz olej przestarzałe mysql_query i zainteresuj się PDO.

Jezeli chcesz to wykonać bez przeładowania strony --> AJAX w innym przypadku tworzysz linka:
  1. <a href="dodajusunfav.php?id=<?php echo $post_id; ?>" class="favourite">Favourite</a>


i w danym pliku dane odbierasz:
  1. DELETE FROM favorite WHERE username = " %zmienna-z-username% " AND post_id = " (int)$_GET['id'] "


a po wykonaniu zapytania header z powrotem.
annie
dzięki za odpowiedź smile.gif zależałoby mi na tym, żeby było bez przeładowania strony, ale chyba się zanosi wtedy na dłuższy skrypt, który będzie ponad moje podstawy. próbowałam znaleźć coś gotowego w necie, ale nie ma nic w stylu "bare bones", co można by samemu sobie dostosować według potrzeb.
jest szansa, że pomożesz z tym kodem (ajax)? smile.gif
Turson
Ajax jest prosty http://api.jquery.com/jQuery.ajax/
Tak czy inaczej PHP też musi być
Wazniak96
PS: można bez przeładowania strony, a mianowicie spowodować otwarcie nowej karty, w której otworzysz plik dodający do ulubionych, a potem zamknąć ją javascript'em (window.close() ) smile.gif
annie
okej! biggrin.gif to myślę by działało, gdybym wiedziała jak uzupełnić początek:

Kod
<?php
if(in_array($_POST['id'], $row_favorite))
{
   // jezeli juz jest w ulubionych, usun z ulubionych
}
else
{
  // jezeli nie ma, dodaj do ulubionych
}

?>

<a href="#" class="favourite" data-id="<?php echo $post_id; ?>">Favourite</a>


    $(document).ready(function() {
    $('.favourite').on('click', null, function() {
        var _this = $(this);
        $.ajax({
          'complete' : function(data) {
               if(_this.text() == 'Favourite')
               {
                 _this.html('Favourited');
               }
               else
               {
                 _this.html('Favourite');
               }
            }
            });
        });
    });


pomysły? smile.gif
trueblue
Do pierwszego warunku używasz zapytania DELETE, które podał Ci slashynsky.
Do drugiego używasz zapytania INSERT.
W opcjach Ajax nie ustawiłaś opcji "url", który ma być wywołany przy kliknięciu.
W funkcji "oncomplete" proponuję używać tego co żądanie dostanie w odpowiedzi (dawać odpowiedź w omawianych warunkach), a nie opierać się na tekście w linku.
annie
dzięki, ale muszę coś źle robić, bo mi warningi wywala ;/
Notice: Undefined index: id
lub Notice: Undefined variable: id
Warning: mysqli_query() expects parameter 1 to be mysqli, resource given

to co dodałam:

Kod
$username=$_SESSION['valid_user'];

if(in_array($_POST['id'], $row_favorite)) // tej linii dotyczy notice
{
   mysqli_query($connection,"DELETE FROM favorite WHERE postID='id'");
}
else
{
   mysqli_query($connection,"INSERT INTO user (username, postID) VALUES ('$username', '$id')"); // tej linii dotyczy warning
}


// ajax bez zmian, co masz na myśli z url-em?

i tu nie wiem które ma byc?
<a href="#" class="delta captionbutton" data-id="<?php echo id; ?>">Favourite</a>
<a href="#" class="delta captionbutton" data-id="<?php echo $id; ?>">Favourite</a>
<a href="#" class="delta captionbutton" data-id="<?php echo $post_id; ?>">Favourite</a>
trueblue
Nie przekazujesz w poście url, który ma wywołać Ajax. Nie ma też danych jakie ma przesłać. https://api.jquery.com/jQuery.ajax/
W atrybucie data-id musisz umieścić id postu, więc albo 2 albo 3, chyba, że id postu masz w stałej "id". Umieszczenie id postu w tym atrybucie w magiczny sposób nie dołączy go do żądania ajaxowego, więc musisz go pobrać i przekazać do obiektu data.

Wywala błędy, bo założeniem jest, że część PHP ma nie być wywołana z palca, tylko poprzez Ajax.
annie
w ten sposób?
ten url ma być do osobnego pliku?

Kod
$(document).ready(function() {
    $('.delta').on('click', null, function() {
        var _this = $(this);
                var post_id = _this.data('id');
          $.ajax({
              type     : 'POST',
              url      : '/file.php',
              dataType : 'json',
              data     : 'id='+ post_id,
              complete : function(data) {
               if(_this.text() == 'Favorite')
               {
                 _this.html('Favorited');
               }
               else
               {
                 _this.html('Favorite');
               }
            }
            });
        });
    });
Turson
Najpierw musisz pobrać do js id posta, potem przesłać.

Powiedzmy, że masz:
  1. <div class="blabla" post_id="3">
  2. treść
  3. </div>

[JAVASCRIPT] pobierz, plaintext
  1. $(document).ready(function() {
  2. $('.delta').on('click', null, function() {
  3. var _this = $(this);
  4. var post_id = $('.blabla').attr('post_id');
  5. $.ajax({
  6. type : 'POST',
  7. url : '/file.php',
  8. dataType : 'json',
  9. data : { post_id:post_id },
  10. complete : function(data) {
  11. if(_this.text() == 'Favorite')
  12. {
  13. _this.html('Favorited');
  14. }
  15. else
  16. {
  17. _this.html('Favorite');
  18. }
  19. }
  20. });
  21. });
  22. });
[JAVASCRIPT] pobierz, plaintext

tym sposobem w file.php masz $_POST['post_id']
slashynsky
url do pliku, ktory chcesz wywołać.
w tym pliku mozesz dac print_r ($_POST); zobaczysz jakei dane sa odbierane.
w complete: function( x ) <-- zmienna "x" bedzie zawierała to co zwróci ci tamten plik. czyli np. nowa tresc diva, czy linku.
annie
@Turson, u mnie postID nie jest atrybutem elementu, tylko komórką w bazie danych. próbować mimo to? powinno działać ?
slashynsky
Musisz podac wartosc tej komorki w bazie danych do pliku wywolanego przez ajaxa, np. tak jak tu wspomniane przez atrybut elementu.
annie
okeeej, spróbuję tak. smile.gif
zauważyłam, ze $_POST['id'] nie jest ustalone. to w ten sposób mam to ustalić, tak?
slashynsky
Dokładnie, nie jest ustalone bo wysyłasz:

data : { post_id:post_id },

przez:

type : 'POST',

wiec masz ustalona zmienna $_POST['post_id'] o wartosci pobranej przez js z atrybutu:

var post_id = $('.blabla').attr('post_id');

czyli w tym przypadku majac <div class="blabla" post_id="3">, bedzie to cyferka "3" smile.gif
slashynsky
nie jestem pewna tego attr('post_id')

i slusznie, bo w swoim przypadku ustalasz attr('data-id')

i nie $('.grid') a prawdopodobnie bedzie to $(this) ale dla pewnosci podaj kod smile.gif
annie
ciągle te same notice'y :/

ok, widze edit, chwila wink.gif
slashynsky
pokaz całość cos zaradzimy :-)
trueblue
Wprowadziłem Cię w błąd.
Niepotrzebne są dwa zapytanie w zależności od warunków. Zostaje jeden warunek z if.
Masz ładnie założony klucz na username i post_id.
Dodaj w tej tabeli pole fav, jako boolean.
W warunku sprawdź czy dostajesz post_id, jeśli dostajesz to zrób zapytanie:
  1. INSERT INTO post(username, post_id, fav) VALUES(username, post_id, 1)
  2. ON duplicate KEY SET fav=NOT fav

To wyżej to pseudokod, wstaw odpowiednie wartości otrzymane z $_POST oraz jak rozumiem username w sesji.
Jeśli polubienie istnieje, to zamiast usuwania, pole fav otrzyma wartość=0 (musisz to uwzględnić w SELECT), jeśli nie polubił, to wstawi rekord.

Zamiast:
  1. <div class="blabla" post_id="3">,

daj:
  1. <div class="blabla" data-id-post="3">,

i przekaż to do ajaxa jako:
  1. data : { id:_this.attr('data-id-post');},

Powyższe lepiej ze względu na walidację. id to nazwa zmiennej, którą otrzymasz w $_POST, możesz zmienić tu, ale w skrypcie PHP musisz to również uwzględnić.

PHP+JS+HTML mogą być w jednym pliku.

Wprowadziłem Cię w błąd.
Niepotrzebne są dwa zapytanie w zależności od warunków. Zostaje jeden warunek z if.
Masz ładnie założony klucz na username i post_id.
Dodaj w tej tabeli pole fav, jako boolean.
W warunku sprawdź czy dostajesz post_id, jeśli dostajesz to zrób zapytanie:
  1. INSERT INTO favorite(username, post_id, fav) VALUES(username, post_id, 1)
  2. ON duplicate KEY SET fav=NOT fav

To wyżej to pseudokod, wstaw odpowiednie wartości otrzymane z $_POST oraz jak rozumiem username w sesji.
Jeśli polubienie istnieje, to zamiast usuwania, pole fav otrzyma wartość=0 (musisz to uwzględnić w SELECT), jeśli nie polubił, to wstawi rekord.

Zamiast:
  1. <div class="blabla" post_id="3">,

daj:
  1. <div class="blabla" data-id-post="3">,

i przekaż to do ajaxa jako:
  1. data : { id:_this.attr('data-id-post');},

Powyższe lepiej ze względu na walidację. id to nazwa zmiennej, którą otrzymasz w $_POST, możesz zmienić tu, ale w skrypcie PHP musisz to również uwzględnić.

PHP+JS+HTML mogą być w jednym pliku.

Coś się chrzani z edycją postu.
Druga połowa postu (zmieniona nazwa tabeli jest poprawna).
annie
tylko się nie przeraźcie jak całość zobaczycie, haha biggrin.gif
trochę niepotrzebności wam wytnę wink.gif

a, i będziecie się musieli przestawić, od teraz postID to eventID, username to brukernavn, user to bruker itd. nie chce żadnych literówek zrobić przez tłumaczenie wink.gif

Gist na Githubie

EDIT: przeczytam co napisał trueblue i się ustosunkuje do tego wink.gif trzy minuty smile.gif
slashynsky
Wklejaj kod przez PHP a nie CODE smile.gif

skad sie bierze zmienna $event_id ? powinno byc $row_joining['eventID'];
trueblue
Bootlean może nie, ale boolean:) Pytasz czy ten typ jest wymagany do tej kolumny czy kolumna "fav"?
Jeśli dasz tą kolumnę, to załatwisz dodawanie i "usuwanie" jednym zapytaniem. Nie trzeba sprawdzać czy jest rekord i dodawać lub usuwać.
Ma to jedną wadę, że nie zastosujesz zmiany tekstu w linku w zależności od odpowiedzi, chyba, że dodasz zapytanie sprawdzające jaki status polubienia (pole fav) ma dany post, ale nie po to upraszczamy zapytania, żeby dodawać nowe. Więc zmiana statusu w linku pozostaje taka jak jest w "oncomplete" Ajaxa.

Pseudokod:
  1. if(isset($_POST['event_id'])){
  2. //zapytanie INSERT ... ON DUPLICATE KEY UPDATE
  3. }
  4. //ajax
  5. //data : { event_id:_this.attr('data-id-event');},
  6.  
  7. //html
  8. <a href="#" class="delta captionbutton" data-id-event="<?php echo $event_id; ?>">Delta</a>
  9. //$event_id ma zawierać id eventu

to co jest tym samym kolorem może mieć dowolną nazwę.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.