PDA

View Full Version : Adopt Conditions Not Working


Abronsyth
12-29-2015, 11:31 AM
Resolved

Apparently the moreless condition is not working for adoptables on my website. For several adoptables I have the limit set to 1 or 2, and yet users are able to adopt 10+ with no issue (and looking through old threads I see this has been an issue for a while now).

Note; this is only happening for Promo and shop adoptables, the condition is working just fine for free adoptables not sold in shops. Looking through the files I believe this is because only adopt.php has the code that tells it to check the conditions before making the adoptable available. Shops and promocodes do not have this code, so they don't bother checking, which results in users being able to get as many of pets sold in shops and through promocodes as they like.

Does anyone know how to fix this? It's kind of really messed up the values of pets on my website. I'm going to be playing with it a bit and see if I can get it to work, so if I find it before someone else does then I will post it.

---

Here are the two snippets I found in adopt.php;
$adopt = new Adoptable($id);
$conditions = $adopt->getConditions();
if(!$conditions->checkConditions()) throw new NoPermissionException("condition");
and
if($total == 0) $adopts = new Null;
else{
$adopts = new Arrays($total);
$available = 0;

foreach($ids as $id){
$adopt = new Adoptable($id);
$conditions = $adopt->getConditions();
if($conditions->checkConditions()) $adopts[$available++] = $adopt;
}

if($available == 0) $adopts = new Null;
else $adopts->setSize($available);
}
if($adopts instanceof Null) throw new InvalidActionException("adopt_none");
$this->setField("adopts", $adopts);
}

So now I just need to figure out what to do with these, and where to put something like them in files that deal with promocode adopts and shop adopts.

----

Now looking at the file .../classes/class_adoptshop.php I think that the conditions snippet should be included in the display function (which I've snipped to show below), so that the code can check conditions, and if the user HAS met the moreless limit, then the adoptable is no longer displayed in the shop at all. I'm still not sure about this (as you all likely know I'm very uneducated with PHP), but I'm hoping that my speculations aren't too off.
public function display(){
$mysidia = Registry::get("mysidia");
$document = $mysidia->frame->getDocument();
$document->addLangvar($mysidia->lang->select_adopt);
if($this->gettotal() == 0){
$document->addLangvar($mysidia->lang->empty);
return;
}

$adoptList = new TableBuilder("shop");
$adoptList->setAlign(new Align("center", "middle"));
$adoptList->buildHeaders("Image", "Breed", "Price", "Buy");
$adoptList->setHelper(new ShopTableHelper);
$this->adopts = $this->getadopttypes();

foreach($this->adopts as $stockadopt){
$adopt = $this->getadopt($stockadopt->type);
$cells = new LinkedList;
$cells->add(new TCell($this->getadoptimage($adopt->eggimage)));
#$cells->add(new TCell($adopt->class));
#$cells->add(new TCell($adopt->type));
$cells->add(new TCell($adopt->description));
$cells->add(new TCell($adopt->cost));
$cells->add(new TCell($adoptList->getHelper()->getAdoptPurchaseForm($this, $adopt)));
$adoptList->buildRow($cells);
}
$document->add($adoptList);
}

Hall of Famer
12-29-2015, 01:32 PM
Well I understand what you are saying, but this is in fact an intended behavior, not an issue. The adoptable condition is for adoption, which means it only applies when you 'adopt' a pet. If you obtain it through other means such as promocode, shop or breeding, the limit is bypassed, since you are not actually 'adopting' a pet. There is a reason why I initially did not make the adoptable shop in Mys v1.3.0 and v1.3.1(it only appeared after v1.3.2), since it leads to conflicts and confusion about adoptable conditions.

Of course, there is a way to alter this behavior if you want to, and it wont be difficult to achieve.

Abronsyth
12-29-2015, 05:10 PM
Oh, alright. Do you know how I'd be able to achieve it so that conditions are not bypassed?

Thank you,
Abronsyth

Is there at least a simplistic way to change it so that the availability feature for promocodes is per user, and not how many times in total the promocode can be redeemed (so if I set it to "1" then each user can only redeem it once)?

Abronsyth
01-07-2016, 05:38 AM
If anyone here is able to do this I'm very willing to pay, it's very necessary that I can have these features (limited number of each adopt available in stores that can be purchased, and making it so the admin can determine the number of times each individual can redeem a specific promocode) for some of my site activities (riddles and seasonal specials) to work.

Kyttias
01-07-2016, 08:11 AM
The only way I can think of is to have a separate table in the database that will hold information about whether a user has ever activated a code before. It'd have users as rows (obviously), but must have all the promo codes as columns. Every time you make a new limited promocode you'd have to add another column to that table. The checks would be as simple as 'has the user activated this code more than 0 times?' - and any limit could work, if you wanted to limit some things to other amounts.

The users would be automatically be added to the table only after the first time they adopt a limited pet, so you needn't add any manually. Here's vaguely where my thoughts lead me.

Create a table in the database (can run this SQL) -
CREATE TABLE IF NOT EXISTS `adopts_limitedpromos` (
`pcid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`examplecode1` int(11) NOT NULL DEFAULT '0',
`examplecode2` int(11) NOT NULL DEFAULT '0',
`examplecode3` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`pcid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

And you can use it like this -


/* You'll want this code to run whenever a limited promocode is trying to be claimed: */
// You will need to get these variables yourself, perhaps with a function?
$promocode;
$username;

// Example here using MySQLi instead of what's native to Mysidia.
include("../../inc/config.php");
$db = new mysqli(DBHOST, DBUSER, DBPASS, DBNAME);

// Check the number of times a user has used a promocode.
$sql = mysqli_query("SELECT {$promocode} FROM `adopts_limitedpromos` WHERE `username` = '{$username}'");
$result = mysqli_fetch_object($sql);

// If the number of times the user has used this code is less than 1, procede!
if ($result->$promocode < 1){
// Updates the database for this user to increase the number of times this promocode has been claimed by one.
mysqli_query($db,"UPDATE `adopts_limitedpromos` SET `{$promocode}` = {$promocode} + 1 WHERE `username` = '{$username}'");

if (mysqli_affected_rows($db) < 1){
// If the update function did not fire, the user doesn't have a row in the table yet. This'll create one.
mysqli_query($db,"INSERT INTO `adopts_limitedpromos` SET `username` = '{$username}', `{$promocode}` = '1'");
}

mysqli_close($db);
}


Not sure how well you follow me. This is the best way I can think of? Actually implementing it in parts of the site might require more help. :ti: