Request: Tutorial o...
 
Notifications
Clear all

Request: Tutorial on modifying additional fields and tables using Combu

6 Posts
2 Users
0 Reactions
888 Views
(@derrickbarra)
Posts: 3
Active Member
Topic starter
 

Thanks for making Combu, it's awesome!

I do have a request though, could you put together a tutorial on what modifications I would have to make to Combu's unity and server scripts in order to read additional fields in existing tables, and how to read additional database tables as well? Thank you, I know it's a bit of work on your end, but it will save us a good bit of time on our end to have this laid out.

 
Posted : 28/09/2013 1:41 am
(@skaredcreations)
Posts: 805
Prominent Member Admin
 

Hi, thank you for using Combu.

About your request, to add more fields to the current table is pretty easy: in the server scripts add a new public variable to the modified table/class and do related changes to the INSERT INTO/UPDATE queries in the Save() function, while in Unity manage the new field in the class function that decode JSON (usually called "fromHashtable", in some classes it could be handled directly in the constructor that accepts the JSON string).

For example, if you create a new field "MyCustom" in the table CB_Account on MySQL, then you have to:

  • add the following line in the class CB_Account (/lib/CB_Account.php) right after all other public vars:
    public $MyCustom = "";

    add the field MyCustom to the INSERT INTO and/or UPDATE queries in the function CB_Account::Save()
    PS: of course you should know at least a minimum of SQL and PHP to do such changes, but it's not hard at all. As alternative you could use the CustomData of accounts and inventories that allows you at no cost to maintain fields that are not defined in the tables/classes

  • in Unity you will manage the new field "MyCustom" in the method CBUser.fromHashtable()

 

To add more tables (and web services) you can take a look at the lib classes on the server (CB_Account, CB_Leaderboard etc.) and make similar code (it's nothing too hard, pretty simple to follow and most code is self-explicative and commented), then add the require_once to this new class file in /lib/api.php ; In Unity is just matter of create new classes and wrapper functions in CBManager (you can take a look at how the other functions calls the webservice, really easy).

 

PS: if you purchased Combu from Unity Asset Store, may be you could rate it and write a comment there if you like :)

FRANCESCO CROCETTI @ SKARED CREATIONS

 
Posted : 28/09/2013 3:40 am
(@derrickbarra)
Posts: 3
Active Member
Topic starter
 

Thanks, this is my first time working with PHP/SQL, but it seems straightforward.

 

I've got Combu to load in the data from some new fields in the CB_Account table, however I'm having an issue with updating the fields, I'm not getting any error messages during OnUpdateUser(), and it seems like the fields are being updated, however when I check my database the fields stay the same. This doesn't hold true for the fields that were part of the default Combu, so I'm missing something, I was hoping you could spot where the problem was...

 

In CBUser.cs in Unity, I've added variables for the new table fields, which you can see in the pseudo code below,

public class CBUser 
{
 
 public string firstName;
 public string lastName;
 
 public void fromHashtable(Hashtable hash)
 {
 if(hash != null)
 {
 
 if (hash.ContainsKey("FirstName")){
 firstName = hash["FirstName"].ToString();
 }

 }
 }

} //END CBUser.cs

 

And here's the CB_Account.php file, with the updated Save() function...

 

<?

class CB_Account extends DataClass
{

 public $FirstName;
 public $LastName;

