En l'occurrence, le résultat de query() est un objet PDOStatement. Cette méthode ne retourne FALSE qu'en cas d'erreur technique : pas de connexion à la base, la table demandée n'existe pas, erreur dans le nom de colonne etc. Si aucun enregistrement n'est trouvé, la méthode retourne un objet PDOStatement vide. Mais puisqu'elle retourne toujours un objet, ta condition " if ($usercontribution) " est toujours vraie.
Au lieu d'un "SELECT * FROM contributions ..." qui va te retourner tous les enregistrements de l'utilisateur dont tu n'as que faire, fais plutôt un " SELECT COUNT(*) FROM contributions ... " pour connaitre le nombre d'enregistrements présents en base pour cet utilisateur. Récupère le résultat de la requête et modifier ton test : si le résultat > 0 alors l'utilisateur a déjà contribué