 public function Save()
 {
 global $Database;
 if( $this->Id < 1 )
 {
 $query = sprintf("INSERT INTO %s (FirstName, LastName) VALUES ('%s', '%s')",
 self::TABLE_NAME,
 $Database->Escape($this->FirstName),
 $Database->Escape($this->LastName));
 }
 else
 {
 $setFirstNameQuery = sprintf("UPDATE %s SET FirstName = '%s' WHERE Id = %d",
 self::TABLE_NAME,
 $Database->Escape($this->FirstName),
 $this->Id);

 $setLastNameQuery = sprintf("UPDATE %s SET LastName = '%s' WHERE Id = %d",
 self::TABLE_NAME,
 $Database->Escape($this->LastName),
 $this->Id);

 $Database->Query($setFirstNameQuery);
 $Database->Query($setLastNameQuery);

 }

 $saved = $Database->Query($query);
 if( $saved ) {
 if ($this->Id <= 0)
 $this->Id = $Database->InsertedId();
 return TRUE;
 }
 return FALSE;
 }

 

Did you spot anything out of the ordinary? Or maybe your know of a good way to debug this (writing debug statements to a file maybe)?

 

Also, I wrote Combu a glowing review on the Unity Asset Store, thanks for your continued support!

 
Posted : 30/09/2013 12:36 am
(@skaredcreations)
Posts: 805
Prominent Member Admin
 

Thanks for the review on Asset Store. By the way your code is wrong and I suppose it would work only for updating an already existing user, because you're executing the INSERT/UPDATE of the new fields before it is being created (in case of new user adding) that is made by the latest lines ($saved=$Database->Query($query);).

Here is your correct Save function for the PHP class CB_Account:

public function Save() {
    global $Database;
    if ($this->Id < 1) {
        $query = sprintf("INSERT INTO %s (Username, Password, FirstName, LastName) VALUES ('%s', '%s', '%s', '%s')",
            self::TABLE_NAME,
            $Database->Escape($this->Username),
            $Database->Escape($this->Password),
            $Database->Escape($this->FirstName),
            $Database->Escape($this->LastName));
    } else {
        $query = sprintf("UPDATE %s SET Username = '%s', FirstName = '%s', LastName = '%s' WHERE Id = %d",
            self::TABLE_NAME,
            $Database->Escape($this->Username),
            $Database->Escape($this->FirstName),
            $Database->Escape($this->LastName),
            $this->Id);
    }
    $saved = $Database->Query($query);
    if ($saved) {
        if ($this->Id <= 0)
            $this->Id = $Database->InsertedId();
        return TRUE;
    }
    return FALSE;
}

 

About the queries, if you take a look at the different CB classes, you need to use $Database->Escape($yourVariable) to add a String field to the query (in the sprintf function it must be: '%s' including the enclosing single quotes), $Database->EscapeDate($yourVariable) to add a Date field (in the sprintf it must be: %s without single quotes), $yourVariable to add a Numeric field (in the sprintf it must be: %d without single quotes).

To print debug text on a log file in the PHP application, you can use AppLog::Info("my text") and it will wrote it in the file set for the constant LOG_FILEPATH in /lib/config.php (by default: /_logs/applog.log) and make sure that the containing folder exists and have set write permissions.

FRANCESCO CROCETTI @ SKARED CREATIONS

 
Posted : 30/09/2013 11:40 am
(@derrickbarra)
Posts: 3
Active Member
Topic starter
 

I went ahead and updated my CH_Account.php Save() script, you can review it below.

public function Save() 
{
   global $Database; 
   if ($this->Id < 1) 
   {
      $query = sprintf("INSERT INTO %s (Username, Password, FirstName, LastName) VALUES ('%s', '%s', '%s', '%s')",
      self::TABLE_NAME,
      $Database->Escape($this->Username),
      $Database->Escape($this->Password),
      $Database->Escape($this->FirstName),
      $Database->Escape($this->LastName));
   }
   else
   {
      $query = sprintf("UPDATE %s SET Username = '%s', FirstName = '%s', LastName = '%s' WHERE Id = %d",
      self::TABLE_NAME,
      $Database->Escape($this->Username),
      $Database->Escape($this->FirstName),
      $Database->Escape($this->LastName),
      $this->Id);
   }

   $saved = $Database->Query($query);

   if ($saved) 
   {
      if ($this->Id <= 0)
      {
         $this->Id = $Database->InsertedId();
      }

      AppLog::Info("CB_Account.php Save() Name Set To = " . $this->FirstName . " " . $this->LastName );

      return TRUE;
   }

   AppLog::Info("CB_Account.php Save() Unsuccessful, returning FALSE " );

   return FALSE;

   }

}

However my Update() calls are still not updating the database, so just in case I've missed a step I've included the function call below...

//C# script that holds function used to change player data 

//In my usage I'm passing in the currently logged in user.. 
public void SetFirstName( CBUser user, string firstName ) 
{ 
   user.firstName = firstName; 
   user.Update(); 
}

 

I've also been unsuccessful with getting logs to write to file, which is making this debug process complicated, for reference I'm using a Godaddy Linux server (Paid shared hosting), and I've enabled read/write permissions on the _log folder and the log file itself. I'm also using the default LOG_FILEPATH (/_logs/applog.log).

I'm aware that the problems with writing to the log file are most likely outside of the scope of this conversation (and indeed, the help you've provided so far), and probably stem from either a simple error, but again I'm grateful for any advice you have.

 

 
Posted : 30/09/2013 8:01 pm
(@skaredcreations)
Posts: 805
Prominent Member Admin
 

Oh you probably forgot to add the new fields to the WWWForm in UpdateUser and CreateUser functions of the CBManager component. This is why I created the CustomData for, you could just create a class inheriting from CBUser with two properties that in "get" returned customData["FirstName"] and in "set" put it: this way you didn't need to touch any core/PHP code in Combu.

About your log write issue you can go to your domain filemanager webapp that gives you GoDaddy and edit permissions of the folder _logs to be read+write (if I'm not wrong you have to select the checkbox in the folder content list and click a button edit or permissions in the toolbar).

FRANCESCO CROCETTI @ SKARED CREATIONS

 
Posted : 30/09/2013 8:31 pm
Share: